Add acceptance test accessibility auditing and fixes (#8455)

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.
This commit is contained in:
Buck Doyle
2020-07-28 12:59:14 -05:00
committed by GitHub
parent a326bd7eb5
commit 9d190a643e
45 changed files with 341 additions and 72 deletions

View File

@@ -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);
}

View File

@@ -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>

View File

@@ -16,6 +16,7 @@
@clipboardText={{this.clipboardText}}
@success={{perform this.indicateSuccess}}
@error={{action (mut this.state) "error"}}
@title="Copy"
>
{{x-icon 'copy-action'}}
</AddonCopyButton>

View File

@@ -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%" />

Before

Width:  |  Height:  |  Size: 830 B

After

Width:  |  Height:  |  Size: 850 B

View File

@@ -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>
@@ -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>

View File

@@ -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
}} />

View File

@@ -3,6 +3,7 @@
@options={{hash
mode="javascript"
theme="hashi-read-only"
screenReaderLabel="Job definition"
tabSize=2
lineNumbers=true
readOnly=true

View File

@@ -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

View File

@@ -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}}

View File

@@ -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>

View File

@@ -1,7 +1,7 @@
<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"
@@ -9,6 +9,7 @@
max={{this.max}}
value={{this.internalValue}}
disabled={{this.disabled}}
id="stepper-input-{{this.elementId}}"
class="stepper-input-input"
onFocus={{action "selectValue"}}
onKeyDown={{action "resetTextInput"}}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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",
@@ -147,5 +148,8 @@
},
"dependencies": {
"lru_map": "^0.3.3"
},
"resolutions": {
"ivy-codemirror/codemirror": "^5.56.0"
}
}

View File

@@ -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';
@@ -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');

View File

@@ -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';
@@ -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]);

View File

@@ -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';
@@ -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 }));

View File

@@ -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';
@@ -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 });

View File

@@ -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;
@@ -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 });

View File

@@ -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';
@@ -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;

View File

@@ -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';
@@ -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');

View File

@@ -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;
@@ -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;

View File

