Skip to content

Commit 22eb38b

Browse files
committed
a11y #2 port playwright tests to repo
1 parent 29654ba commit 22eb38b

File tree

7 files changed

+503
-0
lines changed

7 files changed

+503
-0
lines changed

a11y/playwright/.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
2+
# Playwright
3+
node_modules/
4+
/test-results/
5+
/playwright-report/
6+
/blob-report/
7+
/playwright/.cache/
8+
/playwright/.auth/

a11y/playwright/README.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Playwright tests
2+
3+
## Target size test
4+
5+
The **target size** test (`tests/target_size.js`) opens a page, finds all focusable elements, measures their size, and writes a markdown report. Use it to check whether interactive controls meet [WCAG 2.2 target size](https://www.w3.org/WAI/WCAG22/Understanding/target-size.html) (Level AA: 24×24px minimum; Level AAA: 44×44px).
6+
7+
### Prerequisites
8+
9+
Install Playwright browsers once:
10+
11+
```bash
12+
npx playwright install
13+
```
14+
15+
### How to run
16+
17+
From the `playwright` directory:
18+
19+
```bash
20+
# Run with default URL (http://localhost:8000/olh/)
21+
npx playwright test target_size --project=chromium
22+
23+
# Run against a specific URL
24+
TARGET_SIZE_URL=https://example.com npx playwright test target_size --project=chromium
25+
```
26+
27+
To run in headed mode (see the browser):
28+
29+
```bash
30+
npx playwright test target_size --project=chromium --headed
31+
```
32+
33+
### What to expect
34+
35+
- The test **passes** if it can load the page and collect focusable elements (even if none are found).
36+
- A markdown report is written and attached to the run:
37+
- Path: `test-results/.../target-size-report.md` (exact path is printed in the test output).
38+
- It is also attached in the HTML report; open it with `npx playwright show-report` after a run.
39+
40+
The report includes:
41+
42+
1. **Header** – URL, generation time, and total number of focusable elements.
43+
2. **Table** with one row per focusable element:
44+
45+
| Column | Meaning |
46+
|--------|--------|
47+
| # | Index |
48+
| Tag | Element type (e.g. `a`, `button`, `input`) |
49+
| Name / Label | Accessible name from `aria-label`, `title`, `placeholder`, or text (trimmed) |
50+
| Width (px) | Rendered width in pixels |
51+
| Height (px) | Rendered height in pixels |
52+
| ≥24×24 (AA) | ✓ if both dimensions are ≥ 24px (WCAG 2.2 Level AA) |
53+
| ≥44×44 (AAA) | ✓ if both dimensions are ≥ 44px (WCAG 2.2 Level AAA) |
54+
55+
Elements counted as focusable include: links with `href`, buttons, inputs, selects, textareas, `summary`, `[contenteditable="true"]`, and elements with a non-negative `tabindex`. Hidden or zero-size elements are excluded.
56+
57+
### Example report snippet
58+
59+
```markdown
60+
# Focusable elements target size – http://localhost:8000/olh/
61+
62+
Generated: 2025-03-05T12:00:00.000Z
63+
Total focusable elements: 8
64+
65+
| # | Tag | Name / Label | Width (px) | Height (px) | ≥24×24 (AA) | ≥44×44 (AAA) |
66+
|---|-----|--------------|------------|-------------|-------------|--------------|
67+
| 1 | a | Home | 48 | 24 |||
68+
| 2 | button | Submit | 80 | 36 |||
69+
```
70+
71+
Use this report to find controls that are too small for touch or pointer and to plan fixes (e.g. larger hit areas or spacing).

a11y/playwright/package-lock.json

Lines changed: 97 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

a11y/playwright/package.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"name": "playwright",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {},
7+
"keywords": [],
8+
"author": "",
9+
"license": "ISC",
10+
"type": "commonjs",
11+
"devDependencies": {
12+
"@playwright/test": "^1.58.2",
13+
"@types/node": "^25.3.3"
14+
}
15+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
// @ts-check
2+
import { defineConfig, devices } from '@playwright/test';
3+
4+
/**
5+
* Read environment variables from file.
6+
* https://github.com/motdotla/dotenv
7+
*/
8+
// import dotenv from 'dotenv';
9+
// import path from 'path';
10+
// dotenv.config({ path: path.resolve(__dirname, '.env') });
11+
12+
/**
13+
* @see https://playwright.dev/docs/test-configuration
14+
*/
15+
export default defineConfig({
16+
testDir: './tests',
17+
testMatch: ['**/*.@(spec|test).?(c|m)[jt]s?(x)', '**/target_size.js'],
18+
/* Run tests in files in parallel */
19+
fullyParallel: true,
20+
/* Fail the build on CI if you accidentally left test.only in the source code. */
21+
forbidOnly: !!process.env.CI,
22+
/* Retry on CI only */
23+
retries: process.env.CI ? 2 : 0,
24+
/* Opt out of parallel tests on CI. */
25+
workers: process.env.CI ? 1 : undefined,
26+
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
27+
reporter: 'html',
28+
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
29+
use: {
30+
/* Base URL to use in actions like `await page.goto('')`. */
31+
// baseURL: 'http://localhost:3000',
32+
33+
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
34+
trace: 'on-first-retry',
35+
},
36+
37+
/* Configure projects for major browsers */
38+
projects: [
39+
{
40+
name: 'chromium',
41+
use: { ...devices['Desktop Chrome'] },
42+
},
43+
44+
{
45+
name: 'firefox',
46+
use: { ...devices['Desktop Firefox'] },
47+
},
48+
49+
{
50+
name: 'webkit',
51+
use: { ...devices['Desktop Safari'] },
52+
},
53+
54+
/* Test against mobile viewports. */
55+
// {
56+
// name: 'Mobile Chrome',
57+
// use: { ...devices['Pixel 5'] },
58+
// },
59+
// {
60+
// name: 'Mobile Safari',
61+
// use: { ...devices['iPhone 12'] },
62+
// },
63+
64+
/* Test against branded browsers. */
65+
// {
66+
// name: 'Microsoft Edge',
67+
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
68+
// },
69+
// {
70+
// name: 'Google Chrome',
71+
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
72+
// },
73+
],
74+
75+
/* Run your local dev server before starting the tests */
76+
// webServer: {
77+
// command: 'npm run start',
78+
// url: 'http://localhost:3000',
79+
// reuseExistingServer: !process.env.CI,
80+
// },
81+
});
82+
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// @ts-check
2+
import { test, expect } from '@playwright/test';
3+
4+
test('has title', async ({ page }) => {
5+
await page.goto('https://playwright.dev/');
6+
7+
// Expect a title "to contain" a substring.
8+
await expect(page).toHaveTitle(/Playwright/);
9+
});
10+
11+
test('get started link', async ({ page }) => {
12+
await page.goto('https://playwright.dev/');
13+
14+
// Click the get started link.
15+
await page.getByRole('link', { name: 'Get started' }).click();
16+
17+
// Expects page to have a heading with the name of Installation.
18+
await expect(page.getByRole('heading', { name: 'Installation' })).toBeVisible();
19+
});

0 commit comments

Comments
 (0)