Install
$ agentstack add skill-vibeeval-vibecosystem-accessibility-testing ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Accessibility Testing
axe-core Setup
jest-axe (unit / component tests)
import { axe, toHaveNoViolations } from 'jest-axe'
import { render } from '@testing-library/react'
expect.extend(toHaveNoViolations)
test('LoginForm has no a11y violations', async () => {
const { container } = render()
const results = await axe(container)
expect(results).toHaveNoViolations()
})
playwright-axe (e2e)
import { test, expect } from '@playwright/test'
import AxeBuilder from '@axe-core/playwright'
test('homepage passes axe audit', async ({ page }) => {
await page.goto('/')
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21aa'])
.analyze()
expect(results.violations).toEqual([])
})
cypress-axe
// cypress/support/e2e.js
import 'cypress-axe'
// in test
cy.visit('/')
cy.injectAxe()
cy.checkA11y(null, {
runOnly: { type: 'tag', values: ['wcag2aa'] },
})
WCAG 2.2 AA Checklist — Top 20 Violations
| # | Criterion | Check | |---|-----------|-------| | 1 | Images have alt text | ` or alt="" for decorative | | 2 | Form inputs have labels | or aria-label or aria-labelledby | | 3 | Color contrast ≥ 4.5:1 | Normal text; 3:1 for large text (18pt or 14pt bold) | | 4 | Heading hierarchy | h1 → h2 → h3, no skipping levels | | 5 | Keyboard focusable | All interactive elements reachable via Tab | | 6 | Focus visible | :focus outline never outline: none without replacement | | 7 | No keyboard trap | Tab can always exit modals, dropdowns, widgets | | 8 | Skip navigation link | First focusable element: "Skip to main content" | | 9 | Page has | Unique, descriptive per page | | 10 | Language attribute | | | 11 | Error identification | Form errors are text, not color-only | | 12 | Error suggestions | Tell users how to fix the error | | 13 | Link purpose clear | No "click here" or "read more" without context | | 14 | Button text | No icon-only buttons without aria-label | | 15 | Table headers | on data tables | | 16 | No seizure content | No flashing > 3 times/sec | | 17 | Status messages | role="status" or aria-live` for dynamic updates | | 18 | Reflow at 400% zoom | Single column, no horizontal scroll | | 19 | Text spacing adjustable | No overflow when line-height/letter-spacing increased | | 20 | Timeout warning | Warn before session expires, allow extension |
Keyboard Navigation Test Patterns
Tab order verification
test('modal tab order is correct', async ({ page }) => {
await page.click('[data-testid="open-modal"]')
// First focus should be the modal's close button or heading
await expect(page.locator('[aria-label="Close dialog"]')).toBeFocused()
// Tab through: close → input → submit
await page.keyboard.press('Tab')
await expect(page.locator('#email-input')).toBeFocused()
await page.keyboard.press('Tab')
await expect(page.locator('[type="submit"]')).toBeFocused()
// Wrap back to close button (focus trap)
await page.keyboard.press('Tab')
await expect(page.locator('[aria-label="Close dialog"]')).toBeFocused()
})
Focus trap in modals
// Escape should close
await page.keyboard.press('Escape')
await expect(page.locator('[role="dialog"]')).not.toBeVisible()
// Focus returns to trigger element after close
await expect(page.locator('[data-testid="open-modal"]')).toBeFocused()
Skip navigation link
test('skip link goes to main content', async ({ page }) => {
await page.goto('/')
await page.keyboard.press('Tab') // first tab = skip link
const skipLink = page.locator('a:has-text("Skip to")')
await expect(skipLink).toBeFocused()
await page.keyboard.press('Enter')
await expect(page.locator('main, #main-content')).toBeFocused()
})
Arrow key navigation (listbox/menu)
test('dropdown menu responds to arrow keys', async ({ page }) => {
await page.click('[aria-haspopup="listbox"]')
await page.keyboard.press('ArrowDown') // first option focused
await page.keyboard.press('ArrowDown') // second option
await page.keyboard.press('Enter') // select
// Verify selection
await expect(page.locator('[aria-selected="true"]')).toContainText('Option 2')
})
ARIA Patterns
Live regions (dynamic announcements)
Your payment failed. Please try again.
Showing 42 results for "laptop"
.sr-only {
position: absolute; width: 1px; height: 1px;
padding: 0; margin: -1px; overflow: hidden;
clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
Dialog / Modal
Confirm Delete
This action cannot be undone.
Cancel
Delete
Tabs
Profile
Billing
...
...
Combobox / Autocomplete
Search users
Alice
Bob
Color Contrast Requirements
| Text Size | Minimum Ratio | Enhanced (AAA) | |-----------|--------------|----------------| | Normal text (
...
...
Email address
Email is required
## CI Integration (axe-core in GitHub Actions)
```yaml
# .github/workflows/a11y.yml
name: Accessibility Tests
on: [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
- run: npm run test:a11y
- uses: actions/upload-artifact@v4
if: failure()
with:
name: a11y-report
path: playwright-report/
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: vibeeval
- Source: vibeeval/vibecosystem
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.