@@ -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';
@@ -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`);

View File

@@ -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';
@@ -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 });

View File

@@ -3,6 +3,7 @@ import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { selectChoose } from 'ember-power-select/test-support';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import moduleForJob from 'nomad-ui/tests/helpers/module-for-job';
import JobDetail from 'nomad-ui/tests/pages/jobs/detail';
import JobsList from 'nomad-ui/tests/pages/jobs/list';
@@ -76,6 +77,13 @@ module('Acceptance | job detail (with namespaces)', function(hooks) {
clientToken = server.create('token');
});
test('it passes an accessibility audit', async function(assert) {
const namespace = server.db.namespaces.find(job.namespaceId);
await JobDetail.visit({ id: job.id, namespace: namespace.name });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('when there are namespaces, the job detail page states the namespace for the job', async function(assert) {
const namespace = server.db.namespaces.find(job.namespaceId);
await JobDetail.visit({ id: job.id, namespace: namespace.name });

View File

@@ -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 Evaluations from 'nomad-ui/tests/pages/jobs/job/evaluations';
let job;
@@ -18,6 +19,11 @@ module('Acceptance | job evaluations', function(hooks) {
await Evaluations.visit({ id: job.id });
});
test('it passes an accessibility audit', async function(assert) {
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('lists all evaluations for the job', async function(assert) {
assert.equal(Evaluations.evaluations.length, evaluations.length, 'All evaluations are listed');

View File

@@ -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 setupCodeMirror from 'nomad-ui/tests/helpers/codemirror';
import JobRun from 'nomad-ui/tests/pages/jobs/run';
@@ -54,6 +55,12 @@ module('Acceptance | job run', function(hooks) {
window.localStorage.nomadTokenSecret = managementToken.secretId;
});
test('it passes an accessibility audit', async function(assert) {
await JobRun.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('visiting /jobs/run', async function(assert) {
await JobRun.visit();

View File

@@ -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 Versions from 'nomad-ui/tests/pages/jobs/job/versions';
import moment from 'moment';
@@ -19,6 +20,11 @@ module('Acceptance | job versions', function(hooks) {
await Versions.visit({ id: job.id });
});
test('it passes an accessibility audit', async function(assert) {
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/jobs/:id/versions should list all job versions', async function(assert) {
assert.ok(Versions.versions.length, versions.length, 'Each version gets a row in the timeline');
assert.equal(document.title, `Job ${job.name} versions - Nomad`);

View File

@@ -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 pageSizeSelect from './behaviors/page-size-select';
import JobsList from 'nomad-ui/tests/pages/jobs/list';
import Layout from 'nomad-ui/tests/pages/layout';
@@ -23,6 +24,12 @@ module('Acceptance | jobs list', function(hooks) {
window.localStorage.nomadTokenSecret = managementToken.secretId;
});
test('it passes an accessibility audit', async function(assert) {
await JobsList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('visiting /jobs', async function(assert) {
await JobsList.visit();

View File

@@ -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 { selectChoose } from 'ember-power-select/test-support';
import JobsList from 'nomad-ui/tests/pages/jobs/list';
import ClientsList from 'nomad-ui/tests/pages/clients/list';
@@ -47,6 +48,12 @@ module('Acceptance | namespaces (enabled)', function(hooks) {
window.localStorage.clear();
});
test('it passes an accessibility audit', async function(assert) {
await JobsList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('the namespace switcher lists all namespaces', async function(assert) {
const namespaces = server.db.namespaces;

View File

@@ -2,6 +2,7 @@ import { module, test } from 'qunit';
import { currentURL } 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 pageSizeSelect from './behaviors/page-size-select';
import PluginAllocations from 'nomad-ui/tests/pages/storage/plugins/plugin/allocations';
@@ -16,6 +17,19 @@ module('Acceptance | plugin allocations', function(hooks) {
window.localStorage.clear();
});
test('it passes an accessibility audit', async function(assert) {
plugin = server.create('csi-plugin', {
shallow: true,
controllerRequired: true,
controllersExpected: 3,
nodesExpected: 3,
});
await PluginAllocations.visit({ id: plugin.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/csi/plugins/:id/allocations shows all allocations in a single table', async function(assert) {
plugin = server.create('csi-plugin', {
shallow: true,

View File

@@ -2,6 +2,7 @@ import { module, test } from 'qunit';
import { currentURL } 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 moment from 'moment';
import { formatBytes } from 'nomad-ui/helpers/format-bytes';
import PluginDetail from 'nomad-ui/tests/pages/storage/plugins/detail';
@@ -17,6 +18,12 @@ module('Acceptance | plugin detail', function(hooks) {
plugin = server.create('csi-plugin', { controllerRequired: true });
});
test('it passes an accessibility audit', async function(assert) {
await PluginDetail.visit({ id: plugin.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/csi/plugins/:id should have a breadcrumb trail linking back to Plugins and Storage', async function(assert) {
await PluginDetail.visit({ id: plugin.id });

View File

@@ -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 pageSizeSelect from './behaviors/page-size-select';
import PluginsList from 'nomad-ui/tests/pages/storage/plugins/list';
@@ -14,6 +15,12 @@ module('Acceptance | plugins list', function(hooks) {
window.localStorage.clear();
});
test('it passes an accessibility audit', async function(assert) {
await PluginsList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('visiting /csi/plugins', async function(assert) {
await PluginsList.visit();

View File

@@ -3,6 +3,7 @@ import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { selectChoose } from 'ember-power-select/test-support';
import { setupMirage } from 'ember-cli-mirage/test-support';
import a11yAudit from 'nomad-ui/tests/helpers/a11y-audit';
import JobsList from 'nomad-ui/tests/pages/jobs/list';
import ClientsList from 'nomad-ui/tests/pages/clients/list';
import PageLayout from 'nomad-ui/tests/pages/layout';
@@ -18,6 +19,12 @@ module('Acceptance | regions (only one)', function(hooks) {
server.createList('job', 2, { createAllocations: false, noDeployments: true });
});
test('it passes an accessibility audit', async function(assert) {
await JobsList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('when there is only one region, the region switcher is not shown in the nav bar and the region is not in the page title', async function(assert) {
server.create('region', { id: 'global' });

View File

@@ -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 ServerDetail from 'nomad-ui/tests/pages/servers/detail';
let agent;
@@ -16,6 +17,11 @@ module('Acceptance | server detail', function(hooks) {
await ServerDetail.visit({ name: agent.name });
});
test('it passes an accessibility audit', async function(assert) {
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('visiting /servers/:server_name', async function(assert) {
assert.equal(currentURL(), `/servers/${encodeURIComponent(agent.name)}`);
assert.equal(document.title, `Server ${agent.name} - Nomad`);

View File

@@ -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 ServerMonitor from 'nomad-ui/tests/pages/servers/monitor';
let agent;
@@ -24,6 +25,12 @@ module('Acceptance | server monitor', function(hooks) {
run.later(run, run.cancelTimers, 500);
});
test('it passes an accessibility audit', async function(assert) {
await ServerMonitor.visit({ name: agent.name });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/servers/:id/monitor should have a breadcrumb trail linking back to servers', async function(assert) {
await ServerMonitor.visit({ name: agent.name });

View File

@@ -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 { findLeader } from '../../mirage/config';
import ServersList from 'nomad-ui/tests/pages/servers/list';
@@ -23,6 +24,13 @@ module('Acceptance | servers list', function(hooks) {
setupApplicationTest(hooks);
setupMirage(hooks);
test('it passes an accessibility audit', async function(assert) {
minimumSetup();
await ServersList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/servers should list all servers', async function(assert) {
server.createList('node', 1);
server.createList('agent', 10);

View File

@@ -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 Task from 'nomad-ui/tests/pages/allocations/task/detail';
import moment from 'moment';
@@ -22,6 +23,11 @@ module('Acceptance | task detail', function(hooks) {
await Task.visit({ id: allocation.id, name: task.name });
});
test('it passes an accessibility audit', async function(assert) {
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/allocation/:id/:task_name should name the task and list high-level task information', async function(assert) {
assert.ok(Task.title.text.includes(task.name), 'Task name');
assert.ok(Task.state.includes(task.state), 'Task state');

View File

@@ -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 { formatBytes } from 'nomad-ui/helpers/format-bytes';
import TaskGroup from 'nomad-ui/tests/pages/jobs/job/task-group';
import pageSizeSelect from './behaviors/page-size-select';
@@ -67,6 +68,12 @@ module('Acceptance | task group detail', function(hooks) {
window.localStorage.clear();
});
test('it passes an accessibility audit', async function(assert) {
await TaskGroup.visit({ id: job.id, name: taskGroup.name });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/jobs/:id/:task-group should list high-level metrics for the allocation', async function(assert) {
const totalCPU = tasks.mapBy('Resources.CPU').reduce(sum, 0);
const totalMemory = tasks.mapBy('Resources.MemoryMB').reduce(sum, 0);

View File

@@ -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 TaskLogs from 'nomad-ui/tests/pages/allocations/task/logs';
let allocation;
@@ -24,6 +25,11 @@ module('Acceptance | task logs', function(hooks) {
await TaskLogs.visit({ id: allocation.id, name: task.name });
});
test('it passes an accessibility audit', async function(assert) {
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/allocation/:id/:task_name/logs should have a log component', async function(assert) {
assert.equal(currentURL(), `/allocations/${allocation.id}/${task.name}/logs`, 'No redirect');
assert.ok(TaskLogs.hasTaskLog, 'Task log component found');

View File

@@ -2,6 +2,7 @@ import { find } from '@ember/test-helpers';
import { module, skip, 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 Tokens from 'nomad-ui/tests/pages/settings/tokens';
import Jobs from 'nomad-ui/tests/pages/jobs/list';
import JobDetail from 'nomad-ui/tests/pages/jobs/detail';
@@ -27,6 +28,12 @@ module('Acceptance | tokens', function(hooks) {
clientToken = server.create('token');
});
test('it passes an accessibility audit', async function(assert) {
await Tokens.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('the token form sets the token in local storage', async function(assert) {
const { secretId } = managementToken;

View File

@@ -2,6 +2,7 @@ import { module, test } from 'qunit';
import { currentURL } 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 moment from 'moment';
import { formatBytes } from 'nomad-ui/helpers/format-bytes';
import VolumeDetail from 'nomad-ui/tests/pages/storage/volumes/detail';
@@ -28,6 +29,12 @@ module('Acceptance | volume detail', function(hooks) {
volume = server.create('csi-volume');
});
test('it passes an accessibility audit', async function(assert) {
await VolumeDetail.visit({ id: volume.id });
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('/csi/volumes/:id should have a breadcrumb trail linking back to Volumes and Storage', async function(assert) {
await VolumeDetail.visit({ id: volume.id });

View File

@@ -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 pageSizeSelect from './behaviors/page-size-select';
import VolumesList from 'nomad-ui/tests/pages/storage/volumes/list';
import Layout from 'nomad-ui/tests/pages/layout';
@@ -26,6 +27,12 @@ module('Acceptance | volumes list', function(hooks) {
window.localStorage.clear();
});
test('it passes an accessibility audit', async function(assert) {
await VolumesList.visit();
await a11yAudit();
assert.ok(true, 'a11y audit passes');
});
test('visiting /csi redirects to /csi/volumes', async function(assert) {
await visit('/csi');

View File

@@ -0,0 +1,16 @@
import a11yAudit from 'ember-a11y-testing/test-support/audit';
export default async function defaultA11yAudit(...overriddenRules) {
const rules = {
'color-contrast': {
enabled: false
},
'heading-order': {
enabled: false
}
};
overriddenRules.forEach(rule => rules[rule] = { enabled: false });
await a11yAudit({rules});
}

View File

@@ -4296,6 +4296,11 @@ aws4@^1.8.0:
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
axe-core@3.5.5:
version "3.5.5"
resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-3.5.5.tgz#84315073b53fa3c0c51676c588d59da09a192227"
integrity sha512-5P0QZ6J5xGikH780pghEdbEKijCTrruK9KxtPZCFWUpef0f6GipO+xEZ5GKCb020mmqgbiNO6TcA55CriL784Q==
babel-code-frame@^6.22.0, babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@@ -5690,6 +5695,22 @@ broccoli-funnel@2.0.1:
symlink-or-copy "^1.0.0"
walk-sync "^0.3.1"
broccoli-funnel@3.0.3, broccoli-funnel@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-3.0.3.tgz#26fd42632471f67a91f4770d1987118087219937"
integrity sha512-LPzZ91BwStoHZXdXHQAJeYORl189OrRKM5NdIi86SDU9wZ4s/3lV1PRFOiobDT/jKM10voM7CDzfvicHbCYxAQ==
dependencies:
array-equal "^1.0.0"
blank-object "^1.0.1"
broccoli-plugin "^4.0.1"
debug "^4.1.1"
fast-ordered-set "^1.0.0"
fs-tree-diff "^2.0.1"
heimdalljs "^0.2.0"
minimatch "^3.0.0"
path-posix "^1.0.0"
walk-sync "^2.0.2"
broccoli-funnel@^1.0.1, broccoli-funnel@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-1.2.0.tgz#cddc3afc5ff1685a8023488fff74ce6fb5a51296"
@@ -5729,22 +5750,6 @@ broccoli-funnel@^2.0.0, broccoli-funnel@^2.0.1, broccoli-funnel@^2.0.2:
symlink-or-copy "^1.0.0"
walk-sync "^0.3.1"
broccoli-funnel@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/broccoli-funnel/-/broccoli-funnel-3.0.3.tgz#26fd42632471f67a91f4770d1987118087219937"
integrity sha512-LPzZ91BwStoHZXdXHQAJeYORl189OrRKM5NdIi86SDU9wZ4s/3lV1PRFOiobDT/jKM10voM7CDzfvicHbCYxAQ==
dependencies:
array-equal "^1.0.0"
blank-object "^1.0.1"
broccoli-plugin "^4.0.1"
debug "^4.1.1"
fast-ordered-set "^1.0.0"
fs-tree-diff "^2.0.1"
heimdalljs "^0.2.0"
minimatch "^3.0.0"
path-posix "^1.0.0"
walk-sync "^2.0.2"
broccoli-kitchen-sink-helpers@^0.2.5:
version "0.2.9"
resolved "https://registry.yarnpkg.com/broccoli-kitchen-sink-helpers/-/broccoli-kitchen-sink-helpers-0.2.9.tgz#a5e0986ed8d76fb5984b68c3f0450d3a96e36ecc"
@@ -6846,10 +6851,10 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.47.0:
version "5.49.2"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.49.2.tgz#c84fdaf11b19803f828b0c67060c7bc6d154ccad"
integrity sha512-dwJ2HRPHm8w51WB5YTF9J7m6Z5dtkqbU9ntMZ1dqXyFB9IpjoUFDj80ahRVEoVanfIp6pfASJbOlbWdEf8FOzQ==
codemirror@^5.47.0, codemirror@^5.56.0:
version "5.56.0"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.56.0.tgz#675640fcc780105cd22d3faa738b5d7ea6426f61"
integrity sha512-MfKVmYgifXjQpLSgpETuih7A7WTTIsxvKfSLGseTY5+qt0E1UD1wblZGM6WLenORo8sgmf+3X+WTe2WF7mufyw==
collection-visit@^1.0.0:
version "1.0.0"
@@ -8029,6 +8034,17 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0"
ember-a11y-testing@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/ember-a11y-testing/-/ember-a11y-testing-3.0.2.tgz#8819941bf7cd1b31c1463d95de19e8c4927b1111"
integrity sha512-9FYh3S07C10c4oub6ziSXHcLHAT3RxFPrn7DV39TRtbz+H3ZAD84dRrIvQrR8wORi3Ti51OmygSmfH2G7CqwvA==
dependencies:
axe-core "3.5.5"
broccoli-funnel "3.0.3"
ember-cli-babel "7.21.0"
ember-cli-version-checker "5.1.1"
ember-get-config "0.2.4"
ember-assign-polyfill@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/ember-assign-polyfill/-/ember-assign-polyfill-2.6.0.tgz#07847e3357ee35b33f886a0b5fbec6873f6860eb"
@@ -8151,6 +8167,38 @@ ember-cli-babel-plugin-helpers@^1.0.0, ember-cli-babel-plugin-helpers@^1.1.0:
resolved "https://registry.yarnpkg.com/ember-cli-babel-plugin-helpers/-/ember-cli-babel-plugin-helpers-1.1.0.tgz#de3baedd093163b6c2461f95964888c1676325ac"
integrity sha512-Zr4my8Xn+CzO0gIuFNXji0eTRml5AxZUTDQz/wsNJ5AJAtyFWCY4QtKdoELNNbiCVGt1lq5yLiwTm4scGKu6xA==
ember-cli-babel@7.21.0, ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.17.2, ember-cli-babel@^7.18.0:
version "7.21.0"
resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.21.0.tgz#c79e888876aee87dfc3260aee7cb580b74264bbc"
integrity sha512-jHVi9melAibo0DrAG3GAxid+29xEyjBoU53652B4qcu3Xp58feZGTH/JGXovH7TjvbeNn65zgNyoV3bk1onULw==
dependencies:
"@babel/core" "^7.10.2"
"@babel/helper-compilation-targets" "^7.10.2"
"@babel/plugin-proposal-class-properties" "^7.10.1"
"@babel/plugin-proposal-decorators" "^7.10.1"
"@babel/plugin-transform-modules-amd" "^7.10.1"
"@babel/plugin-transform-runtime" "^7.10.1"
"@babel/plugin-transform-typescript" "^7.10.1"
"@babel/polyfill" "^7.10.1"
"@babel/preset-env" "^7.10.2"
"@babel/runtime" "^7.10.2"
amd-name-resolver "^1.2.1"
babel-plugin-debug-macros "^0.3.3"
babel-plugin-ember-data-packages-polyfill "^0.1.2"
babel-plugin-ember-modules-api-polyfill "^2.13.4"
babel-plugin-module-resolver "^3.1.1"
broccoli-babel-transpiler "^7.5.0"
broccoli-debug "^0.6.4"
broccoli-funnel "^2.0.1"
broccoli-source "^1.1.0"
clone "^2.1.2"
ember-cli-babel-plugin-helpers "^1.1.0"
ember-cli-version-checker "^4.1.0"
ensure-posix-path "^1.0.2"
fixturify-project "^1.10.0"
rimraf "^3.0.1"
semver "^5.5.0"
ember-cli-babel@7.8.0, ember-cli-babel@^7.1.0, ember-cli-babel@^7.7.3:
version "7.8.0"
resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.8.0.tgz#e596500eca0f5a7c9aaee755f803d1542f578acf"
@@ -8283,38 +8331,6 @@ ember-cli-babel@^7.11.1:
rimraf "^3.0.1"
semver "^5.5.0"
ember-cli-babel@^7.12.0, ember-cli-babel@^7.13.2, ember-cli-babel@^7.17.2, ember-cli-babel@^7.18.0:
version "7.21.0"
resolved "https://registry.yarnpkg.com/ember-cli-babel/-/ember-cli-babel-7.21.0.tgz#c79e888876aee87dfc3260aee7cb580b74264bbc"
integrity sha512-jHVi9melAibo0DrAG3GAxid+29xEyjBoU53652B4qcu3Xp58feZGTH/JGXovH7TjvbeNn65zgNyoV3bk1onULw==
dependencies:
"@babel/core" "^7.10.2"
"@babel/helper-compilation-targets" "^7.10.2"
"@babel/plugin-proposal-class-properties" "^7.10.1"
"@babel/plugin-proposal-decorators" "^7.10.1"
"@babel/plugin-transform-modules-amd" "^7.10.1"
"@babel/plugin-transform-runtime" "^7.10.1"
"@babel/plugin-transform-typescript" "^7.10.1"
"@babel/polyfill" "^7.10.1"
"@babel/preset-env" "^7.10.2"
"@babel/runtime" "^7.10.2"
amd-name-resolver "^1.2.1"
babel-plugin-debug-macros "^0.3.3"
babel-plugin-ember-data-packages-polyfill "^0.1.2"
babel-plugin-ember-modules-api-polyfill "^2.13.4"
babel-plugin-module-resolver "^3.1.1"
broccoli-babel-transpiler "^7.5.0"
broccoli-debug "^0.6.4"
broccoli-funnel "^2.0.1"
broccoli-source "^1.1.0"
clone "^2.1.2"
ember-cli-babel-plugin-helpers "^1.1.0"
ember-cli-version-checker "^4.1.0"
ensure-posix-path "^1.0.2"
fixturify-project "^1.10.0"
rimraf "^3.0.1"
semver "^5.5.0"
ember-cli-clipboard@^0.13.0:
version "0.13.0"
resolved "https://registry.yarnpkg.com/ember-cli-clipboard/-/ember-cli-clipboard-0.13.0.tgz#47d3de3aec09987409c162cbff36f966a2c138b7"
@@ -8639,6 +8655,15 @@ ember-cli-uglify@^3.0.0:
broccoli-uglify-sourcemap "^3.1.0"
lodash.defaultsdeep "^4.6.0"
ember-cli-version-checker@5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-5.1.1.tgz#3185c526c14671609cbd22ab0d0925787fc84f3d"
integrity sha512-YziSW1MgOuVdJSyUY2CKSC4vXrGQIHF6FgygHkJOxYGjZNQYwf5MK0sbliKatvJf7kzDSnXs+r8JLrD74W/A8A==
dependencies:
resolve-package-path "^2.0.0"
semver "^7.3.2"
silent-error "^1.1.1"
ember-cli-version-checker@^2.0.0, ember-cli-version-checker@^2.1.0, ember-cli-version-checker@^2.1.1, ember-cli-version-checker@^2.1.2:
version "2.2.0"
resolved "https://registry.yarnpkg.com/ember-cli-version-checker/-/ember-cli-version-checker-2.2.0.tgz#47771b731fe0962705e27c8199a9e3825709f3b3"
@@ -8887,7 +8912,7 @@ ember-fetch@^7.0.0:
node-fetch "^2.6.0"
whatwg-fetch "^3.0.0"
ember-get-config@^0.2.2:
ember-get-config@0.2.4, ember-get-config@^0.2.2:
version "0.2.4"
resolved "https://registry.yarnpkg.com/ember-get-config/-/ember-get-config-0.2.4.tgz#118492a2a03d73e46004ed777928942021fe1ecd"
integrity sha1-EYSSoqA9c+RgBO13eSiUICH+Hs0=
@@ -15795,6 +15820,11 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.2:
version "7.3.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
send@0.16.2:
version "0.16.2"
resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1"