Skip to content

Commit

Permalink
Add acceptance test accessibility auditing and fixes (#8455)
Browse files Browse the repository at this point in the history
This introduces ember-a11y-testing to acceptance tests via a helper
wrapper that allows us to globally ignore rules that we can address
separately. It also adds fixes for the aXe rules that were failing.
  • Loading branch information
backspace committed Jul 28, 2020
1 parent a326bd7 commit 9d190a6
Show file tree
Hide file tree
Showing 45 changed files with 341 additions and 72 deletions.
4 changes: 0 additions & 4 deletions ui/app/components/stepper-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,6 @@ export default class StepperInput extends Component {
e.target.select();
}

@action focusInput() {
this.element.querySelector('.stepper-input-input').focus();
}

update(value) {
debounce(this, sendUpdateAction, value, this.debounce);
}
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/agent-monitor.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
@onChange={{action this.setLevel}} as |level|>
<span class="ember-power-select-prefix">Level: </span>{{capitalize level}}
</PowerSelect>
<button data-test-toggle class="button is-white is-compact pull-right" {{action this.toggleStream}} type="button">
<button data-test-toggle class="button is-white is-compact pull-right" {{action this.toggleStream}} type="button" title="{{if this.logger.isStreaming "Stop" "Start"}} log streaming">
{{x-icon (if this.logger.isStreaming "media-pause" "media-play") class="is-text"}}
</button>
</div>
Expand Down
1 change: 1 addition & 0 deletions ui/app/templates/components/copy-button.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
@clipboardText={{this.clipboardText}}
@success={{perform this.indicateSuccess}}
@error={{action (mut this.state) "error"}}
@title="Copy"
>
{{x-icon 'copy-action'}}
</AddonCopyButton>
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/gauge-chart.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<svg data-test-gauge-svg role="img" height={{this.height}}>
<svg data-test-gauge-svg role="img" height={{this.height}} title="gauge chart">
<defs>
<linearGradient x1="0" x2="1" y1="0" y2="0" class="{{this.chartClass}}" id="{{this.fillId}}">
<stop class="start" offset="0%" />
Expand Down
6 changes: 3 additions & 3 deletions ui/app/templates/components/global-header.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<nav class="navbar is-primary">
<nav class="navbar is-primary" title="navigation">
<div class="navbar-brand">
<span data-test-header-gutter-toggle class="gutter-toggle" aria-label="menu" onclick={{action this.onHamburgerClick}}>
<HamburgerMenu />
</span>
<LinkTo @route="jobs" class="navbar-item is-logo">
<LinkTo @route="jobs" class="navbar-item is-logo" aria-label="Home">
<NomadLogo />
</LinkTo>
</div>
Expand All @@ -19,7 +19,7 @@
<div class="navbar-item is-gutter">
<RegionSwitcher @decoration="is-outlined" />
</div>
<nav class="breadcrumb is-large">
<nav class="breadcrumb is-large" title="breadcrumb navigation">
<ul>
{{yield}}
</ul>
Expand Down
2 changes: 2 additions & 0 deletions ui/app/templates/components/job-editor.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,13 @@
<div class="boxed-section-body is-full-bleed">
<IvyCodemirror
data-test-editor
aria-label="Job definition"
@value={{or this.job._newDefinition this.jobSpec}}
@valueUpdated={{action (mut this.job._newDefinition)}}
@options={{hash
mode="javascript"
theme="hashi"
screenReaderLabel="Job definition editor"
tabSize=2
lineNumbers=true
}} />
Expand Down
1 change: 1 addition & 0 deletions ui/app/templates/components/json-viewer.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@options={{hash
mode="javascript"
theme="hashi-read-only"
screenReaderLabel="Job definition"
tabSize=2
lineNumbers=true
readOnly=true
Expand Down
8 changes: 4 additions & 4 deletions ui/app/templates/components/list-pagination.hbs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{{#if this.source.length}}
{{yield (hash
first=(component "list-pagination/list-pager" test="first" page=1 visible=(not (eq this.page 1)))
prev=(component "list-pagination/list-pager" test="prev" page=(dec this.page) visible=(not (eq this.page 1)))
next=(component "list-pagination/list-pager" test="next" page=(inc this.page) visible=(not (eq this.page this.lastPage)))
last=(component "list-pagination/list-pager" test="last" page=this.lastPage visible=(not (eq this.page this.lastPage)))
first=(component "list-pagination/list-pager" test="first" label="First page" page=1 visible=(not (eq this.page 1)))
prev=(component "list-pagination/list-pager" test="prev" label="Previous page" page=(dec this.page) visible=(not (eq this.page 1)))
next=(component "list-pagination/list-pager" test="next" label="Next page" page=(inc this.page) visible=(not (eq this.page this.lastPage)))
last=(component "list-pagination/list-pager" test="last" label="Last page" page=this.lastPage visible=(not (eq this.page this.lastPage)))
pageLinks=this.pageLinks
currentPage=this.page
totalPages=this.lastPage
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/list-pagination/list-pager.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{#if this.visible}}
<LinkTo @query={{hash currentPage=this.page}} class={{this.attrs.class}} data-test-pager={{this.test}}>
<LinkTo @query={{hash currentPage=this.page}} class={{this.attrs.class}} data-test-pager={{this.test}} aria-label={{this.label}}>
{{yield}}
</LinkTo>
{{/if}}
3 changes: 2 additions & 1 deletion ui/app/templates/components/search-box.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
class="input {{this.inputClass}}"
type="text"
placeholder={{this.placeholder}}
aria-label={{this.placeholder}}
value={{this._searchTerm}}
oninput={{action "setSearchTerm"}}
size="1">
<button class="suffix-icon" onclick={{action "clear"}} type="button">{{x-icon "cancel"}}</button>
<button class="suffix-icon" onclick={{action "clear"}} type="button" title="Clear search">{{x-icon "cancel"}}</button>
</div>
5 changes: 3 additions & 2 deletions ui/app/templates/components/stepper-input.hbs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<label
data-test-stepper-label
class="stepper-input-label"
onClick={{action "focusInput"}}>{{yield}}</label>
for="stepper-input-{{this.elementId}}"
class="stepper-input-label">{{yield}}</label>
<input
data-test-stepper-input
type="number"
min={{this.min}}
max={{this.max}}
value={{this.internalValue}}
disabled={{this.disabled}}
id="stepper-input-{{this.elementId}}"
class="stepper-input-input"
onFocus={{action "selectValue"}}
onKeyDown={{action "resetTextInput"}}
Expand Down
2 changes: 1 addition & 1 deletion ui/app/templates/components/task-log.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<span class="pull-right">
<button data-test-log-action="head" class="button is-white" onclick={{action "gotoHead"}} type="button">Head</button>
<button data-test-log-action="tail" class="button is-white" onclick={{action "gotoTail"}} type="button">Tail</button>
<button data-test-log-action="toggle-stream" class="button is-white" onclick={{action "toggleStream"}} type="button">
<button data-test-log-action="toggle-stream" class="button is-white" onclick={{action "toggleStream"}} type="button" title="{{if this.logger.isStreaming "Stop" "Start"}} log streaming">
{{x-icon (if this.logger.isStreaming "media-pause" "media-play") class="is-text"}}
</button>
</span>
Expand Down
4 changes: 3 additions & 1 deletion ui/app/templates/settings/tokens.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@

{{#unless this.tokenIsValid}}
<div class="field">
<label class="label">Secret ID</label>
<label class="label" for="token-input">Secret ID</label>
<div class="control">
<input
id="token-input"
class="input"
type="text"
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
{{!-- FIXME this placeholder gets read out by VoiceOver sans dashes 😵 --}}
value={{this.token.secret}}
oninput={{action (mut this.secret) value="target.value"}}
data-test-token-secret>
Expand Down
4 changes: 4 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
"d3-time-format": "^2.1.0",
"d3-transition": "^1.1.0",
"duration-js": "^4.0.0",
"ember-a11y-testing": "^3.0.2",
"ember-auto-import": "^1.5.3",
"ember-can": "^2.0.0",
"ember-classic-decorator": "^1.0.8",
Expand Down Expand Up @@ -147,5 +148,8 @@
},
"dependencies": {
"lru_map": "^0.3.3"
},
"resolutions": {
"ivy-codemirror/codemirror": "^5.56.0"
}
}
6 changes: 6 additions & 0 deletions ui/tests/acceptance/allocation-detail-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { assign } from '@ember/polyfills';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import Allocation from 'nomad-ui/tests/pages/allocations/detail';
import moment from 'moment';

Expand Down Expand Up @@ -46,6 +47,11 @@ module('Acceptance | allocation detail', function(hooks) {
await Allocation.visit({ id: allocation.id });
});

test('it passes an accessibility audit', async function(assert) {
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('/allocation/:id should name the allocation and link to the corresponding job and node', async function(assert) {
assert.ok(Allocation.title.includes(allocation.name), 'Allocation name is in the heading');
assert.equal(Allocation.details.job, job.name, 'Job name is in the subheading');
Expand Down
9 changes: 9 additions & 0 deletions ui/tests/acceptance/application-errors-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { currentURL, visit } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import ClientsList from 'nomad-ui/tests/pages/clients/list';
import JobsList from 'nomad-ui/tests/pages/jobs/list';
import Job from 'nomad-ui/tests/pages/jobs/detail';
Expand All @@ -16,6 +17,14 @@ module('Acceptance | application errors ', function(hooks) {
server.create('job');
});

test('it passes an accessibility audit', async function(assert) {
server.pretender.get('/v1/nodes', () => [500, {}, null]);
await ClientsList.visit();
await a11yAudit();

assert.ok(true, 'a11y audit passes');
});

test('transitioning away from an error page resets the global error', async function(assert) {
server.pretender.get('/v1/nodes', () => [500, {}, null]);

Expand Down
7 changes: 7 additions & 0 deletions ui/tests/acceptance/behaviors/fs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { currentURL, visit } from '@ember/test-helpers';

import { filesForPath } from 'nomad-ui/mirage/config';
import { formatBytes } from 'nomad-ui/helpers/format-bytes';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';

import Response from 'ember-cli-mirage/response';
import moment from 'moment';
Expand All @@ -24,6 +25,12 @@ const fileSort = (prop, files) => {
};

export default function browseFilesystem({ pageObjectVisitPathFunctionName, pageObjectVisitFunctionName, visitSegments, getExpectedPathBase, getTitleComponent, getBreadcrumbComponent, getFilesystemRoot }) {
test('it passes an accessibility audit', async function(assert) {
await FS[pageObjectVisitFunctionName](visitSegments({allocation: this.allocation, task: this.task }));
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('visiting filesystem root', async function(assert) {
await FS[pageObjectVisitFunctionName](visitSegments({allocation: this.allocation, task: this.task }));

Expand Down
7 changes: 7 additions & 0 deletions ui/tests/acceptance/client-detail-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { assign } from '@ember/polyfills';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import { formatBytes } from 'nomad-ui/helpers/format-bytes';
import moment from 'moment';
import ClientDetail from 'nomad-ui/tests/pages/clients/detail';
Expand Down Expand Up @@ -41,6 +42,12 @@ module('Acceptance | client detail', function(hooks) {
});
});

test('it passes an accessibility audit', async function(assert) {
await ClientDetail.visit({ id: node.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('/clients/:id should have a breadcrumb trail linking back to clients', async function(assert) {
await ClientDetail.visit({ id: node.id });

Expand Down
7 changes: 7 additions & 0 deletions ui/tests/acceptance/client-monitor-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { run } from '@ember/runloop';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import ClientMonitor from 'nomad-ui/tests/pages/clients/monitor';

let node;
Expand All @@ -25,6 +26,12 @@ module('Acceptance | client monitor', function(hooks) {
run.later(run, run.cancelTimers, 500);
});

test('it passes an accessibility audit', async function(assert) {
await ClientMonitor.visit({ id: node.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('/clients/:id/monitor should have a breadcrumb trail linking back to clients', async function(assert) {
await ClientMonitor.visit({ id: node.id });

Expand Down
12 changes: 12 additions & 0 deletions ui/tests/acceptance/clients-list-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { currentURL, settled } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import pageSizeSelect from './behaviors/page-size-select';
import ClientsList from 'nomad-ui/tests/pages/clients/list';

Expand All @@ -13,6 +14,17 @@ module('Acceptance | clients list', function(hooks) {
window.localStorage.clear();
});

test('it passes an accessibility audit', async function(assert) {
const nodesCount = ClientsList.pageSize + 1;

server.createList('node', nodesCount);
server.createList('agent', 1);

await ClientsList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('/clients should list one page of clients', async function(assert) {
// Make sure to make more nodes than 1 page to assert that pagination is working
const nodesCount = ClientsList.pageSize + 1;
Expand Down
7 changes: 7 additions & 0 deletions ui/tests/acceptance/exec-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { module, skip, test } from 'qunit';
import { currentURL, settled } from '@ember/test-helpers';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import Service from '@ember/service';
import Exec from 'nomad-ui/tests/pages/exec';
import KEYS from 'nomad-ui/utils/keys';
Expand Down Expand Up @@ -33,6 +34,12 @@ module('Acceptance | exec', function(hooks) {
});
});

test('it passes an accessibility audit', async function(assert) {
await Exec.visitJob({ job: this.job.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('/exec/:job should show the region, namespace, and job name', async function(assert) {
server.create('namespace');
let namespace = server.create('namespace');
Expand Down
10 changes: 10 additions & 0 deletions ui/tests/acceptance/job-allocations-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { currentURL } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import Allocations from 'nomad-ui/tests/pages/jobs/job/allocations';

let job;
Expand All @@ -28,6 +29,15 @@ module('Acceptance | job allocations', function(hooks) {
job = server.create('job', { noFailedPlacements: true, createAllocations: false });
});

test('it passes an accessibility audit', async function(assert) {
server.createList('allocation', Allocations.pageSize - 1, { shallow: true });
allocations = server.schema.allocations.where({ jobId: job.id }).models;

await Allocations.visit({ id: job.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('lists all allocations for the job', async function(assert) {
server.createList('allocation', Allocations.pageSize - 1, { shallow: true });
allocations = server.schema.allocations.where({ jobId: job.id }).models;
Expand Down
6 changes: 6 additions & 0 deletions ui/tests/acceptance/job-definition-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { currentURL } from '@ember/test-helpers';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import setupCodeMirror from 'nomad-ui/tests/helpers/codemirror';
import Definition from 'nomad-ui/tests/pages/jobs/job/definition';

Expand All @@ -19,6 +20,11 @@ module('Acceptance | job definition', function(hooks) {
await Definition.visit({ id: job.id });
});

test('it passes an accessibility audit', async function(assert) {
await a11yAudit('scrollable-region-focusable');
assert.ok(true, 'a11y audit passes');
});

test('visiting /jobs/:job_id/definition', async function(assert) {
assert.equal(currentURL(), `/jobs/${job.id}/definition`);
assert.equal(document.title, `Job ${job.name} definition - Nomad`);
Expand Down
7 changes: 7 additions & 0 deletions ui/tests/acceptance/job-deployments-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { get } from '@ember/object';
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import moment from 'moment';
import Deployments from 'nomad-ui/tests/pages/jobs/job/deployments';

Expand Down Expand Up @@ -33,6 +34,12 @@ module('Acceptance | job deployments', function(hooks) {
});
});

test('it passes an accessibility audit', async function(assert) {
await Deployments.visit({ id: job.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});

test('/jobs/:id/deployments should list all job deployments', async function(assert) {
await Deployments.visit({ id: job.id });

Expand Down
Loading

0 comments on commit 9d190a6

Please sign in to comment.