This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import AxeBuilder from '@axe-core/playwright'
|
||||
import { expect, test } from '@playwright/test'
|
||||
|
||||
const email = process.env.DEVRUNBOOK_E2E_EMAIL
|
||||
const password = process.env.DEVRUNBOOK_E2E_PASSWORD
|
||||
|
||||
const criticalRoutes = [
|
||||
'/start',
|
||||
'/composer/new',
|
||||
'/repositories',
|
||||
'/runs',
|
||||
'/account',
|
||||
'/account/security',
|
||||
'/repositories/new',
|
||||
'/management',
|
||||
] as const
|
||||
|
||||
test.describe('Phase 14 accessibility regression', () => {
|
||||
test.skip(!email || !password, 'live local-account credentials are required')
|
||||
test.use({
|
||||
storageState: 'test-results/.auth/m2.json',
|
||||
reducedMotion: 'reduce',
|
||||
})
|
||||
|
||||
for (const route of criticalRoutes) {
|
||||
test(`${route} has one main and no serious accessibility violations`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.goto(route)
|
||||
await expect(page.locator('main')).toHaveCount(1)
|
||||
await expect(page.locator('[id]')).toHaveCount(
|
||||
await page
|
||||
.locator('[id]')
|
||||
.evaluateAll(
|
||||
(elements) => new Set(elements.map((element) => element.id)).size,
|
||||
),
|
||||
)
|
||||
const results = await new AxeBuilder({ page })
|
||||
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
|
||||
.analyze()
|
||||
expect(
|
||||
results.violations.filter(
|
||||
({ impact }) => impact === 'critical' || impact === 'serious',
|
||||
),
|
||||
).toEqual([])
|
||||
})
|
||||
}
|
||||
|
||||
test('Start remains keyboard complete, reflows and exposes touch targets', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.setViewportSize({ width: 390, height: 844 })
|
||||
await page.goto('/start')
|
||||
await page.keyboard.press('Tab')
|
||||
await expect(page.locator(':focus-visible')).toHaveCount(1)
|
||||
expect(
|
||||
await page.evaluate(
|
||||
() =>
|
||||
document.documentElement.scrollWidth <=
|
||||
document.documentElement.clientWidth,
|
||||
),
|
||||
).toBe(true)
|
||||
const undersizedPrimaryTargets = await page
|
||||
.locator('main button, main a[href="/settings/integrations/gitea/new"]')
|
||||
.evaluateAll((elements) =>
|
||||
elements
|
||||
.filter((element) => {
|
||||
const box = element.getBoundingClientRect()
|
||||
const style = getComputedStyle(element)
|
||||
return (
|
||||
style.display !== 'none' &&
|
||||
style.visibility !== 'hidden' &&
|
||||
box.width > 0 &&
|
||||
box.height > 0 &&
|
||||
(box.width < 44 || box.height < 44)
|
||||
)
|
||||
})
|
||||
.map(
|
||||
(element) =>
|
||||
element.getAttribute('aria-label') ?? element.textContent,
|
||||
),
|
||||
)
|
||||
expect(undersizedPrimaryTargets).toEqual([])
|
||||
})
|
||||
|
||||
test('critical pages reflow at a 200 percent equivalent CSS viewport', async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.setViewportSize({ width: 640, height: 720 })
|
||||
for (const route of criticalRoutes) {
|
||||
await page.goto(route)
|
||||
expect(
|
||||
await page.evaluate(
|
||||
() =>
|
||||
document.documentElement.scrollWidth <=
|
||||
document.documentElement.clientWidth,
|
||||
),
|
||||
).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
for (const locale of ['en', 'nl'] as const) {
|
||||
for (const mode of ['simple', 'expert'] as const) {
|
||||
test(`${locale}/${mode} presentation stays accessible`, async ({
|
||||
page,
|
||||
context,
|
||||
baseURL,
|
||||
}) => {
|
||||
const origin = new URL(baseURL ?? 'http://127.0.0.1:3000')
|
||||
await context.addCookies([
|
||||
{ name: 'devrunbook_locale', value: locale, url: origin.origin },
|
||||
{ name: 'devrunbook_mode', value: mode, url: origin.origin },
|
||||
])
|
||||
await page.goto('/start')
|
||||
await expect(
|
||||
page.getByRole('heading', {
|
||||
name:
|
||||
locale === 'nl' ? 'Wat wil je doen?' : 'What do you want to do?',
|
||||
}),
|
||||
).toBeVisible()
|
||||
const results = await new AxeBuilder({ page })
|
||||
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
|
||||
.analyze()
|
||||
expect(
|
||||
results.violations.filter(
|
||||
({ impact }) => impact === 'critical' || impact === 'serious',
|
||||
),
|
||||
).toEqual([])
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user