Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI: Add acceptance test accessibility auditing and fixes #8455

Merged
merged 10 commits into from
Jul 28, 2020
Merged
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
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>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a much nicer implementation than the action route I took.

<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