Skip to content

Commit

Permalink
Merge pull request openshift#6398 from dtaylor113/cypress-axe-plugin
Browse files Browse the repository at this point in the history
Bug 1871260: Implemented Axe A11y testing into Cypress
  • Loading branch information
openshift-merge-robot authored Aug 22, 2020
2 parents 14250fb + e5f3620 commit 336208a
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 9 deletions.
2 changes: 2 additions & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@
"@graphql-codegen/typescript-operations": "^1.15.1",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.1",
"@types/classnames": "^2.2.7",
"@types/cypress-axe": "^0.8.0",
"@types/enzyme": "3.10.x",
"@types/glob": "7.x",
"@types/immutable": "3.x",
Expand Down Expand Up @@ -202,6 +203,7 @@
"circular-dependency-plugin": "5.x",
"css-loader": "0.28.x",
"cypress": "^5.0.0",
"cypress-axe": "^0.8.1",
"cypress-jest-adapter": "^0.1.1",
"cypress-multi-reporters": "^1.4.0",
"enzyme": "3.10.x",
Expand Down
7 changes: 6 additions & 1 deletion frontend/packages/integration-tests-cypress/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,10 @@
"../.eslintrc",
"plugin:cypress/recommended"
],
"plugins": ["cypress"]
"plugins": ["cypress"],
"rules": {
"no-console": "off",
"no-namespace" : "off",
"no-redeclare": "off"
}
}
6 changes: 4 additions & 2 deletions frontend/packages/integration-tests-cypress/plugins/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ module.exports = (on, config) => {
// `on` is used to hook into various events Cypress emits
on('task', {
log(message) {
// eslint-disable-next-line no-console
console.log(message);
return null;
},
logError(message) {
// eslint-disable-next-line no-console
console.error(message);
return null;
},
logTable(data) {
console.table(data);
return null;
},
});
on('file:preprocessor', wp(options));
/* In a Docker container, the default size of the /dev/shm shared memory space is 64MB. This is not typically enough
Expand Down
47 changes: 47 additions & 0 deletions frontend/packages/integration-tests-cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,58 @@ import './selectors';
import './nav';
import './resources';
import 'cypress-jest-adapter';
import 'cypress-axe';
import { Result } from 'axe-core';

declare global {
namespace Cypress {
interface Chainable<Subject> {
logA11yViolations(violations: Result[], target: string): Chainable<Element>;
testA11y(target: string): Chainable<Element>;
}
}
}

Cypress.Cookies.defaults({
preserve: ['openshift-session-token', 'csrf-token'],
});

Cypress.Commands.add('logA11yViolations', (violations: Result[], target: string) => {
// pluck specific keys to keep the table readable
const violationData = violations.map(({ id, impact, description, nodes }) => ({
id,
impact,
description,
nodes: nodes.length,
}));
cy.task(
'log',
`${violations.length} accessibility violation${violations.length === 1 ? '' : 's'} ${
violations.length === 1 ? 'was' : 'were'
} detected ${target ? `for ${target}` : ''}`,
);
cy.task('logTable', violationData);
});

Cypress.Commands.add('testA11y', (target: string) => {
cy.injectAxe();
cy.configureAxe({
rules: [
{ id: 'color-contrast', enabled: false }, // seem to be somewhat inaccurate and has difficulty always picking up the correct colors, tons of open issues for it on axe-core
{ id: 'focusable-content', enabled: false }, // recently updated and need to give the PF team time to fix issues before enabling
{ id: 'scrollable-region-focusable', enabled: false }, // recently updated and need to give the PF team time to fix issues before enabling
],
});
cy.checkA11y(
null,
{
includedImpacts: ['serious', 'critical'],
},
(violations) => cy.logA11yViolations(violations, target),
true,
);
});

export const checkErrors = () =>
cy.window().then((win) => {
if (win.windowError) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { submitButton } from '../views/form';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace,no-redeclare
namespace Cypress {
interface Chainable<Subject> {
login(providerName?: string, username?: string, password?: string): Chainable<Element>;
Expand Down
1 change: 0 additions & 1 deletion frontend/packages/integration-tests-cypress/support/nav.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export {}; // needed in files which don't have an import to trigger ES6 module usage
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace,no-redeclare
namespace Cypress {
interface Chainable<Subject> {
clickNavLink(path: [string, string]): Chainable<Element>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { listPage } from '../views/list-page';
import { modal } from '../views/modal';

declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace,no-redeclare
namespace Cypress {
interface Chainable<Subject> {
createProject(name: string): Chainable<Element>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { K8sResourceKindReference } from '@console/internal/module/k8s';

export {};
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace,no-redeclare
namespace Cypress {
interface Chainable<Subject> {
resourceShouldBeDeleted(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
export {};
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace,no-redeclare
namespace Cypress {
interface Chainable<Subject> {
byTestID(selector: string): Chainable<Element>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe('Kubernetes resource CRUD operations', () => {
// sidebar needs to be fully loaded, else it sometimes overlays the Create button
cy.byTestID('resource-sidebar').should('exist');
yamlEditor.isLoaded();
cy.testA11y(`YAML Editor for ${kind}: ${name}`);
let newContent;
// get, update, and set yaml editor content.
return yamlEditor.getEditorContent().then((content) => {
Expand Down Expand Up @@ -123,6 +124,7 @@ describe('Kubernetes resource CRUD operations', () => {
it('displays detail view for newly created resource instance', () => {
cy.url().should('include', `/${name}`);
detailsPage.titleShouldContain(name);
cy.testA11y(`Details page for ${kind}: ${name}`);
});

it(`displays a list view for the resource`, () => {
Expand All @@ -137,6 +139,8 @@ describe('Kubernetes resource CRUD operations', () => {
cy.log('does not have a namespace dropdown on non-namespaced objects');
listPage.projectDropdownShouldNotExist();
}
listPage.rows.shouldBeLoaded();
cy.testA11y(`List page for ${kind}: ${name}`);
});

it('search view displays created resource instance', () => {
Expand All @@ -149,6 +153,7 @@ describe('Kubernetes resource CRUD operations', () => {
// filter should have 3 chip groups: resource, label, and name
listPage.filter.numberOfActiveFiltersShouldBe(3);
listPage.rows.shouldExist(name);
cy.testA11y(`Search page for ${kind}: ${name}`);

cy.log('link to to details page');
listPage.rows.clickRowByName(name);
Expand Down
2 changes: 1 addition & 1 deletion frontend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"experimentalDecorators": true,
"sourceMap": true,
"noUnusedLocals": true,
"types": ["jest", "cypress"],
"types": ["jest", "cypress", "cypress-axe"],
"paths": {
"protractor": ["integration-tests/protractor.d.ts"]
},
Expand Down
17 changes: 17 additions & 0 deletions frontend/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2187,6 +2187,13 @@
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==

"@types/cypress-axe@^0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@types/cypress-axe/-/cypress-axe-0.8.0.tgz#c22f5cb197080378fd65082255a613fa2e8e1afa"
integrity sha512-4sTqNsXUXnl/CqmSI+xCCmYwml+/zZ66uBExMLqnF1dn3wd+BIyrLL8fJ81O/AJePuh08igR2VjZqWuZaoqWaw==
dependencies:
axe-core "^3.4.1"

"@types/d3-array@*":
version "1.2.2"
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.2.tgz#29edf3e2001e5f4e33e899fcda52ee2387401792"
Expand Down Expand Up @@ -3736,6 +3743,11 @@ aws4@^1.6.0, aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==

axe-core@^3.4.1:
version "3.5.5"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.5.5.tgz#84315073b53fa3c0c51676c588d59da09a192227"
integrity sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==

axios@^0.19.2:
version "0.19.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.2.tgz#3ea36c5d8818d0d5f8a8a97a6d36b86cdc00cb27"
Expand Down Expand Up @@ -5535,6 +5547,11 @@ cyclist@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640"

cypress-axe@^0.8.1:
version "0.8.1"
resolved "https://registry.yarnpkg.com/cypress-axe/-/cypress-axe-0.8.1.tgz#ddb37dca6570c0642dda2388daf678e83b3e8d3f"
integrity sha512-hX48+r5n7Ns7CHkn601Ag0JiCG1vby5+g7QhlP8X+mkiVYpTLpXAPiiaKFj9QTTCdZSI5+0UqwIxA+ShTsr5tA==

cypress-jest-adapter@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/cypress-jest-adapter/-/cypress-jest-adapter-0.1.1.tgz#d1aa9d84393b6a5007022d1d33b3cdd3ce9672af"
Expand Down

0 comments on commit 336208a

Please sign in to comment.