Skip to content

Commit

Permalink
Component accessibility testing (#1352)
Browse files Browse the repository at this point in the history
Co-authored-by: Mayank <[email protected]>
  • Loading branch information
xman343 and mayank99 authored Jun 29, 2023
1 parent e73eec4 commit d1dc494
Show file tree
Hide file tree
Showing 26 changed files with 225 additions and 35 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -376,3 +376,33 @@ jobs:
with:
name: 'cypress-visual-screenshots'
path: '${{ github.workspace }}/apps/storybook/cypress-visual-screenshots'
a11y:
name: Test for a11y violations
needs: install
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Use Node 18.X
uses: actions/setup-node@v3
with:
node-version: 18.x

- name: Cache node_modules
uses: actions/cache@v3
id: cache-node-modules
with:
path: |
node_modules
packages/*/node_modules
apps/*/node_modules
playgrounds/*/node_modules
key: modules-${{ runner.os }}-${{ hashFiles('yarn.lock') }}

- run: yarn build --filter=itwinui-react

- uses: cypress-io/github-action@v5
with:
working-directory: testing/a11y
component: true
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion apps/storybook/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@types/react": "^18.0.2",
"@types/react-dom": "^18.0.2",
"configs": "*",
"cypress": "12.11.0",
"cypress": "12.16.0",
"cypress-image-diff-js": "1.23.0",
"dotenv-cli": "7.0.0",
"eslint": "^8.14.0",
Expand Down
2 changes: 1 addition & 1 deletion apps/storybook/scripts/run-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
const spawn = require('child_process').spawn;
const args = process.argv.slice(2).join(' ');

const IMAGE_NAME = 'cypress/included:12.11.0'; // https://hub.docker.com/r/cypress/included
const IMAGE_NAME = 'cypress/included:12.16.0'; // https://hub.docker.com/r/cypress/included

// Need to use this script because current directory variable is different in different shells
const dockerProcess = spawn(
Expand Down
2 changes: 1 addition & 1 deletion examples/Anchor.asbutton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Anchor } from '@itwin/itwinui-react';

export default () => {
return (
<Anchor as='button' onClick={console.log('Button clicked!')}>
<Anchor as='button' onClick={() => console.log('Button clicked!')}>
Anchor as a button
</Anchor>
);
Expand Down
2 changes: 1 addition & 1 deletion examples/ButtonGroup.input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
Flex,
Button,
} from '@itwin/itwinui-react';
import { SvgSearch, SvgAdd } from '@itwin/itwinui-icons-react';
import { SvgSearch } from '@itwin/itwinui-icons-react';

export default () => {
return (
Expand Down
9 changes: 1 addition & 8 deletions examples/ButtonGroup.overflow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,7 @@ import {
IconButton,
MenuItem,
} from '@itwin/itwinui-react';
import {
SvgAdd,
SvgEdit,
SvgDelete,
SvgUndo,
SvgMore,
SvgPlaceholder,
} from '@itwin/itwinui-icons-react';
import { SvgMore, SvgPlaceholder } from '@itwin/itwinui-icons-react';

export default () => {
const buttons = Array(12)
Expand Down
1 change: 0 additions & 1 deletion examples/ColorPicker.advancedPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import * as React from 'react';
import {
ColorBuilder,
ColorInputPanel,
ColorPalette,
ColorPicker,
ColorValue,
Expand Down
5 changes: 4 additions & 1 deletion examples/ComboBox.custom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ export default () => {
}, []);

const itemRenderer = React.useCallback(
({ value, label }, { isSelected, id }) => (
(
{ value, label }: { value: string; label: string },
{ isSelected, id }: { isSelected: boolean; id: string },
) => (
<MenuItem key={id} id={id} isSelected={isSelected} value={value}>
<em
style={{
Expand Down
3 changes: 2 additions & 1 deletion examples/ComboBox.disabled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import { ComboBox, SelectOption } from '@itwin/itwinui-react';
import type { SelectOption } from '@itwin/itwinui-react';
import { ComboBox } from '@itwin/itwinui-react';

export default () => {
const [value, setValue] = React.useState('');
Expand Down
3 changes: 2 additions & 1 deletion examples/ComboBox.loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import { ComboBox, MenuItemSkeleton, SelectOption } from '@itwin/itwinui-react';
import type { SelectOption } from '@itwin/itwinui-react';
import { ComboBox, MenuItemSkeleton } from '@itwin/itwinui-react';

export default () => {
const countriesList = React.useMemo(
Expand Down
2 changes: 1 addition & 1 deletion examples/Dialog.dismissible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
// import * as ReactDOM from 'react-dom';
import {
Dialog,
Button,
Expand Down
2 changes: 1 addition & 1 deletion examples/Dialog.draggable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
// import * as ReactDOM from 'react-dom';
import {
Dialog,
Button,
Expand Down
2 changes: 1 addition & 1 deletion examples/Dialog.main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
// import * as ReactDOM from 'react-dom';
import { Dialog, Button } from '@itwin/itwinui-react';

export default () => {
Expand Down
2 changes: 1 addition & 1 deletion examples/Dialog.nondismissible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
// import * as ReactDOM from 'react-dom';
import { Dialog, Button } from '@itwin/itwinui-react';

export default () => {
Expand Down
2 changes: 1 addition & 1 deletion examples/Dialog.placement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import * as ReactDOM from 'react-dom';
// import * as ReactDOM from 'react-dom';
import { Dialog, Button } from '@itwin/itwinui-react';

export default () => {
Expand Down
2 changes: 1 addition & 1 deletion examples/Fieldset.disabled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import { Fieldset, LabeledInput, Flex } from '@itwin/itwinui-react';
import { Fieldset, LabeledInput } from '@itwin/itwinui-react';

export default () => {
return (
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
"packages/*",
"playgrounds/*",
"internal/*",
"examples"
"examples",
"testing/*"
]
},
"lint-staged": {
Expand Down
5 changes: 5 additions & 0 deletions testing/a11y/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
/test-results/
.next/
cypress/videos
cypress/screenshots
37 changes: 37 additions & 0 deletions testing/a11y/cypress.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import { defineConfig } from 'cypress';
import react from '@vitejs/plugin-react';
import { createRequire } from 'node:module';

const require = createRequire(import.meta.url);
const axeCorePath = require.resolve('axe-core');

export default defineConfig({
component: {
devServer: {
framework: 'react',
bundler: 'vite',
viteConfig: {
plugins: [react()],
},
},
env: { axeCorePath },
video: false,
screenshotOnRunFailure: false,
setupNodeEvents(on, config) {
on('task', {
log(message) {
console.log(message);
return null;
},
table(message) {
console.table(message);
return null;
},
});
},
},
});
25 changes: 25 additions & 0 deletions testing/a11y/cypress/support/component-index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<!--
Copyright (c) Bentley Systems, Incorporated. All rights reserved.
See LICENSE.md in the project root for license terms and full copyright notice.
-->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta
name="color-scheme"
content="dark"
/>
<meta
name="viewport"
content="width=device-width,initial-scale=1.0"
>
<title>a11y testing</title>
</head>
<body>
<main>
<h1>a11y testing</h1>
<div data-cy-root></div>
</main>
</body>
</html>
34 changes: 34 additions & 0 deletions testing/a11y/cypress/support/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
// ***********************************************************
// This example support/component.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************

import { mount } from 'cypress/react18';

declare global {
namespace Cypress {
interface Chainable {
mount: typeof mount;
}
}
}

Cypress.Commands.add('mount', mount);

import '@itwin/itwinui-react/styles.css';

import 'cypress-axe';
18 changes: 18 additions & 0 deletions testing/a11y/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"name": "a11y",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "cypress run --component",
"open": "cypress open --component",
"clean": "rimraf .turbo && rimraf node_modules"
},
"dependencies": {
"@itwin/itwinui-react": "3.0.0-dev.3",
"axe-core": "^4.7.2",
"cypress": "^12.16.0",
"cypress-axe": "^1.4.0",
"examples": "*"
}
}
30 changes: 30 additions & 0 deletions testing/a11y/src/Component.cy.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
import * as React from 'react';
import * as allExamples from 'examples';
import { ThemeProvider } from '@itwin/itwinui-react';

describe('Should have no WCAG violations', () => {
Object.entries(allExamples).forEach(([name, Component]) => {
it(name, () => {
cy.mount(
<ThemeProvider theme='dark' style={{ height: '100vh' }}>
<Component />
</ThemeProvider>,
);
cy.injectAxe({
axeCorePath: Cypress.env('axeCorePath'),
});
cy.checkA11y(undefined, undefined, (violations) => {
const violationData = violations.map(({ id, help }) => ({
Component: name,
'Rule ID': id,
Description: help,
}));
cy.task('table', violationData);
});
});
});
});
3 changes: 3 additions & 0 deletions turbo.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
"@itwin/itwinui-css#test": {
"dependsOn": ["build"]
},
"a11y#test": {
"dependsOn": ["^build"]
},
"lint": {
"outputs": []
},
Expand Down
Loading

0 comments on commit d1dc494

Please sign in to comment.