1. Introduction: Why Accessibility Testing Matters
Accessibility testing is no longer an optional quality activity for modern web applications.
A feature can be functionally correct and still be unusable for someone who relies on:
- Screen readers
- Keyboard navigation
- Magnification
- Voice control
- High-contrast modes
- Alternative input devices
For QA engineers, accessibility testing should therefore be treated as another quality dimension alongside functional, API, security, visual, and performance testing.
Playwright accessibility testing advanced techniques combine Playwright’s browser automation capabilities with automated accessibility analysis, ARIA-aware locators, keyboard interaction, focus assertions, and WCAG-oriented checks.
Playwright officially recommends combining automated accessibility testing with manual assessments and inclusive user testing because automated tools cannot detect every accessibility problem.
A practical enterprise architecture looks like this:
Accessibility Strategy
|
+—————–+——————+
| | |
Automated Keyboard Manual
Scans Tests Testing
| | |
axe-core Playwright Screen Reader
| Assertions Testing
+—————–+——————+
|
CI/CD
|
Accessibility Report
This guide explains how to build that strategy with Playwright and TypeScript.
2. What Is Playwright Accessibility Testing?
Playwright Accessibility Testing verifies that web pages and interactive components can be accessed and operated by users with different accessibility needs.
It includes testing:
- Semantic HTML
- ARIA roles
- Accessible names
- Form labels
- Keyboard navigation
- Focus management
- Headings
- Landmarks
- Alternative text
- Dialogs
- Buttons
- Links
- Color contrast
- Automated WCAG-related rules
Playwright’s documentation specifically demonstrates using @axe-core/playwright to identify automatically detectable accessibility issues such as missing labels, poor color contrast, and duplicate IDs.
However, accessibility testing is broader than an axe scan.
A good strategy combines:
Axe scan
+
ARIA assertions
+
Keyboard tests
+
Focus tests
+
Semantic assertions
+
+
Assistive technology
3. Accessibility Testing vs Functional Testing vs Usability Testing
These testing types overlap but have different goals.
| Testing type | Main question |
| Functional testing | Does the feature work? |
| Accessibility testing | Can people with disabilities use it? |
| Usability testing | Is it easy and intuitive to use? |
| Visual testing | Does the UI look correct? |
| Security testing | Can unauthorized users access it? |
For example, consider a login button.
Click Login → User signs in
Accessibility testing:
Can keyboard users reach Login?
Does it have an accessible name?
Is it exposed as a button?
Can a screen reader identify it?
Usability testing:
Is Login easy to find?
Is the wording clear?
A mature Playwright framework should not confuse these objectives.
4. WCAG, ARIA, Semantic HTML, and Accessibility Fundamentals
The Web Content Accessibility Guidelines, or WCAG, provide widely used accessibility guidance.
The four fundamental principles are commonly summarized as POUR:
P — Perceivable
O — Operable
U — Understandable
R — Robust
Perceivable
Information should be available through appropriate sensory channels.
Examples:
- Text alternatives
- Captions
- Sufficient contrast
Operable
Users should be able to operate the interface.
Examples:
- Keyboard access
- Focus management
- No keyboard traps
Understandable
The interface should behave predictably.
Examples:
- Clear labels
- Consistent navigation
- Useful error messages
Robust
Content should work reliably with browsers and assistive technologies.
ARIA provides semantic information when native HTML semantics are insufficient.
Prefer:
<button>Save</button>
over:
<div onclick=”save()”>Save</div>
Native semantic HTML is generally easier to make accessible.
5. Setting Up Playwright Accessibility Testing
Create a Playwright project:
npm init playwright@latest
Playwright Test provides the test runner, assertions, isolation, parallel execution, and browser support.
Install axe:
npm install -D @axe-core/playwright
A useful structure is:
playwright-accessibility/
├── tests/
│ ├── accessibility.spec.ts
│ ├── keyboard.spec.ts
│ └── forms-accessibility.spec.ts
├── fixtures/
│ └── accessibility.fixture.ts
├── utils/
│ └── accessibility.ts
├── pages/
│ └── checkout.page.ts
├── playwright.config.ts
└── package.json
6. Using @axe-core/playwright for Automated Accessibility Scanning
@axe-core/playwright provides AxeBuilder, which injects and runs the axe accessibility engine against the current page.
Install:
npm install -D @axe-core/playwright
import { test, expect } from ‘@playwright/test’;
import AxeBuilder from ‘@axe-core/playwright’;
test(‘homepage has no automatically detectable accessibility violations’, async ({
page
}) => {
await page.goto(‘/’);
const results =
await new AxeBuilder({ page }).analyze();
expect(results.violations).toEqual([]);
});
The execution flow is:
Page
↓
AxeBuilder
↓
Accessibility scan
↓
Violations
↓
Playwright assertion
↓
Pass / Fail
This is the foundation of Playwright accessibility testing with Axe.
7. Checking Accessibility Violations With Playwright
For debugging, don’t immediately throw away the result.
Capture useful information:
test(‘accessibility scan’, async ({
page
}, testInfo) => {
await page.goto(‘/products’);
const results =
await new AxeBuilder({ page }).analyze();
await testInfo.attach(
‘accessibility-results’,
{
body: JSON.stringify(
results,
null,
2
),
contentType: ‘application/json’
}
);
expect(results.violations).toEqual([]);
});
Playwright specifically documents attaching the complete axe result to test output for debugging and reporting.
A violation can contain information such as:
Rule
Impact
Description
Help
Affected elements
CSS selectors
HTML snippets
This makes failures much easier to investigate.
8. WCAG Tag Filtering With Axe
By default, axe evaluates a broad set of rules.
You can target WCAG-related rules:
const results =
await new AxeBuilder({ page })
.withTags([
‘wcag2a’,
‘wcag2aa’,
‘wcag21a’,
‘wcag21aa’
])
.analyze();
expect(results.violations).toEqual([]);
Playwright’s accessibility guide demonstrates this approach for WCAG A and AA-related checks.
This is useful when your organization has a specific compliance target.
For example:
Pull Request
↓
WCAG automated checks
↓
No new critical violations
↓
Merge
Do not interpret this as proof of complete WCAG conformance. Automated scanning covers only a subset of accessibility requirements.
9. Testing ARIA Roles and Accessible Names
One of the strongest features of Playwright ARIA testing is using role-based locators.
Instead of:
page.locator(‘.submit-btn’)
prefer:
page.getByRole(‘button’, {
name: ‘Submit’
});
Playwright provides accessibility-focused assertions including:
- toHaveAccessibleName()
- toHaveAccessibleDescription()
- toHaveRole()
These assertions were added specifically to make accessibility-related verification easier.
Example:
test(‘submit button has correct semantics’, async ({
page
}) => {
const button = page.getByTestId(
‘submit-button’
);
await expect(button)
.toHaveRole(‘button’);
await expect(button)
.toHaveAccessibleName(‘Submit’);
});
This checks the interface from an accessibility-tree perspective rather than merely verifying CSS.
10. Playwright ARIA Accessibility Testing
Consider:
<button
aria-label=”Open shopping cart”>
🛒
</button>
Test:
const cartButton =
page.getByRole(‘button’, {
name: ‘Open shopping cart’
});
await expect(cartButton).toBeVisible();
await expect(cartButton)
.toHaveAccessibleName(
‘Open shopping cart’
);
This is much stronger than:
expect(
await cartButton.getAttribute(‘aria-label’)
).toBe(‘Open shopping cart’);
The latter checks implementation.
The former checks the accessible name exposed through Playwright’s accessibility-aware locator model.
11. Keyboard Navigation and Focus Management
Automated axe scanning does not replace keyboard testing.
A critical Playwright Keyboard Testing scenario is:
Tab
↓
Header
↓
Navigation
↓
Search
↓
Product
↓
Add to Cart
↓
Checkout
Example:
test(‘user can reach checkout using keyboard’, async ({
page
}) => {
await page.goto(‘/cart’);
await page.keyboard.press(‘Tab’);
await page.keyboard.press(‘Tab’);
await expect(
page.getByRole(‘button’, {
name: ‘Checkout’
})
).toBeFocused();
});
For more stable tests, focus the page and use known interactive controls:
await page.locator(‘body’).focus();
await page.keyboard.press(‘Tab’);
const checkout =
page.getByRole(‘button’, {
name: ‘Checkout’
});
await checkout.focus();
await expect(checkout).toBeFocused();
The important goal is not to count tabs blindly.
Test the actual keyboard interaction model.
12. Testing Focus Management
Dialogs are a common source of accessibility defects.
Example:
test(‘dialog receives focus’, async ({
page
}) => {
await page.goto(‘/products’);
await page.getByRole(‘button’, {
name: ‘Add product’
}).click();
const dialog =
page.getByRole(‘dialog’);
await expect(dialog).toBeVisible();
await expect(
dialog.getByRole(‘textbox’, {
name: ‘Product name’
})
).toBeFocused();
});
A robust dialog should also handle focus when closed.
test(‘focus returns after closing dialog’, async ({
page
}) => {
const trigger =
page.getByRole(‘button’, {
name: ‘Add product’
});
await trigger.click();
await page.getByRole(‘button’, {
name: ‘Close’
}).click();
await expect(trigger).toBeFocused();
});
This is an example of accessibility testing that an automated axe scan alone may not fully establish.
13. Testing Forms, Buttons, Links, and Interactive Components
Forms should expose meaningful labels.
Example:
test(‘checkout form has accessible fields’, async ({
page
}) => {
await page.goto(‘/checkout’);
await expect(
page.getByRole(‘textbox’, {
name: ‘Email address’
})
).toBeVisible();
await expect(
page.getByRole(‘textbox’, {
name: ‘Billing address’
})
).toBeVisible();
await expect(
page.getByRole(‘button’, {
name: ‘Place order’
})
).toBeVisible();
});
Avoid selectors like:
page.locator(‘#email’)
when the actual accessibility contract is:
textbox → accessible name → Email address
For links:
await expect(
page.getByRole(‘link’, {
name: ‘Privacy Policy’
})
).toBeVisible();
For checkboxes:
await expect(
page.getByRole(‘checkbox’, {
name: ‘Accept terms’
})
).toBeVisible();
This makes the automation itself more aligned with accessible UI semantics.
14. Testing Images, Alternative Text, Headings, and Landmarks
Images conveying meaningful information should have appropriate text alternatives.
test(‘product images have alt text’, async ({
page
}) => {
await page.goto(‘/products’);
const images =
page.locator(‘img’);
const count =
await images.count();
for (let i = 0; i < count; i++) {
const alt =
await images.nth(i)
.getAttribute(‘alt’);
expect(alt).not.toBeNull();
}
});
But don’t automatically require non-empty alt for every image.
Decorative images may correctly use:
<img alt=””>
The correct question is:
Does the alternative text appropriately communicate the image’s purpose?
Headings
await expect(
page.getByRole(‘heading’, {
level: 1
})
).toHaveCount(1);
Landmarks
await expect(
page.getByRole(‘main’)
).toBeVisible();
await expect(
page.getByRole(‘navigation’)
).toBeVisible();
These tests provide useful semantic regression protection.
15. Testing Color Contrast and Other WCAG Issues
Color contrast is one of the issues automated accessibility engines can help identify.
Axe can detect automatically testable contrast-related violations. Playwright’s accessibility guide lists poor color contrast among examples of issues automated accessibility testing can catch.
Run:
const results =
await new AxeBuilder({ page })
.withTags([
‘wcag2aa’
])
.analyze();
expect(results.violations)
.toEqual([]);
However, don’t assume:
axe = complete WCAG compliance
Some issues require human judgment.
Examples include:
- Whether link text is understandable
- Whether focus order makes sense
- Whether instructions are clear
- Whether dynamic content is announced appropriately
- Whether a complete workflow works with a screen reader
16. Handling Accessibility Violations and False Positives
Real applications often contain known accessibility issues during migration.
You should not blindly ignore all violations.
Axe supports:
.exclude()
for excluding specific elements and:
.disableRules()
for disabling specific rules.
Example:
const results =
await new AxeBuilder({ page })
.exclude(‘#legacy-widget’)
.analyze();
But exclusions should be temporary and documented.
A better governance model is:
Known issue
↓
Document owner
↓
Create remediation ticket
↓
Temporary scoped exception
↓
Fix
↓
Remove exception
Do not use:
expect(results.violations).toEqual([]);
after filtering away most of the application just to make CI green.
17. Snapshotting Known Accessibility Violations
For some legacy applications, teams may need to ensure the existing accessibility debt does not increase.
Playwright’s accessibility documentation recommends fingerprinting known violations instead of snapshotting the entire axe violation object, because full results can contain fragile implementation details.
Example:
function violationFingerprints(
results: any
) {
return results.violations.map(
(violation: any) => ({
rule: violation.id,
targets: violation.nodes.map(
(node: any) => node.target
)
})
);
}
Then:
expect(
violationFingerprints(results)
).toMatchSnapshot();
This approach tracks the known problem more reliably than snapshotting rendered HTML snippets.
18. Creating Reusable Accessibility Fixtures
Enterprise frameworks should avoid creating a new AxeBuilder configuration in every test.
Create:
// fixtures/accessibility.fixture.ts
import { test as base, expect } from ‘@playwright/test’;
import AxeBuilder from ‘@axe-core/playwright’;
type AccessibilityFixtures = {
makeAxeBuilder: () => AxeBuilder;
};
export const test =
base.extend<AccessibilityFixtures>({
makeAxeBuilder: async ({ page }, use) => {
const makeAxeBuilder = () =>
new AxeBuilder({ page })
.withTags([
‘wcag2a’,
‘wcag2aa’,
‘wcag21a’,
‘wcag21aa’
]);
await use(makeAxeBuilder);
}
});
export { expect };
Then:
import {
test,
expect
} from ‘../fixtures/accessibility.fixture’;
test(‘product page accessibility’, async ({
page,
makeAxeBuilder
}) => {
await page.goto(‘/products’);
const results =
await makeAxeBuilder().analyze();
expect(results.violations)
.toEqual([]);
});
This fixture architecture is directly aligned with Playwright’s documented approach for sharing common axe configuration.
19. Accessibility Testing With Page Object Model
Accessibility checks can also live alongside Page Object Model behavior.
import {
expect,
Locator,
Page
} from ‘@playwright/test’;
export class CheckoutPage {
readonly email: Locator;
readonly address: Locator;
readonly placeOrder: Locator;
constructor(
private readonly page: Page
) {
this.email =
page.getByRole(‘textbox’, {
name: ‘Email address’
});
this.address =
page.getByRole(‘textbox’, {
name: ‘Billing address’
});
this.placeOrder =
page.getByRole(‘button’, {
name: ‘Place order’
});
}
async expectAccessibleForm() {
await expect(this.email)
.toBeVisible();
await expect(this.address)
.toBeVisible();
await expect(this.placeOrder)
.toHaveAccessibleName(
‘Place order’
);
}
}
This prevents accessibility assertions from becoming disconnected from business components.
20. Accessibility Testing Across Browsers and Devices
Playwright supports Chromium, Firefox, and WebKit, as well as mobile device emulation.
Configure projects:
projects: [
{
name: ‘chromium’,
use: {
browserName: ‘chromium’
}
},
{
name: ‘firefox’,
use: {
browserName: ‘firefox’
}
},
{
name: ‘webkit’,
use: {
browserName: ‘webkit’
}
}
]
Run:
npx playwright test tests/accessibility.spec.ts
or:
npx playwright test \
–project=chromium \
–project=firefox
Different browsers can expose rendering and interaction differences, so cross-browser accessibility regression is valuable.
Mobile projects should additionally validate:
- Touch targets
- Responsive navigation
- Focus behavior
- Dialogs
- Zoom/reflow
- Accessible labels
21. Accessibility Testing in CI/CD and GitHub Actions
Accessibility tests should run continuously rather than only before releases.
Example:
name: Accessibility Tests
on:
pull_request:
push:
branches:
– main
jobs:
accessibility:
runs-on: ubuntu-latest
steps:
– uses: actions/checkout@v6
– uses: actions/setup-node@v6
with:
node-version: lts/*
cache: npm
– run: npm ci
– run: npx playwright install –with-deps chromium
– name: Run accessibility tests
run: npx playwright test tests/accessibility
– name: Upload accessibility artifacts
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v5
with:
name: accessibility-results
path: |
test-results/
playwright-report/
Playwright’s CI documentation covers installing browsers and collecting reports/artifacts in CI environments.
A mature pipeline can separate:
Pull Request
↓
Critical accessibility checks
↓
Merge
↓
Full accessibility regression
↓
Nightly manual/AT validation
22. Accessibility Reports, Screenshots, Traces, and Debugging
When accessibility tests fail, collect evidence.
Configure:
use: {
screenshot: ‘only-on-failure’,
trace: ‘retain-on-failure’,
video: ‘retain-on-failure’
}
Then attach the axe result:
await testInfo.attach(
‘axe-results’,
{
body: JSON.stringify(
results,
null,
2
),
contentType: ‘application/json’
}
);
A failure should tell the developer:
Rule: color-contrast
Impact: serious
Element: .checkout-button
Target: #checkout
rather than simply:
Accessibility test failed
Playwright’s HTML report and UI Mode can help inspect test execution and failures.
23. Real-World E-Commerce Accessibility Testing Project
Consider an e-commerce application containing:
Homepage
Product listing
Product details
Cart
Checkout
Payment
Account
The accessibility suite can be organized into four layers.
Layer 1: Automated scans
Homepage
Product
Cart
Checkout
Account
Run axe against each page.
Layer 2: Component semantics
Validate:
Buttons
Links
Inputs
Dialogs
Navigation
Headings
Landmarks
Layer 3: Keyboard workflows
Test:
Search
Add to Cart
Open Cart
Checkout
Payment
Confirmation
using keyboard interactions.
Layer 4: Security and user-state accessibility
Test:
Guest
Authenticated user
Admin
Error state
Empty state
Loading state
This prevents accessibility testing from becoming a single “scan every page” exercise.
24. Common Playwright Accessibility Testing Errors and Solutions
| Problem | Cause | Solution |
| Axe finds no violations but screen reader fails | Automated coverage limitation | Perform manual AT testing |
| Button cannot be found by role | Missing/incorrect semantics | Fix HTML/ARIA |
| Accessible name is wrong | Missing label or bad ARIA | Use semantic labels |
| Keyboard test fails | Poor focus order | Fix DOM/focus behavior |
| Dialog loses focus | Incorrect focus management | Explicitly manage focus |
| CI has inconsistent results | Dynamic UI | Stabilize application state |
| Axe scans wrong state | Scan happens too early | Wait for desired UI state |
| Too many known violations | Legacy application | Baseline and remediate gradually |
| False confidence from axe | Automation-only strategy | Combine automated + manual testing |
| Cross-browser issue | Browser-specific behavior | Run accessibility projects across browsers |
A particularly important point is scan timing.
AxeBuilder.analyze() evaluates the page in its current state. If a menu or dialog appears only after interaction, perform that interaction and wait for the component before scanning it.
25. Playwright Accessibility Testing Best Practices
1. Prefer semantic locators
Use:
getByRole()
and:
getByLabel()
where appropriate.
2. Use axe as one layer
Do not define accessibility as:
axe = accessibility
Instead:
axe
+
keyboard
+
ARIA
+
focus
+
manual
3. Scan meaningful application states
Test:
- Default state
- Open menus
- Dialogs
- Validation errors
- Empty states
- Logged-in states
4. Avoid excessive exclusions
Every exclusion reduces coverage.
5. Track accessibility debt
Known issues should have owners and remediation plans.
6. Test keyboard workflows explicitly
Axe cannot replace keyboard interaction testing.
7. Validate accessible names
Use:
toHaveAccessibleName()
where the accessible name is part of the contract.
8. Test focus management
Especially for dialogs, menus, and dynamic content.
9. Integrate accessibility into CI
Catch regressions during pull requests.
10. Keep reports actionable
Attach scan results and debugging artifacts.
11. Test multiple browsers
Accessibility behavior should not be assumed identical across rendering engines.
12. Use manual assistive-technology testing
Automated tools detect only a subset of accessibility problems. Playwright explicitly recommends combining automated, manual, and inclusive user testing.
26. Advanced Playwright Accessibility Testing Interview Questions
1. Can Playwright perform accessibility testing?
Yes. Playwright can perform accessibility-oriented assertions and can integrate with @axe-core/playwright for automated accessibility scanning.
2. Does axe guarantee WCAG compliance?
No.
Axe detects many automatically testable issues, but automated testing cannot identify every WCAG problem.
3. What is the difference between getByRole() and CSS selectors?
getByRole() locates elements based on accessibility semantics and accessible names, making it useful for both robust automation and accessibility-oriented testing.
4. How do you test an accessible button?
const button =
page.getByRole(‘button’, {
name: ‘Submit’
});
await expect(button)
.toHaveAccessibleName(‘Submit’);
You can additionally verify:
await expect(button)
.toHaveRole(‘button’);
5. How do you test keyboard accessibility?
Use keyboard interactions and focus assertions:
await page.keyboard.press(‘Tab’);
await expect(
page.getByRole(‘button’, {
name: ‘Submit’
})
).toBeFocused();
6. How do you scan only a component?
Use:
new AxeBuilder({ page })
.include(‘#checkout’)
.analyze();
Axe supports scoped analysis through include().
7. How do you handle known violations?
Prefer a narrowly scoped temporary exclusion or disabled rule with an associated remediation ticket. Avoid permanently suppressing large sections of the application.
8. How do you test a dialog?
Validate:
- Dialog role
- Accessible name
- Focus entering the dialog
- Keyboard interaction
- Escape behavior where appropriate
- Focus returning to the trigger
9. How do you integrate accessibility testing into CI?
Install axe, run accessibility suites during CI, fail on agreed violations, and upload axe results, screenshots, traces, and reports as artifacts.
10. What is the most important accessibility automation limitation?
Automated tools cannot determine whether every interaction is genuinely usable by people with disabilities.
27. Playwright Accessibility Testing Learning Roadmap
Level 1: Playwright
Learn:
- TypeScript
- Locators
- Assertions
- Fixtures
- Page Object Model
Level 2: Accessibility Fundamentals
Learn:
- WCAG
- POUR
- Semantic HTML
- ARIA
- Accessible names
- Focus management
Level 3: Automated Accessibility
Learn:
- @axe-core/playwright
- AxeBuilder
- WCAG tags
- Include/exclude
- Rule configuration
- Accessibility reports
Level 4: Advanced Automation
Learn:
- Keyboard workflows
- Dialog accessibility
- Dynamic content
- Accessibility fixtures
- Cross-browser testing
- Component-level scans
Level 5: Enterprise Accessibility Engineering
Learn:
- CI/CD quality gates
- Accessibility debt management
- Custom reporting
- Screen-reader testing
- Manual accessibility assessment
- Inclusive user testing
For broader framework development, continue with Advanced Playwright Automation Techniques, Playwright Test Architecture for Large Projects, Playwright Multi-Tenant Testing Strategy, Playwright Network Mocking Advanced, Playwright Custom Reporter Development, Playwright Visual Regression Advanced Setup, Playwright Performance Testing Techniques, Playwright Custom Fixtures Advanced, Playwright Test Sharding Advanced, Playwright Authentication Tutorial, Playwright API Testing, Playwright Page Object Model, Playwright Fixtures Tutorial, Playwright Parallel Execution Tutorial, Playwright Reporting Tutorial, Playwright CI/CD Tutorial, Playwright GitHub Actions Tutorial, Playwright Docker Tutorial, Playwright TypeScript Tutorial, Playwright Framework Design, Playwright Best Practices, and Playwright Interview Questions.
28. FAQs: Playwright Accessibility Testing
What is Playwright accessibility testing?
It is the practice of using Playwright to validate accessibility semantics, keyboard behavior, focus management, ARIA roles, accessible names, and automatically detectable accessibility violations.
How do I perform accessibility testing in Playwright?
Install @axe-core/playwright, navigate to the target page, run AxeBuilder.analyze(), and assert that the returned violations collection meets your project’s policy.
Is Playwright accessibility testing enough for WCAG compliance?
No. Automated checks cover only some accessibility requirements. Manual assessment and assistive-technology testing are still necessary.
How do I use Axe with Playwright TypeScript?
import AxeBuilder from ‘@axe-core/playwright’;
const results =
await new AxeBuilder({ page })
.analyze();
Then:
expect(results.violations)
.toEqual([]);
How do I test ARIA roles in Playwright?
Use role-based locators and accessibility assertions:
await expect(
page.getByTestId(‘save’)
).toHaveRole(‘button’);
Playwright supports toHaveRole() and accessible-name/description assertions.
How do I test keyboard navigation?
Use page.keyboard together with toBeFocused():
await page.keyboard.press(‘Tab’);
await expect(
page.getByRole(‘button’, {
name: ‘Save’
})
).toBeFocused();
Can Playwright test color contrast?
Axe can detect many automatically testable color-contrast issues. However, visual and contextual accessibility assessment may still require manual review.
How do I scan a specific component?
Use:
await new AxeBuilder({ page })
.include(‘#checkout’)
.analyze();
AxeBuilder.include() scopes analysis to specified elements.
How do I run accessibility tests in GitHub Actions?
Install dependencies, install the required Playwright browsers, run the accessibility suite, and upload test reports and artifacts.
Should accessibility tests run on every pull request?
Critical automated checks should ideally run on pull requests. Broader accessibility regression and manual assistive-technology testing can be scheduled separately depending on project size.
