Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/accessibility.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: Accessibility

on:
pull_request:
branches: [graphiql-6]

permissions:
contents: read

jobs:
a11y:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
cache: yarn
- run: yarn install --immutable
- run: yarn build
- run: npx playwright install --with-deps chromium
- run: |
yarn workspace @graphiql/react storybook --port 6006 --ci --no-open &
npx wait-on http://localhost:6006 -t 60000
yarn workspace @graphiql/react test:a11y
62 changes: 62 additions & 0 deletions packages/graphiql-react/.storybook/a11y-baseline.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"stories": {
"primitives-spinner--default": {
"violations": [
{
"id": "landmark-one-main",
"impact": "moderate",
"tags": ["cat.semantics", "best-practice"],
"description": "Ensure the document has a main landmark",
"help": "Document should have one main landmark",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.11/landmark-one-main?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "page-has-main",
"data": null,
"relatedNodes": [],
"impact": "moderate",
"message": "Document does not have a main landmark"
}
],
"none": [],
"impact": "moderate",
"html": "<html lang=\"en\">",
"target": ["html"],
"failureSummary": "Fix all of the following:\n Document does not have a main landmark"
}
]
},
{
"id": "page-has-heading-one",
"impact": "moderate",
"tags": ["cat.semantics", "best-practice"],
"description": "Ensure that the page, or at least one of its frames contains a level-one heading",
"help": "Page should contain a level-one heading",
"helpUrl": "https://dequeuniversity.com/rules/axe/4.11/page-has-heading-one?application=axeAPI",
"nodes": [
{
"any": [],
"all": [
{
"id": "page-has-heading-one",
"data": null,
"relatedNodes": [],
"impact": "moderate",
"message": "Page must have a level-one heading"
}
],
"none": [],
"impact": "moderate",
"html": "<html lang=\"en\">",
"target": ["html"],
"failureSummary": "Fix all of the following:\n Page must have a level-one heading"
}
]
}
]
}
}
}
2 changes: 1 addition & 1 deletion packages/graphiql-react/.storybook/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { StorybookConfig } from '@storybook/react-vite';

const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(ts|tsx)'],
addons: [],
addons: ['@storybook/addon-a11y'],
framework: { name: '@storybook/react-vite', options: {} },
};

Expand Down
4 changes: 4 additions & 0 deletions packages/graphiql-react/.storybook/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import '../src/style/root.css';
const preview: Preview = {
parameters: {
backgrounds: { disable: true },
a11y: {
config: { rules: [] },
options: { runOnly: ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'] },
},
},
globalTypes: {
theme: {
Expand Down
53 changes: 53 additions & 0 deletions packages/graphiql-react/.storybook/test-runner.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import type { TestRunnerConfig } from '@storybook/test-runner';
import { getStoryContext } from '@storybook/test-runner';
import { injectAxe, configureAxe, getViolations } from 'axe-playwright';
import { readFileSync, writeFileSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const baselinePath = join(__dirname, 'a11y-baseline.json');
const baseline = JSON.parse(readFileSync(baselinePath, 'utf-8')) as {
stories: Record<string, { violations: any[] }>;
};
const updateBaseline = process.env.A11Y_UPDATE_BASELINE === '1';

const config: TestRunnerConfig = {
async preVisit(page) {
await injectAxe(page);
},
async postVisit(page, context) {
const storyContext = await getStoryContext(page, context);
if (storyContext.parameters?.a11y?.disable) {
return;
}

await configureAxe(page, {
rules: storyContext.parameters?.a11y?.config?.rules ?? [],
});

const violations = await getViolations(page);
const storyId = context.id;

if (updateBaseline) {
baseline.stories[storyId] = { violations };
writeFileSync(baselinePath, JSON.stringify(baseline, null, 2) + '\n');
return;
}

const baselineViolations = baseline.stories[storyId]?.violations ?? [];
const toKey = (v: { id: string; nodes: unknown[] }) =>
`${v.id}:${v.nodes.length}`;
const baselineKeys = new Set(baselineViolations.map(toKey));
const newViolations = violations.filter(v => !baselineKeys.has(toKey(v)));

if (newViolations.length > 0) {
const summary = newViolations
.map(v => ` - ${v.id}: ${v.help} (${v.nodes.length} node(s))`)
.join('\n');
throw new Error(`New a11y violations in "${storyId}":\n${summary}`);
}
},
};

export default config;
7 changes: 6 additions & 1 deletion packages/graphiql-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@
"build": "vite build",
"build-storybook": "storybook build",
"storybook": "storybook dev -p 6006",
"test": "vitest run --typecheck"
"test": "vitest run --typecheck",
"test:a11y": "test-storybook --config-dir .storybook",
"test:a11y:update": "A11Y_UPDATE_BASELINE=1 test-storybook --config-dir .storybook"
},
"peerDependencies": {
"graphql": "^15.5.0 || ^16.0.0 || ^17.0.0",
Expand Down Expand Up @@ -72,12 +74,15 @@
},
"devDependencies": {
"@babel/helper-string-parser": "^7.19.4",
"@storybook/addon-a11y": "^10.3.6",
"@storybook/react-vite": "^10.3.6",
"@storybook/test-runner": "^0.24.3",
"@types/get-value": "^3.0.5",
"@types/markdown-it": "^14.1.2",
"@types/react-dom": "^19.1.2",
"@types/set-value": "^4.0.1",
"@vitejs/plugin-react": "^4.4.1",
"axe-playwright": "^2",
"babel-plugin-react-compiler": "19.1.0-rc.1",
"graphql": "^16.9.0",
"react": "^19.1.0",
Expand Down
3 changes: 3 additions & 0 deletions resources/custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ browserslistrc
calar
chainable
changesets
circlehollow
clsx
codebases
codegen
Expand All @@ -57,6 +58,7 @@ combobox
cshaver
dedenting
delivr
deps
devx
dhanani
dima
Expand Down Expand Up @@ -242,6 +244,7 @@ vitejs
vitest
vizag
vsix
wcag
webp
websockets
wgutils
Expand Down
Loading
Loading