playwright-testing
Skill409 starsChanged 6 months agoMITView on GitHub
Browser accessibility testing using Playwright and @axe-core/playwright. Keyboard scans, contrast verification, and accessibility tree snapshots.
- Reads credentials
- Installs packages
18 other projects use a version of this.
Adopted by
Most recently taken up by
- kazemcodes/skill-treetheir own version, first seen Nov 8, 2026
- n-n-code/n-n-code-skillstheir own version, first seen Nov 1, 2026
- suryas91/claude-skillstheir own version, first seen Oct 11, 2026
- TangleML/tangle-uitheir own version, first seen Oct 8, 2026
- PrairieLearn/PrairieLearntheir own version, first seen Oct 8, 2026
- fossasia/visdomtheir own version, first seen Oct 8, 2026
Used with
Projects with it also use security, ponytail and 1 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
0xSeroSkillsecurity
Also in 3 projects that use this
GoogleSkillponytail
Forces the laziest solution that actually works, simplest, shortest, most minimal. Channels a senior dev who has seen everything: question whether the task needs to exist at all (YAGNI), reach for the standard library before custom code, native platform features before dependencies, one line before fifty. Supports intensity levels: lite, full (default), ultra. Use on ANY coding task: writing, adding, refactoring, fixing, reviewing, or designing code, and choosing libraries or dependencies. Also use whenever the user says "ponytail", "be lazy", "lazy mode", "simplest solution", "minimal solution", "yagni", "do less", or "shortest path", or complains about over-engineering, bloat, boilerplate, or unnecessary dependencies. Do NOT use for non-coding requests (general knowledge, prose, translation, summaries, recipes).
Also in 3 projects that use this
GoogleSkillgrill-me
A relentless interview to sharpen a plan or design.
Also in 3 projects that use this
Other versions18 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 18
- fossasia/visdom★ 10ksame name
- podman-desktop/podman-desktop★ 8.1ksame name
- silvertakana/worldwideview★ 1.9ksame name
- marmelab/atomic-crm★ 1.4ksame name
- alinaqi/maggy★ 711same name
- alinaqi/claude-bootstrap★ 708same name
- PrairieLearn/PrairieLearn★ 530same name
- chongdashu/vibejam-starter-pack★ 147same name
- TangleML/tangle-ui★ 104same name
- navikt/copilot★ 61same name
8 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository31 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .claude/AGENTS.mdAGENTS.md
- claude-code-plugin/AGENTS.mdAGENTS.md
- claude-code-plugin/CLAUDE.mdCLAUDE.md
- CLAUDE.mdCLAUDE.md
- .github/copilot-instructions.mdCopilot instructions
- accessibility-rulesSkill
- ci-integrationSkill
- cognitive-accessibilitySkill
- data-visualization-accessibilitySkill
- design-systemSkill
- document-scanningSkill
- email-accessibilitySkill
- framework-accessibilitySkill
- github-a11y-scannerSkill
- github-analytics-scoringSkill
- github-scanningSkill
- github-workflow-standardsSkill
- help-url-referenceSkill
- legal-compliance-mappingSkill
- lighthouse-scannerSkill
- markdown-accessibilitySkill
- media-accessibilitySkill
- mobile-accessibilitySkill
- office-remediationSkill
- python-developmentSkill
- report-generationSkill
- severity-mappingSkill
- testing-strategySkill
- web-scanningSkill
- web-severity-scoringSkill
The file
Files
Playwright Accessibility Testing
Reusable knowledge module for browser-based accessibility testing using Playwright and @axe-core/playwright.
MCP Tools Available
| Tool | Purpose | Requires @axe-core/playwright |
run_playwright_keyboard_scan | Tab-order traversal, keyboard trap detection | No |
run_playwright_state_scan | Click triggers, scan revealed content with axe-core | Yes |
run_playwright_viewport_scan | Multi-viewport axe-core + touch target measurement | Yes |
run_playwright_contrast_scan | Computed-style contrast ratio after CSS cascade | No |
run_playwright_a11y_tree | Browser accessibility tree snapshot | No |
@axe-core/playwright Patterns
Full Page Scan
import AxeBuilder from '@axe-core/playwright';
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa'])
.analyze();Scoped Element Scan
const results = await new AxeBuilder({ page })
.include('.modal-content')
.withTags(['wcag2a', 'wcag2aa'])
.analyze();Single Rule Verification
const results = await new AxeBuilder({ page })
.include('#hero-image')
.withRules(['image-alt'])
.analyze();
expect(results.violations).toEqual([]);Scan After Interaction
await page.click('[aria-expanded="false"]');
await page.waitForSelector('.accordion-content', { state: 'visible' });
const results = await new AxeBuilder({ page })
.include('.accordion-content')
.analyze();Keyboard Traversal Patterns
Record Tab Sequence
const tabStops = [];
for (let i = 0; i < maxTabs; i++) {
await page.keyboard.press('Tab');
const info = await page.evaluate(() => {
const el = document.activeElement;
return {
tagName: el?.tagName,
role: el?.getAttribute('role'),
name: el?.getAttribute('aria-label') || el?.textContent?.trim().slice(0, 50),
id: el?.id,
tabIndex: el?.tabIndex
};
});
tabStops.push(info);
}Detect Keyboard Traps
A keyboard trap is detected when the same element receives focus after consecutive Tab presses:
let trapCount = 0;
let lastSelector = '';
for (const stop of tabStops) {
const currentSelector = `${stop.tagName}#${stop.id}`;
if (currentSelector === lastSelector) {
trapCount++;
if (trapCount >= 3) { /* TRAP DETECTED */ }
} else {
trapCount = 0;
}
lastSelector = currentSelector;
}Focus Management After Modal Open
await page.click('[data-modal-trigger]');
await page.waitForSelector('[role="dialog"]', { state: 'visible' });
const focusedRole = await page.evaluate(() =>
document.activeElement?.closest('[role="dialog"]') ? 'inside-dialog' : 'outside-dialog'
);
// focusedRole should be 'inside-dialog'Focus Management Test Templates
Modal Focus Trap Test
test('modal traps focus correctly', async ({ page }) => {
await page.goto(url);
await page.click('[data-open-modal]');
await page.waitForSelector('[role="dialog"]', { state: 'visible' });
// Focus should be inside the dialog
const inDialog = await page.evaluate(() =>
document.activeElement?.closest('[role="dialog"]') !== null
);
expect(inDialog).toBe(true);
// Tab through dialog — should not escape
for (let i = 0; i < 20; i++) {
await page.keyboard.press('Tab');
const stillInDialog = await page.evaluate(() =>
document.activeElement?.closest('[role="dialog"]') !== null
);
expect(stillInDialog).toBe(true);
}
// Escape should close and return focus to trigger
await page.keyboard.press('Escape');
const focusedId = await page.evaluate(() => document.activeElement?.id);
expect(focusedId).toBe('modal-trigger-id');
});Skip Link Test
test('skip link moves focus to main content', async ({ page }) => {
await page.goto(url);
await page.keyboard.press('Tab'); // Focus skip link
await page.keyboard.press('Enter'); // Activate it
const focusedId = await page.evaluate(() => document.activeElement?.id);
expect(focusedId).toBe('main-content');
});CI Integration
GitHub Actions with Playwright
name: Accessibility Tests
on: [push, pull_request]
jobs:
a11y:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npx playwright install --with-deps chromium
- name: Start dev server
run: npm run dev &
env:
CI: true
- name: Wait for server
run: npx wait-on http://localhost:3000 --timeout 30000
- name: Run accessibility tests
run: npx playwright test tests/a11y/
- uses: actions/upload-artifact@v4
if: failure()
with:
name: a11y-test-results
path: test-results/Playwright Config for Accessibility Tests
// playwright.config.js (a11y section)
export default {
testDir: './tests/a11y',
use: {
baseURL: process.env.BASE_URL || 'http://localhost:3000',
// Use Chromium only — @axe-core/playwright is Chromium-validated
browserName: 'chromium',
},
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
},
};Graceful Degradation
Detection Pattern
let _playwrightAvailable = null;
async function isPlaywrightAvailable() {
if (_playwrightAvailable !== null) return _playwrightAvailable;
try {
await import('playwright');
_playwrightAvailable = true;
} catch {
_playwrightAvailable = false;
}
return _playwrightAvailable;
}Degradation Matrix
| Playwright | @axe-core/playwright | Available Scans |
| Yes | Yes | All 5 tools (keyboard, state, viewport, contrast, tree) |
| Yes | No | 3 tools (keyboard, contrast, tree) |
| No | — | None — fall back to code review + axe-core CLI |
User-Facing Messages
When unavailable:
Playwright not installed. Behavioral testing (keyboard traversal, dynamic states,
responsive viewport, rendered contrast) is unavailable.
Install: npm install -D playwright @axe-core/playwright && npx playwright install chromiumWhen partially available:
@axe-core/playwright not installed. State scanning and viewport scanning are
unavailable. Keyboard, contrast, and accessibility tree scans will proceed.
Install: npm install -D @axe-core/playwrightWCAG Coverage Map
| WCAG SC | Description | Playwright Tool |
| 1.3.1 | Info and Relationships | a11y tree, state scan |
| 1.4.3 | Contrast (Minimum) | contrast scan |
| 1.4.6 | Contrast (Enhanced) | contrast scan |
| 1.4.10 | Reflow | viewport scan |
| 2.1.1 | Keyboard | keyboard scan |
| 2.1.2 | No Keyboard Trap | keyboard scan |
| 2.4.3 | Focus Order | keyboard scan |
| 2.4.7 | Focus Visible | keyboard scan |
| 2.5.5 | Target Size (Enhanced) | viewport scan |
| 2.5.8 | Target Size (Minimum) | viewport scan |
| 4.1.2 | Name, Role, Value | a11y tree, state scan |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

