How to Test Accessibility Settings on Web (Complete Guide)
Accessibility settings control how users with disabilities perceive and interact with a web application. When these settings are ignored or mis‑implemented, users may encounter unreadable text, inacce
Introduction: Why Accessibility Settings Testing Matters
Accessibility settings control how users with disabilities perceive and interact with a web application. When these settings are ignored or mis‑implemented, users may encounter unreadable text, inaccessible controls, or broken workflows. In production, a single oversight can lead to lost customers, legal exposure under regulations such as the ADA or EN 301 549, and damage to brand reputation. Testing accessibility settings is therefore not a nicety; it is a risk‑mitigation activity that validates that the UI respects user‑preferred adaptations such as high‑contrast modes, reduced motion, forced colors, and screen‑reader verbosity levels.
Beyond compliance, accessibility testing uncovers usability flaws that affect all users. For example, a button that relies solely on color to convey state fails not only for color‑blind users but also for anyone viewing the screen in bright sunlight. By exercising the full range of browser‑level accessibility preferences, you surface hidden dependencies on visual cues, timing assumptions, and hard‑coded styles that would otherwise remain invisible until a real user encounters them.
The following guide provides a complete, practical framework for testing accessibility settings on web applications. It covers motivation, a detailed test matrix, manual and automated techniques, concrete code examples, persona‑driven autonomous exploration, production‑specific edge cases, a ready‑to‑use checklist, and closing takeaways. Every section is engineered to give you actionable steps you can apply immediately to your codebase.
Understanding Accessibility Settings on the Web
Web browsers expose a set of user‑controlled accessibility preferences that developers can query via CSS media features, JavaScript APIs, or ARIA attributes. These settings influence layout, presentation, and behavior. Knowing which settings exist and how they are signaled is the first step to designing effective tests.
Common Accessibility Settings
| Setting | CSS Media Feature | JavaScript API | Typical User Impact |
|---|---|---|---|
| Prefers‑reduced‑motion | @media (prefers-reduced-motion: reduce) | window.matchMedia('(prefers-reduced-motion: reduce)') | Disables animations, parallax effects, auto‑playing carousels |
| Prefers‑contrast | @media (prefers-contrast: more) / @media (prefers-contrast: less) | window.matchMedia('(prefers-contrast: more)') | Requests higher or lower contrast; may override author colors |
| Forced‑colors | @media (forced-colors: active) | window.matchMedia('(forced-colors: active)') | Forces a limited palette (often Windows High Contrast mode) |
| Prefers‑color‑scheme | @media (prefers-color-scheme: dark) | window.matchMedia('(prefers-color-scheme: dark)') | Switches between light and dark themes |
| Reduced‑transparency | @media (reduced-transparency: reduce) | window.matchMedia('(reduced-transparency: reduce)') | Requests opaque backgrounds, disables blur effects |
| Inverted‑colors | @media (inverted-colors: inverted) | window.matchMedia('(inverted-colors: inverted)') | Indicates system‑wide color inversion (e.g., macOS Smart Invert) |
| Prefers‑reduced‑transparency | @media (prefers-reduced-transparency: reduce) | window.matchMedia('(prefers-reduced-transparency: reduce)') | Similar to reduced‑transparency but less widely supported |
| Prefers‑reduced‑data | @media (prefers-reduced-data: reduce) | window.matchMedia('(prefers-reduced-data: reduce)') | Signals desire to limit data usage; may affect image resolution |
| Animation‑duration | Not a media feature but readable via getComputedStyle on elements with animation-duration | N/A | Users may set global animation speed scales (e.g., Android) |
These features are part of the CSS Media Queries Level 5 specification and are implemented in modern browsers (Chrome, Edge, Firefox, Safari). Some settings, such as forced‑colors, are primarily Windows‑specific but still relevant because many assistive technologies rely on the underlying system accessibility layer.
How Browsers Expose Settings
When a user toggles an accessibility option in the operating system or browser settings, the user agent updates the corresponding media feature values. CSS rules that depend on these media features are re‑evaluated instantly, causing a style recalculation and, if necessary, a layout shift. JavaScript can listen for changes via matchMedia.addListener (deprecated) or the newer matchMedia.addEventListener('change', handler).
It is crucial to test both the initial state (as the page loads) and dynamic changes (while the page is already rendered). Many bugs appear only when a setting is toggled after the app has initialized, because JavaScript may have cached values or initialized animations before the media query update.
Test Matrix for Accessibility Settings
A structured test matrix ensures you cover the typical interactions (happy path), failure conditions (error paths), unusual inputs (edge cases), and any security or privacy implications. The matrix below organizes tests by accessibility feature, with columns for each test category.
| Accessibility Feature | Happy Path (expected behavior) | Error Path (what should not happen) | Edge Cases (boundary or rare conditions) | Security / Privacy Considerations |
|---|---|---|---|---|
| Prefers‑reduced‑motion | All non‑essential animations pause or run at reduced speed; essential feedback (e.g., button press) remains. | Animations continue at full speed despite user preference. | Mixed‑mode animations where some elements ignore the media query due to hard‑coded animation-play-state: running. | No direct security impact, but excessive motion can trigger seizures; ensuring reduction protects vulnerable users. |
| Prefers‑contrast (more) | Text and important UI elements meet WCAG AA contrast (≥4.5:1) using the forced high‑contrast palette. | Contrast falls below AA; text becomes unreadable. | Custom properties that override forced colors via !important or inline styles, causing contrast loss. | High‑contrast mode may expose system colors that could be fingerprintable; ensure no leakage of OS theme via canvas reading. |
| Forced‑colors | All colors are limited to the system palette; SVG currentColor and CanvasRenderingContext2D respect the forced palette. | Elements retain author‑specified colors, breaking the forced‑color contract. | Use of filter or mix-blend-mode that attempts to recolor forced‑color elements, leading to unexpected ways. | Forced colors can be used to detect assistive technology; avoid exposing forced‑color state to third‑party scripts without consent. |
| Prefers‑color‑scheme (dark) | Dark theme applied; background colors are dark, text light; images with prefers-color-scheme media queries swap appropriately. | Light theme persists despite dark preference. | Images that ignore picture/source with media attribute, resulting in bright logos on dark background. | Dark mode can reduce screen‑burn on OLED; no privacy issue, but ensure no tracking via theme detection. |
| Reduced‑transparency | Blur, opacity, and semi‑transparent backgrounds become fully opaque; text remains legible. | Transparent overlays persist, making text illegible over busy backgrounds. | CSS background-blend-mode that attempts to simulate transparency via blend modes. | No direct security risk; however, opaque backgrounds may hide underlying content used for CAPTCHA‑like tricks. |
| Inverted‑colors | Colors are inverted system‑wide; content remains readable and interactive elements retain affordance. | Inversion causes color‑blindness‑like confusion or makes UI indistinguishable. | SVG filters that explicitly set feColorMatrix to counteract inversion, causing double‑inversion artifacts. | Color inversion can be used to infer UI state; limit exposure of pixel data via getImageData when inversion is active. |
| Prefers‑reduced‑data | Images serve low‑resolution variants; non‑essential requests (e.g., analytics, prefetch) are throttled. | High‑resolution assets load despite preference; unnecessary network traffic occurs. | Service workers that ignore navigator.connection.saveData and cache large assets anyway. | Reduced data mode can be used to infer user’s network constraints; avoid fingerprinting via timing differences. |
Each row should be validated with both manual checks and automated assertions where possible. The matrix also serves as a backlog for test case creation in your test management system.
Manual Testing Approach
Manual testing remains indispensable for accessibility settings because human perception can detect subtleties that automated tools miss, such as the perceived harshness of a contrast shift or the cognitive load of a motion reduction. The following step‑by‑step procedure outlines a repeatable manual workflow.
Preparation
- Identify target settings: Based on your audience, prioritize the most relevant features (e.g., forced‑colors for enterprise users, prefers‑reduced‑motion for vestibular disorder users).
- Configure test environments: Use a combination of OS accessibility settings and browser flags. For Windows, enable High Contrast mode via Settings → Ease of Access → High contrast. For macOS, enable Increase Contrast and Reduce Motion under Accessibility. For Linux, use GNOME Tweaks or KDE System Settings.
- Prepare a test charter: Write a short scenario for each feature (e.g., “Navigate the checkout flow with forced‑colors active”). Include expected outcomes and acceptance criteria.
- Gather tools:
- Browser extensions: axe DevTools, WAVE, Color Contrast Analyzer.
- Screen readers: NVDA (Windows), VoiceOver (macOS), Orca (Linux).
- Keyboard only: Ensure you can navigate without a mouse.
- Device emulator: Use Chrome DevTools → Rendering → Emulate CSS media feature
prefers-reduced-motion,forced-colors, etc., for quick toggles.
Step‑by‑Step Procedure
- Baseline capture: With default OS/browser settings, record a short video or screenshot set of key pages (home, login, product detail, checkout). This serves as a reference for visual comparison.
- Apply first setting: Enable the target accessibility feature at the OS level (or via DevTools emulation). Wait for the page to recompute styles (usually <200 ms).
- Perform happy‑path tasks: Complete the core user flow defined in your charter using only keyboard or screen reader as appropriate. Observe:
- Text legibility (contrast, size).
- Presence of essential motion (e.g., loading spinners).
- Correct announcement of dynamic changes by screen reader.
- No loss of functionality (buttons remain operable, forms submit).
- Introduce error conditions: Deliberately violate a best practice (e.g., add a low‑contrast button via inline style) and verify that the setting still forces an accessible outcome or at least does not worsen the problem.
- Explore edge cases:
- Toggle the setting multiple times in rapid succession.
- Combine two settings (e.g., forced‑colors + prefers‑reduced‑motion).
- Resize the viewport, change orientation, or switch between light/dark OS themes while the accessibility feature is active.
- Use zoom levels (200%, 400%) to confirm that text scaling works alongside the setting.
- Document findings: For each observation, note whether the behavior passed, failed, or produced a warning. Capture screenshots or video clips for failed cases.
- Reset and repeat: Disable the setting, return to baseline, and proceed to the next feature.
Tools for Manual Testing
- Chrome DevTools → Rendering: Provides toggles for
prefers-reduced-motion,forced-colors,prefers-contrast,prefers-color-scheme, andreduced-transparency. This is the fastest way to validate CSS media query reactions without changing OS settings. - Firefox Accessibility Inspector: Shows the accessibility tree and highlights contrast failures in real time.
- Color Contrast Analyzer (CCA): Standalone tool that can sample colors from the screen and report WCAG ratios under various contrast modes.
- External hardware: If you need to test genuine forced‑colors on Windows, a physical machine with High Contrast enabled is preferable to emulation, as some CSS features (e.g.,
system-colors) behave differently.
Automated Approaches
Automated testing scales validation across CI pipelines and regression suites. While no tool can fully replace human judgment, combining static analysis, unit tests, and end‑to‑end (E2E) frameworks yields high coverage.
Unit/Integration Tests with Jest + axe-core
For component libraries (React, Vue, Svelte), you can render components in a JSDOM environment and run axe-core to inspect accessibility violations under simulated media features.
// jest.setup.js
import { configure } from '@testing-library/react';
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);
// Example test for prefers-reduced-motion
test('Button respects prefers-reduced-motion', async () => {
// Simulate reduced motion media query
Object.defineProperty(window, 'matchMedia', {
writable: true,
value: jest.fn().mockImplementation(query => ({
matches: query.includes('prefers-reduced-motion'),
media: query,
onchange: null,
addListener: jest.fn(), // deprecated
removeListener: jest.fn(),
addEventListener: (_, cb) => {
this._listener = cb;
},
removeEventListener: (_, cb) => {
this._listener = null;
},
dispatchEvent: (event) => {
if (this._listener) this._listener(event);
}
}))
});
const { container } = render(<PrimaryButton label="Save" />);
// Trigger a change event to ensure components react
window.matchMedia('(prefers-reduced-motion: reduce)').dispatchEvent(new Event('change'));
const results = await axe(container);
expect(results).toHaveNoViolations();
});
Key points:
- Mock
matchMediato force specific media feature states. - Use
axeto run a full audit on the rendered container. - Assert
toHaveNoViolations()to fail the test on any WCAG rule breach.
End‑to‑End Tests with Cypress + axe
Cypress interacts with the real browser, allowing you to toggle OS‑level settings via Chrome DevTools Protocol or external utilities.
// cypress/integration/accessibility_settings.spec.js
describe('Forced colors mode', () => {
beforeEach(() => {
// Enable forced colors via DevTools protocol
cy.visit('/login');
cy.then(() => {
return cy.automation('send', 'Emulation.setEmulatedMedia', {
features: [
{ name: 'forced-colors', value: 'active' }
]
});
});
});
it('should maintain contrast and operable controls', () => {
cy.injectAxe(); // custom command that loads axe core
cy.checkA11y(null, {
// exclude known false positives if any
exclude: [".cookie-banner"]
});
});
it('should respect user‑initiated toggle', () => {
// Simulate user turning off forced colors via OS (not possible in CI)
// Instead we toggle via DevTools again
cy.automation('send', 'Emulation.setEmulatedMedia', {
features: [{ name: 'forced-colors', value: 'none' }]
});
cy.checkA11y();
});
});
The cy.automation command is a wrapper around Chrome DevTools Protocol that you can add via cypress-real-events or a custom plugin.
Using Lighthouse CI
Lighthouse includes an accessibility audit that runs a set of axe‑based checks. You can configure Lighthouse CI to test multiple emulator states.
// lighthouserc.json
{
"ci": {
"collect": {
"url": ["http://localhost:3000"],
"settings": {
"emulatedFormFactor": "desktop",
"screenEmulation": {
"disabled": false,
"width": 1280,
"height": 800,
"deviceScaleFactor": 1,
"mobile": false
}
}
},
"assert": {
"preset": "lighthouse:recommended",
"assertions": {
"categories:accessibility": ["warn", { "minScore": 0.9 }]
}
}
}
}
To test forced colors, launch Chrome with the --force-color-profile flag or use the DevTools protocol within a custom Lighthouse plugin.
Playwright with axe
Playwright offers built‑in support for emulating media features and integrates neatly with the @playwright/test runner.
// tests/accessibility.spec.js
const { test, expect } = require('@playwright/test');
const { injectAxe, checkA11y } = require('playwright-axe');
test.describe('Prefers-reduced-motion', () => {
test.use({
// Emulate reduced motion at the browser context level
reducedMotion: 'reduce'
});
test('animations are disabled', async ({ page }) => {
await page.goto('/dashboard');
await injectAxe(page);
const { violations } = await checkA11y(page, {
// axe rule that detects animation violations
runOnly: { type: 'tag', values: ['animation'] }
});
expect(violations).toEqual([]);
});
});
Playwright’s use({ reducedMotion: 'reduce' }) automatically sets the appropriate CSS media feature, eliminating the need to mock matchMedia.
Code Examples
Concrete snippets illustrate how to assert specific accessibility‑setting behaviors in automated tests.
Example: Testing Color Contrast via axe
This example checks that all text meets AA contrast when forced‑colors is active.
// test/contrast.forced-colors.test.js
const { test, expect } = require('@playwright/test');
const { injectAxe, checkA11y } = require('playwright-axe');
test.use({ forcedColors: 'active' });
test('forced colors yields sufficient contrast', async ({ page }) => {
await page.goto('/product/123');
await injectAxe(page);
const { violations } = await checkA11y(page, {
// limit to contrast-related rules
runOnly: { type: 'tag', values: ['color'] }
});
expect(violations).toHaveLength(0);
});
If any element fails contrast, violations will contain objects with id: 'color-contrast' and detailed failure messages.
Example: Keyboard Navigation Test
Ensures that a modal can be opened, interacted with, and closed using only the Tab key when prefers‑reduced‑motion is enabled (to confirm that no motion‑dependent focus traps exist).
// test/keyboard.modal.test.js
const { test, expect } = require('@playwright/test');
test.use({ reducedMotion: 'reduce' });
test('modal is keyboard operable under reduced motion', async ({ page }) => {
await page.goto('/settings');
// Open modal via button
await page.click('button#open-preferences');
// Wait for modal to be visible
await page.waitForSelector('div[role="dialog"]', { state: 'visible' });
// Trap focus inside modal: pressing Tab should cycle through focusable elements
const focusable = await page.$$eval('div[role="dialog"] button, div[role="dialog"] input, div[role="dialog"] select', els => els.map(e => e.tabIndex));
expect(focusable.every(i => i >= 0)).toBeTruthy();
// Close modal via Escape key
await page.keyboard.press('Escape');
await expect(page.locator('div[role="dialog"]')).toBeHidden();
});
Example: Screen Reader Announcements with Playwright
Verifies that a live region announces a status change when reduced‑motion is on, ensuring that the announcement is not delayed by an animation.
// test/sr.announcement.test.js
const { test, expect } = require('@playwright/test');
test.use({ reducedMotion: 'reduce' });
test('status message is announced promptly', async ({ page }) => {
await page.goto('/checkout');
// Listen for aria-live changes
const messages = [];
page.on('console', msg => {
if (msg.type() === 'log' && msg.text().startsWith('SR:')) {
messages.push(msg.text().substring(4));
}
});
// Expose a helper that logs live region updates
await page.addInitScript(() => {
const observer = new MutationObserver((mutations) => {
for (const mut of mutations) {
if (mut.type === 'characterData' && mut.target.parentElement.getAttribute('aria-live')) {
console.log('SR:' + mut.target.textContent);
}
}
});
document.querySelectorAll('[aria-live]').forEach(el => observer.observe(el, { characterData: true, subtree: true }));
});
// Trigger an update that would normally be accompanied by a spinner
await page.click('button#apply-coupon');
await page.waitForTimeout(300); // give time for live region update
expect(messages).toContain('Coupon applied successfully');
});
This test uses a mutation observer to pipe live‑region updates to the console, where the test harness captures them. It validates that the announcement appears promptly, not after a lengthy animation that would violate the user’s reduced‑motion preference.
Autonomous, Persona‑Driven Exploration
Scripted tests excel at checking known conditions, but they cannot anticipate every combination of user behavior, device state, and environmental nuance. Autonomous testing platforms that simulate diverse user personas can surface accessibility‑settings bugs that remain hidden in deterministic test suites.
How Persona Models Work
A persona model encodes a set of behavioral tendencies:
- Curious: explores every link, hovers over icons, opens dropdowns repeatedly.
- Impatient: performs rapid clicks, skips modal dialogs, expects immediate feedback.
- Novice: relies heavily on visual cues, avoids keyboard shortcuts, may miss hidden controls.
- Adversarial: attempts to break the UI by entering malformed data, triggering error states rapidly.
- Elderly: prefers larger touch targets, uses system‑wide font scaling, may enable high‑contrast or reduced‑motion.
- Accessibility: actively enables screen‑reader, speech‑input, and prefers reduced‑motion or forced‑colors.
- Power user: utilizes keyboard shortcuts, opens developer tools, expects advanced features to work.
Each persona drives a stochastic exploration engine that generates input sequences (taps, scrolls, keystrokes, voice commands) while monitoring the application for crashes, ANRs, dead ends, and accessibility violations. The engine maintains a visited‑state graph to avoid redundant exploration and learns which paths lead to dead ends, thereby increasing coverage over successive runs.
What They Find That Scripts Miss
- Conditional media‑query overrides: A component may check
window.matchMedia('(prefers-reduced-motion: reduce)')only on mount and never re‑evaluate. A script that sets the media query before rendering will pass, but a persona that toggles the setting after interacting with a dynamic widget (e.g., a chart that redraws on zoom) will catch the missed update. - Focus‑traps revealed by impatient navigation: An impatient persona may repeatedly tab through a modal before its entrance animation finishes, exposing a scenario where focus escapes to the background because the trap was enabled only after a transitionend event.
- Contrast regression caused by theme‑switching races: A curious persona that toggles dark mode, then immediately enables forced‑colors, can trigger a race where the CSS custom properties have not yet been updated, resulting in a brief flash of illegible text.
- Screen‑reader verbosity mismatches: An accessibility persona using a screen reader with high verbosity may hear excessive duplicate announcements when a live region is updated multiple times in quick succession due to a debounce bug that only manifests under rapid interaction patterns.
- Dead buttons exposed by adversarial input: An adversarial persona that fills a form with extremely long strings can cause overflow that pushes a call‑to‑action button outside the viewport, making it unreachable via touch or keyboard—something a script with fixed‑length test data would never see.
Integrating SUSA (mention here)
SUSA’s autonomous agent can be pointed at a staging URL or fed an APK‑derived web wrapper. By configuring a persona profile that includes “accessibility” and “elderly” traits, the agent will automatically enable system‑level accessibility settings (forced‑colors, high contrast, reduced‑motion) and explore the application for extended periods. The resulting report highlights:
- Pages where contrast drops below AA under forced‑colors.
- Instances where animation‑duration is not honored despite reduced‑motion being active.
- Focus‑order problems that only appear after a series of rapid tab presses.
- Security‑relevant findings such as accidental exposure of system‑color values via canvas reading when forced‑colors is active.
Because the agent builds a session‑level memory of visited screens, each subsequent run becomes smarter, revisiting previously problematic areas with varied input patterns to confirm fixes. This continuous feedback loop complements traditional unit and E2E tests, catching regressions that arise from complex interaction‑state combinations rather than isolated code paths.
Production Edge Cases
Even with thorough lab testing, certain conditions only surface in production due to real‑world variability, third‑party integrations, or deployment‑specific quirks. Anticipating these helps you design mitigations and monitoring.
Dynamic Theme Switching
Many applications allow users to switch themes via a UI toggle that persists via localStorage. If the theme switch does not force a recomputation of media‑query‑dependent styles, a user who has forced‑colors enabled may see a mismatch: the theme’s custom properties override the forced palette, causing contrast loss.
Mitigation:
- Subscribe to
matchMedia('(forced-colors: active)')and, upon change, reset theme‑specific custom properties to their fallback values or add a class that disables theme‑specific colors. - Emit a custom event (
theme-change) that components listen to, ensuring they re‑run any CSS‑variable calculations.
User‑Generated Content
Comments, reviews, or markdown‑authored posts can introduce inline styles or arbitrary HTML that bypasses your CSS architecture. A user could paste a block that remains visible under forced‑colors, creating a low‑contrast island.
Mitigation:
- Sanitize user input with a library like DOMPurify, stripping
styleattributes and restricting allowed tags. - Implement a content‑security‑policy (CSP) rule that disallows inline styles (
style-src 'self'). - Run a post‑render axe scan on comment sections as part of your CI pipeline for UGC‑heavy pages.
Third‑Party Widgets
Embedded calendars, payment iframes, or social‑share buttons often come with their own CSS that may not respect forced‑colors or reduced‑motion. Because they load from external domains, your page’s media‑query listeners cannot affect them directly.
Mitigation:
- Request accessibility conformance documentation from the provider; prefer vendors that WCAG‑AA certify their embeds.
- Use a sandboxed iframe with the
allowattribute limited to necessary features, and apply a CSSfilter: invert(0)override only if you can guarantee it does not break functionality. - Monitor widget‑induced violations via a MutationObserver that runs axe on the iframe’s
contentDocumentwhen it becomes available.
Server‑Side Rendering Hydration Mismatch
When SSR generates HTML assuming a default theme (e.g., light) but the client has forced‑colors active, the initial paint may show incorrect colors before JavaScript rehydrates and applies the proper styles. This flash can be disorienting for low‑vision users.
Mitigation:
- Render a critical‑CSS baseline that respects forced‑colors by checking
window.matchMediaon the server (if possible via user‑agent hints) or by inlining a noscript fallback that uses system colors. - Apply a transition‑delay or
visibility: hiddenon the root until hydration completes, then reveal with a fade‑in that respects reduced‑motion (i.e., usetransition: nonewhen reduced‑motion is active).
Network‑Throttling Interaction
A user with prefers‑reduced‑data enabled may experience delayed image lazy‑loading, causing layout shifts that affect reading order. If your lazy‑loader relies on IntersectionObserver thresholds that assume immediate image availability, the placeholder may remain too long, pushing content down and breaking the tab order.
Mitigation:
- Observe the
navigationAPI’ssaveDataflag and adjust lazy‑loading thresholds to be more aggressive when data‑saving is active. - Provide explicit
widthandheightattributes on images to reserve space regardless of load state.
By incorporating these edge‑case considerations into your test matrix and runtime guards, you reduce the likelihood that a setting‑related bug escapes to production.
Checklist for Accessibility Settings Testing
Use this checklist before each release or as part of your Definition of Done.
| ✅ Item | Description | How to Verify |
|---|---|---|
| 1 | All non‑essential animations respect prefers-reduced-motion: reduce | Manual toggle + DevTools animation panel; automated axe rule animation |
| 2 | Text and UI components meet WCAG AA contrast under forced-colors: active | Manual high‑contrast mode; automated contrast audit |
| 3 | Color scheme switches correctly with prefers-color-scheme | Manual dark/light toggle; automated media‑query test |
| 4 | Layout remains usable when reduced-transparency: reduce is active | Manual enable reduced transparency; check for opaque backgrounds |
| 5 | Screen reader announces dynamic changes promptly under accessibility persona | Manual NVDA/VoiceOver test; automated live‑region check via Playwright |
| 6 | Keyboard focus never leaves modal/dialog when any accessibility setting is on | Manual tab navigation; automated focus‑trap test |
| 7 | No horizontal scrolling or content loss at 200% zoom combined with any setting | Manual zoom + setting toggle; automated viewport check |
| 8 | Third‑party iframes do not introduce contrast or focus violations | Manual inspect iframe; automated axe on iframe content |
| 9 | CSP and sanitization block inline styles that could override forced colors | Manual attempt to inject style; automated security scan |
| 10 | SSR hydration does not produce a flash of incorrect colors under forced colors | Network throttled load + visual diff; automated screenshot diff on hydrate |
| 11 | Data‑saving mode does not break lazy‑loaded image placeholders | Manual SaveData toggle; automated IntersectionObserver latency test |
| 12 | Persona‑driven autonomous exploration (e.g., SUSA) reports zero new accessibility defects | Run agent with accessibility + elderly personas; review report |
Mark each item as PASS, FAIL, or NA (not applicable). Treat any FAIL as a release blocker unless a justified risk acceptance is documented.
Closing Takeaways
Testing accessibility settings is a disciplined, repeatable activity that protects users, satisfies legal obligations, and improves overall product quality. Begin by enumerating the settings your audience is likely to use, then construct a test matrix that maps each setting to happy‑path, error‑path, edge‑case, and security considerations.
Manual testing remains the gold standard for validating subjective experiences such as perceived contrast or motion sickness; pair it with DevTools emulation and OS‑level toggles for fast iteration. Automate the repeatable portions using axe‑based assertions in unit, integration, and E2E tests, leveraging tools like Playwright, Cypress, and Lighthouse CI to simulate media‑feature states in CI pipelines.
Go beyond scripted checks by employing autonomous, persona‑driven exploration. Platforms such as
Test Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free