@axe-core/webdriverjs 4.3.3-alpha.221 → 4.3.3-alpha.225
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -2
- package/.eslintrc.js +0 -13
- package/error-handling.md +0 -52
- package/example-with-callback.js +0 -15
- package/example.js +0 -13
- package/src/axe-injector.ts +0 -191
- package/src/browser.ts +0 -142
- package/src/index.ts +0 -271
- package/src/types.ts +0 -29
- package/src/utils/index.ts +0 -21
- package/tests/axe-webdriverjs.spec.ts +0 -691
- package/tests/fixtures/context.html +0 -15
- package/tests/fixtures/iframe-one.html +0 -14
- package/tests/test-utils.ts +0 -49
- package/tsconfig.json +0 -15
|
@@ -1,691 +0,0 @@
|
|
|
1
|
-
import 'mocha';
|
|
2
|
-
import { AxeResults, Spec } from 'axe-core';
|
|
3
|
-
import { WebDriver } from 'selenium-webdriver';
|
|
4
|
-
import * as express from 'express';
|
|
5
|
-
import * as chromedriver from 'chromedriver';
|
|
6
|
-
import testListen = require('test-listen');
|
|
7
|
-
import delay from 'delay';
|
|
8
|
-
import { assert } from 'chai';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
import * as fs from 'fs';
|
|
11
|
-
import { Server, createServer } from 'http';
|
|
12
|
-
import { Webdriver, connectToChromeDriver } from './test-utils';
|
|
13
|
-
import AxeBuilder from '../src';
|
|
14
|
-
import { axeRunPartial } from '../src/browser';
|
|
15
|
-
const dylangConfig = require('./fixtures/external/dylang-config.json') as Spec;
|
|
16
|
-
|
|
17
|
-
describe('@axe-core/webdriverjs', () => {
|
|
18
|
-
const port = 9515;
|
|
19
|
-
let driver: WebDriver;
|
|
20
|
-
let server: Server;
|
|
21
|
-
let addr: string;
|
|
22
|
-
let axeSource: string;
|
|
23
|
-
let axeCrasherSource: string;
|
|
24
|
-
let axeForceLegacy: string;
|
|
25
|
-
|
|
26
|
-
before(async () => {
|
|
27
|
-
const axePath = require.resolve('axe-core');
|
|
28
|
-
axeSource = fs.readFileSync(axePath, 'utf8');
|
|
29
|
-
const externalPath = path.resolve(__dirname, 'fixtures', 'external');
|
|
30
|
-
axeCrasherSource = fs.readFileSync(
|
|
31
|
-
path.join(externalPath, 'axe-crasher.js'),
|
|
32
|
-
'utf8'
|
|
33
|
-
);
|
|
34
|
-
axeForceLegacy = fs.readFileSync(
|
|
35
|
-
path.join(externalPath, 'axe-force-legacy.js'),
|
|
36
|
-
'utf8'
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
chromedriver.start([`--port=${port}`]);
|
|
40
|
-
await delay(500);
|
|
41
|
-
await connectToChromeDriver(port);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
after(() => {
|
|
45
|
-
chromedriver.stop();
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
beforeEach(async () => {
|
|
49
|
-
const app = express();
|
|
50
|
-
app.use(express.static(path.resolve(__dirname, 'fixtures')));
|
|
51
|
-
server = createServer(app);
|
|
52
|
-
addr = await testListen(server);
|
|
53
|
-
driver = Webdriver();
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
afterEach(async () => {
|
|
57
|
-
await driver.close();
|
|
58
|
-
server.close();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
describe('analyze', () => {
|
|
62
|
-
it('returns results', async () => {
|
|
63
|
-
await driver.get(`${addr}/external/index.html`);
|
|
64
|
-
const results = await new AxeBuilder(driver).analyze();
|
|
65
|
-
assert.isNotNull(results);
|
|
66
|
-
assert.isArray(results.violations);
|
|
67
|
-
assert.isArray(results.incomplete);
|
|
68
|
-
assert.isArray(results.passes);
|
|
69
|
-
assert.isArray(results.inapplicable);
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
it('handles undefineds', async () => {
|
|
73
|
-
await driver.get(`${addr}/external/index.html`);
|
|
74
|
-
const results = await new AxeBuilder(driver).analyze();
|
|
75
|
-
assert.isNotNull(results);
|
|
76
|
-
assert.isArray(results.violations);
|
|
77
|
-
assert.isArray(results.incomplete);
|
|
78
|
-
assert.isArray(results.passes);
|
|
79
|
-
assert.isArray(results.inapplicable);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('returns correct results metadata', async () => {
|
|
83
|
-
await driver.get(`${addr}/index.html`);
|
|
84
|
-
const results = await new AxeBuilder(driver).analyze();
|
|
85
|
-
assert.isDefined(results.testEngine.name);
|
|
86
|
-
assert.isDefined(results.testEngine.version);
|
|
87
|
-
assert.isDefined(results.testEnvironment.orientationAngle);
|
|
88
|
-
assert.isDefined(results.testEnvironment.orientationType);
|
|
89
|
-
assert.isDefined(results.testEnvironment.userAgent);
|
|
90
|
-
assert.isDefined(results.testEnvironment.windowHeight);
|
|
91
|
-
assert.isDefined(results.testEnvironment.windowWidth);
|
|
92
|
-
assert.isDefined(results.testRunner.name);
|
|
93
|
-
assert.isDefined(results.toolOptions.reporter);
|
|
94
|
-
assert.equal(results.url, `${addr}/index.html`);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('properly isolates the call to axe.finishRun', async () => {
|
|
98
|
-
let err;
|
|
99
|
-
await driver.get(`${addr}/external/isolated-finish.html`);
|
|
100
|
-
try {
|
|
101
|
-
await new AxeBuilder(driver).analyze();
|
|
102
|
-
} catch (e) {
|
|
103
|
-
err = e;
|
|
104
|
-
}
|
|
105
|
-
assert.isUndefined(err);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('throws if axe errors out on the top window', done => {
|
|
109
|
-
driver
|
|
110
|
-
.get(`${addr}/external/crash.html`)
|
|
111
|
-
.then(() => {
|
|
112
|
-
return new AxeBuilder(driver, axeSource + axeCrasherSource).analyze();
|
|
113
|
-
})
|
|
114
|
-
.then(
|
|
115
|
-
() => done(new Error('Expect async function to throw')),
|
|
116
|
-
() => done()
|
|
117
|
-
);
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
it('throws when injecting a problematic source', done => {
|
|
121
|
-
driver
|
|
122
|
-
.get(`${addr}/external/crash-me.html`)
|
|
123
|
-
.then(() => {
|
|
124
|
-
return new AxeBuilder(driver, 'throw new Error()').analyze();
|
|
125
|
-
})
|
|
126
|
-
.then(
|
|
127
|
-
() => done(new Error('Expect async function to throw')),
|
|
128
|
-
() => done()
|
|
129
|
-
);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('throws when a setup fails', done => {
|
|
133
|
-
const brokenSource = axeSource + `;window.axe.utils = {}`;
|
|
134
|
-
driver
|
|
135
|
-
.get(`${addr}/external/index.html`)
|
|
136
|
-
.then(() => {
|
|
137
|
-
return new AxeBuilder(driver, brokenSource)
|
|
138
|
-
.withRules('label')
|
|
139
|
-
.analyze();
|
|
140
|
-
})
|
|
141
|
-
.then(
|
|
142
|
-
() => done(new Error(`Expect async function to throw`)),
|
|
143
|
-
() => done()
|
|
144
|
-
);
|
|
145
|
-
});
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
describe('configure', () => {
|
|
149
|
-
it('should find configured violations in all iframes', async () => {
|
|
150
|
-
await driver.get(`${addr}/external/nested-iframes.html`);
|
|
151
|
-
const results = await new AxeBuilder(driver)
|
|
152
|
-
.configure(dylangConfig)
|
|
153
|
-
.analyze();
|
|
154
|
-
|
|
155
|
-
assert.equal(results.violations[0].id, 'dylang');
|
|
156
|
-
// the second violation is in a iframe
|
|
157
|
-
assert.equal(results.violations[0].nodes.length, 8);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it('should find configured violations in all framesets', async () => {
|
|
161
|
-
await driver.get(`${addr}/external/nested-frameset.html`);
|
|
162
|
-
const results = await new AxeBuilder(driver)
|
|
163
|
-
.configure(dylangConfig)
|
|
164
|
-
.analyze();
|
|
165
|
-
|
|
166
|
-
assert.equal(results.violations[0].id, 'dylang');
|
|
167
|
-
// the second violation is in a frame
|
|
168
|
-
assert.equal(results.violations[0].nodes.length, 8);
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it('throws when passed a non-object', () => {
|
|
172
|
-
assert.throws(() => {
|
|
173
|
-
/* @ts-expect-error */
|
|
174
|
-
new AxeBuilder(driver, axe403Source).configure('abc123');
|
|
175
|
-
});
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
describe('disableRules', () => {
|
|
180
|
-
it('disables the given rules(s) as array', async () => {
|
|
181
|
-
await driver.get(`${addr}/external/index.html`);
|
|
182
|
-
const results = await new AxeBuilder(driver)
|
|
183
|
-
.disableRules(['region'])
|
|
184
|
-
.analyze();
|
|
185
|
-
const all = [
|
|
186
|
-
...results.passes,
|
|
187
|
-
...results.inapplicable,
|
|
188
|
-
...results.violations,
|
|
189
|
-
...results.incomplete
|
|
190
|
-
];
|
|
191
|
-
assert.isTrue(!all.find(r => r.id === 'region'));
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
it('disables the given rules(s) as string', async () => {
|
|
195
|
-
await driver.get(`${addr}/external/index.html`);
|
|
196
|
-
const results = await new AxeBuilder(driver)
|
|
197
|
-
.disableRules('region')
|
|
198
|
-
.analyze();
|
|
199
|
-
const all = [
|
|
200
|
-
...results.passes,
|
|
201
|
-
...results.inapplicable,
|
|
202
|
-
...results.violations,
|
|
203
|
-
...results.incomplete
|
|
204
|
-
];
|
|
205
|
-
assert.isTrue(!all.find(r => r.id === 'region'));
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
describe('frame tests', () => {
|
|
210
|
-
it('injects into nested iframes', async () => {
|
|
211
|
-
await driver.get(`${addr}/external/nested-iframes.html`);
|
|
212
|
-
const { violations } = await new AxeBuilder(driver)
|
|
213
|
-
.options({ runOnly: 'label' })
|
|
214
|
-
.analyze();
|
|
215
|
-
|
|
216
|
-
assert.equal(violations[0].id, 'label');
|
|
217
|
-
const nodes = violations[0].nodes;
|
|
218
|
-
assert.lengthOf(nodes, 4);
|
|
219
|
-
assert.deepEqual(nodes[0].target, [
|
|
220
|
-
'#ifr-foo',
|
|
221
|
-
'#foo-bar',
|
|
222
|
-
'#bar-baz',
|
|
223
|
-
'input'
|
|
224
|
-
]);
|
|
225
|
-
assert.deepEqual(nodes[1].target, ['#ifr-foo', '#foo-baz', 'input']);
|
|
226
|
-
assert.deepEqual(nodes[2].target, ['#ifr-bar', '#bar-baz', 'input']);
|
|
227
|
-
assert.deepEqual(nodes[3].target, ['#ifr-baz', 'input']);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('injects into nested frameset', async () => {
|
|
231
|
-
await driver.get(`${addr}/external/nested-frameset.html`);
|
|
232
|
-
const { violations } = await new AxeBuilder(driver)
|
|
233
|
-
.options({ runOnly: 'label' })
|
|
234
|
-
.analyze();
|
|
235
|
-
|
|
236
|
-
assert.equal(violations[0].id, 'label');
|
|
237
|
-
assert.lengthOf(violations[0].nodes, 4);
|
|
238
|
-
|
|
239
|
-
const nodes = violations[0].nodes;
|
|
240
|
-
assert.deepEqual(nodes[0].target, [
|
|
241
|
-
'#frm-foo',
|
|
242
|
-
'#foo-bar',
|
|
243
|
-
'#bar-baz',
|
|
244
|
-
'input'
|
|
245
|
-
]);
|
|
246
|
-
assert.deepEqual(nodes[1].target, ['#frm-foo', '#foo-baz', 'input']);
|
|
247
|
-
assert.deepEqual(nodes[2].target, ['#frm-bar', '#bar-baz', 'input']);
|
|
248
|
-
assert.deepEqual(nodes[3].target, ['#frm-baz', 'input']);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it('should work on shadow DOM iframes', async () => {
|
|
252
|
-
await driver.get(`${addr}/external/shadow-frames.html`);
|
|
253
|
-
const { violations } = await new AxeBuilder(driver)
|
|
254
|
-
.options({ runOnly: 'label' })
|
|
255
|
-
.analyze();
|
|
256
|
-
|
|
257
|
-
assert.equal(violations[0].id, 'label');
|
|
258
|
-
assert.lengthOf(violations[0].nodes, 3);
|
|
259
|
-
|
|
260
|
-
const nodes = violations[0].nodes;
|
|
261
|
-
assert.deepEqual(nodes[0].target, ['#light-frame', 'input']);
|
|
262
|
-
assert.deepEqual(nodes[1].target, [
|
|
263
|
-
['#shadow-root', '#shadow-frame'],
|
|
264
|
-
'input'
|
|
265
|
-
]);
|
|
266
|
-
assert.deepEqual(nodes[2].target, ['#slotted-frame', 'input']);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it('reports erroring frames in frame-tested', async () => {
|
|
270
|
-
await driver.get(`${addr}/external/crash-parent.html`);
|
|
271
|
-
const results = await new AxeBuilder(driver, axeSource + axeCrasherSource)
|
|
272
|
-
.options({ runOnly: ['label', 'frame-tested'] })
|
|
273
|
-
.analyze();
|
|
274
|
-
|
|
275
|
-
assert.equal(results.incomplete[0].id, 'frame-tested');
|
|
276
|
-
assert.lengthOf(results.incomplete[0].nodes, 1);
|
|
277
|
-
assert.deepEqual(results.incomplete[0].nodes[0].target, ['#ifr-crash']);
|
|
278
|
-
assert.equal(results.violations[0].id, 'label');
|
|
279
|
-
assert.lengthOf(results.violations[0].nodes, 2);
|
|
280
|
-
assert.deepEqual(results.violations[0].nodes[0].target, [
|
|
281
|
-
'#ifr-bar',
|
|
282
|
-
'#bar-baz',
|
|
283
|
-
'input'
|
|
284
|
-
]);
|
|
285
|
-
assert.deepEqual(results.violations[0].nodes[1].target, [
|
|
286
|
-
'#ifr-baz',
|
|
287
|
-
'input'
|
|
288
|
-
]);
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
it('returns the same results from runPartial as from legacy mode', async () => {
|
|
292
|
-
await driver.get(`${addr}/nested-iframes.html`);
|
|
293
|
-
const legacyResults = await new AxeBuilder(
|
|
294
|
-
driver,
|
|
295
|
-
axeSource + axeForceLegacy
|
|
296
|
-
).analyze();
|
|
297
|
-
assert.equal(legacyResults.testEngine.name, 'axe-legacy');
|
|
298
|
-
|
|
299
|
-
const normalResults = await new AxeBuilder(driver, axeSource).analyze();
|
|
300
|
-
normalResults.timestamp = legacyResults.timestamp;
|
|
301
|
-
normalResults.testEngine.name = legacyResults.testEngine.name;
|
|
302
|
-
assert.deepEqual(normalResults, legacyResults);
|
|
303
|
-
});
|
|
304
|
-
});
|
|
305
|
-
|
|
306
|
-
describe('withRules', () => {
|
|
307
|
-
it('only runs the provided rules as an array', async () => {
|
|
308
|
-
await driver.get(`${addr}/external/index.html`);
|
|
309
|
-
const results = await new AxeBuilder(driver)
|
|
310
|
-
.withRules(['region'])
|
|
311
|
-
.analyze();
|
|
312
|
-
const all = [
|
|
313
|
-
...results.passes,
|
|
314
|
-
...results.inapplicable,
|
|
315
|
-
...results.violations,
|
|
316
|
-
...results.incomplete
|
|
317
|
-
];
|
|
318
|
-
assert.strictEqual(all.length, 1);
|
|
319
|
-
assert.strictEqual(all[0].id, 'region');
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
it('only runs the provided rules as a string', async () => {
|
|
323
|
-
await driver.get(`${addr}/external/index.html`);
|
|
324
|
-
const results = await new AxeBuilder(driver)
|
|
325
|
-
.withRules('region')
|
|
326
|
-
.analyze();
|
|
327
|
-
const all = [
|
|
328
|
-
...results.passes,
|
|
329
|
-
...results.inapplicable,
|
|
330
|
-
...results.violations,
|
|
331
|
-
...results.incomplete
|
|
332
|
-
];
|
|
333
|
-
assert.strictEqual(all.length, 1);
|
|
334
|
-
assert.strictEqual(all[0].id, 'region');
|
|
335
|
-
});
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
describe('options', () => {
|
|
339
|
-
it('passes options to axe-core', async () => {
|
|
340
|
-
await driver.get(`${addr}/external/index.html`);
|
|
341
|
-
const results = await new AxeBuilder(driver)
|
|
342
|
-
.options({ rules: { region: { enabled: false } } })
|
|
343
|
-
.analyze();
|
|
344
|
-
const all = [
|
|
345
|
-
...results.passes,
|
|
346
|
-
...results.inapplicable,
|
|
347
|
-
...results.violations,
|
|
348
|
-
...results.incomplete
|
|
349
|
-
];
|
|
350
|
-
assert.isTrue(!all.find(r => r.id === 'region'));
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
describe('withTags', () => {
|
|
355
|
-
it('only rules rules with the given tag(s) as an array', async () => {
|
|
356
|
-
await driver.get(`${addr}/external/index.html`);
|
|
357
|
-
const results = await new AxeBuilder(driver)
|
|
358
|
-
.withTags(['best-practice'])
|
|
359
|
-
.analyze();
|
|
360
|
-
const all = [
|
|
361
|
-
...results.passes,
|
|
362
|
-
...results.inapplicable,
|
|
363
|
-
...results.violations,
|
|
364
|
-
...results.incomplete
|
|
365
|
-
];
|
|
366
|
-
assert.isOk(all);
|
|
367
|
-
for (const rule of all) {
|
|
368
|
-
assert.include(rule.tags, 'best-practice');
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
|
|
372
|
-
it('only rules rules with the given tag(s) as a string', async () => {
|
|
373
|
-
await driver.get(`${addr}/external/index.html`);
|
|
374
|
-
const results = await new AxeBuilder(driver)
|
|
375
|
-
.withTags('best-practice')
|
|
376
|
-
.analyze();
|
|
377
|
-
const all = [
|
|
378
|
-
...results.passes,
|
|
379
|
-
...results.inapplicable,
|
|
380
|
-
...results.violations,
|
|
381
|
-
...results.incomplete
|
|
382
|
-
];
|
|
383
|
-
assert.isOk(all);
|
|
384
|
-
for (const rule of all) {
|
|
385
|
-
assert.include(rule.tags, 'best-practice');
|
|
386
|
-
}
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
it('No results provided when the given tag(s) is invalid', async () => {
|
|
390
|
-
await driver.get(`${addr}/external/index.html`);
|
|
391
|
-
const results = await new AxeBuilder(driver)
|
|
392
|
-
.withTags(['foobar'])
|
|
393
|
-
.analyze();
|
|
394
|
-
|
|
395
|
-
const all = [
|
|
396
|
-
...results.passes,
|
|
397
|
-
...results.inapplicable,
|
|
398
|
-
...results.violations,
|
|
399
|
-
...results.incomplete
|
|
400
|
-
];
|
|
401
|
-
// Ensure all run rules had the "foobar" tag
|
|
402
|
-
assert.deepStrictEqual(0, all.length);
|
|
403
|
-
});
|
|
404
|
-
});
|
|
405
|
-
|
|
406
|
-
describe('include/exclude', () => {
|
|
407
|
-
const flatPassesTargets = (results: AxeResults): string[] => {
|
|
408
|
-
return results.passes
|
|
409
|
-
.reduce((acc, pass) => {
|
|
410
|
-
return acc.concat(pass.nodes as any);
|
|
411
|
-
}, [])
|
|
412
|
-
.reduce((acc, node: any) => {
|
|
413
|
-
return acc.concat(node.target);
|
|
414
|
-
}, []);
|
|
415
|
-
};
|
|
416
|
-
it('with include and exclude', async () => {
|
|
417
|
-
await driver.get(`${addr}/context.html`);
|
|
418
|
-
const builder = new AxeBuilder(driver)
|
|
419
|
-
.include('.include')
|
|
420
|
-
.exclude('.exclude');
|
|
421
|
-
const results = await builder.analyze();
|
|
422
|
-
|
|
423
|
-
assert.isTrue(flatPassesTargets(results).includes('.include'));
|
|
424
|
-
assert.isFalse(flatPassesTargets(results).includes('.exclude'));
|
|
425
|
-
});
|
|
426
|
-
|
|
427
|
-
it('with only include', async () => {
|
|
428
|
-
await driver.get(`${addr}/context.html`);
|
|
429
|
-
const builder = new AxeBuilder(driver).include('.include');
|
|
430
|
-
const results = await builder.analyze();
|
|
431
|
-
|
|
432
|
-
assert.isTrue(flatPassesTargets(results).includes('.include'));
|
|
433
|
-
});
|
|
434
|
-
|
|
435
|
-
it('with only exclude', async () => {
|
|
436
|
-
await driver.get(`${addr}/context.html`);
|
|
437
|
-
const builder = new AxeBuilder(driver).exclude('.exclude');
|
|
438
|
-
const results = await builder.analyze();
|
|
439
|
-
|
|
440
|
-
assert.isFalse(flatPassesTargets(results).includes('.exclude'));
|
|
441
|
-
});
|
|
442
|
-
|
|
443
|
-
it('with chaining only include', async () => {
|
|
444
|
-
await driver.get(`${addr}/context.html`);
|
|
445
|
-
const builder = new AxeBuilder(driver)
|
|
446
|
-
.include('.include')
|
|
447
|
-
.include('.include2');
|
|
448
|
-
const results = await builder.analyze();
|
|
449
|
-
|
|
450
|
-
assert.isTrue(flatPassesTargets(results).includes('.include'));
|
|
451
|
-
assert.isTrue(flatPassesTargets(results).includes('.include2'));
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
it('with chaining only exclude', async () => {
|
|
455
|
-
await driver.get(`${addr}/context.html`);
|
|
456
|
-
const builder = new AxeBuilder(driver)
|
|
457
|
-
.exclude('.exclude')
|
|
458
|
-
.exclude('.exclude2');
|
|
459
|
-
const results = await builder.analyze();
|
|
460
|
-
|
|
461
|
-
assert.isFalse(flatPassesTargets(results).includes('.exclude'));
|
|
462
|
-
assert.isFalse(flatPassesTargets(results).includes('.exclude2'));
|
|
463
|
-
});
|
|
464
|
-
|
|
465
|
-
it('with chaining include and exclude', async () => {
|
|
466
|
-
await driver.get(`${addr}/context.html`);
|
|
467
|
-
const builder = new AxeBuilder(driver)
|
|
468
|
-
.include('.include')
|
|
469
|
-
.include('.include2')
|
|
470
|
-
.exclude('.exclude')
|
|
471
|
-
.exclude('.exclude2');
|
|
472
|
-
const results = await builder.analyze();
|
|
473
|
-
|
|
474
|
-
assert.isTrue(flatPassesTargets(results).includes('.include'));
|
|
475
|
-
assert.isTrue(flatPassesTargets(results).includes('.include2'));
|
|
476
|
-
assert.isFalse(flatPassesTargets(results).includes('.exclude'));
|
|
477
|
-
assert.isFalse(flatPassesTargets(results).includes('.exclude2'));
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
it('with include and exclude iframe selectors with no violations', async () => {
|
|
481
|
-
await driver.get(`${addr}/context.html`);
|
|
482
|
-
const builder = new AxeBuilder(driver)
|
|
483
|
-
.include(['#ifr-one', 'html'])
|
|
484
|
-
.exclude(['#ifr-one', 'main'])
|
|
485
|
-
.exclude(['#ifr-one', 'img']);
|
|
486
|
-
|
|
487
|
-
const results = await builder.analyze();
|
|
488
|
-
|
|
489
|
-
assert.lengthOf(results.violations, 0);
|
|
490
|
-
});
|
|
491
|
-
|
|
492
|
-
it('with include and exclude iframe selectors with violations', async () => {
|
|
493
|
-
await driver.get(`${addr}/context.html`);
|
|
494
|
-
const builder = new AxeBuilder(driver)
|
|
495
|
-
.include(['#ifr-one', 'html'])
|
|
496
|
-
.exclude(['#ifr-one', 'main']);
|
|
497
|
-
const results = await builder.analyze();
|
|
498
|
-
|
|
499
|
-
assert.lengthOf(results.violations, 2);
|
|
500
|
-
assert.strictEqual(results.violations[0].id, 'image-alt');
|
|
501
|
-
assert.strictEqual(results.violations[1].id, 'region');
|
|
502
|
-
});
|
|
503
|
-
});
|
|
504
|
-
|
|
505
|
-
describe('callback()', () => {
|
|
506
|
-
it('returns an error as the first argument', done => {
|
|
507
|
-
driver.get(`${addr}/external/index.html`).then(() => {
|
|
508
|
-
new AxeBuilder(driver, 'throw new Error()').analyze((err, results) => {
|
|
509
|
-
try {
|
|
510
|
-
assert.isNull(results);
|
|
511
|
-
assert.isNotNull(err);
|
|
512
|
-
done();
|
|
513
|
-
} catch (e) {
|
|
514
|
-
done(e);
|
|
515
|
-
}
|
|
516
|
-
});
|
|
517
|
-
});
|
|
518
|
-
});
|
|
519
|
-
|
|
520
|
-
it('returns as the second argument', done => {
|
|
521
|
-
driver.get(`${addr}/external/index.html`).then(() => {
|
|
522
|
-
new AxeBuilder(driver).analyze((err, results) => {
|
|
523
|
-
try {
|
|
524
|
-
assert.isNull(err);
|
|
525
|
-
assert.isNotNull(results);
|
|
526
|
-
assert.isArray(results?.violations);
|
|
527
|
-
assert.isArray(results?.incomplete);
|
|
528
|
-
assert.isArray(results?.passes);
|
|
529
|
-
assert.isArray(results?.inapplicable);
|
|
530
|
-
done();
|
|
531
|
-
} catch (e) {
|
|
532
|
-
done(e);
|
|
533
|
-
}
|
|
534
|
-
});
|
|
535
|
-
});
|
|
536
|
-
});
|
|
537
|
-
});
|
|
538
|
-
|
|
539
|
-
describe('axe.finishRun errors', () => {
|
|
540
|
-
const finishRunThrows = `;axe.finishRun = () => { throw new Error("No finishRun")}`;
|
|
541
|
-
const windowOpenThrows = `;window.open = () => { throw new Error("No window.open")}`;
|
|
542
|
-
|
|
543
|
-
it('throws an error if window.open throws', async () => {
|
|
544
|
-
const source = axeSource + windowOpenThrows;
|
|
545
|
-
await driver.get(`${addr}/external/index.html`);
|
|
546
|
-
|
|
547
|
-
try {
|
|
548
|
-
await new AxeBuilder(driver, source).analyze();
|
|
549
|
-
assert.fail('Should have thrown');
|
|
550
|
-
} catch (err) {
|
|
551
|
-
assert.match((err as Error).message, /switchTo failed./);
|
|
552
|
-
}
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
it('throws an error if axe.finishRun throws', async () => {
|
|
556
|
-
const source = axeSource + finishRunThrows;
|
|
557
|
-
await driver.get(`${addr}/external/index.html`);
|
|
558
|
-
|
|
559
|
-
try {
|
|
560
|
-
await new AxeBuilder(driver, source).analyze();
|
|
561
|
-
assert.fail('Should have thrown');
|
|
562
|
-
} catch (err) {
|
|
563
|
-
assert.match((err as Error).message, /Please check out/);
|
|
564
|
-
}
|
|
565
|
-
});
|
|
566
|
-
});
|
|
567
|
-
|
|
568
|
-
describe('setLegacyMode', () => {
|
|
569
|
-
const runPartialThrows = `;axe.runPartial = () => { throw new Error("No runPartial")}`;
|
|
570
|
-
it('runs legacy mode when used', async () => {
|
|
571
|
-
await driver.get(`${addr}/external/index.html`);
|
|
572
|
-
const results = await new AxeBuilder(driver, axeSource + runPartialThrows)
|
|
573
|
-
.setLegacyMode()
|
|
574
|
-
.analyze();
|
|
575
|
-
assert.isNotNull(results);
|
|
576
|
-
});
|
|
577
|
-
|
|
578
|
-
it('prevents cross-origin frame testing', async () => {
|
|
579
|
-
await driver.get(`${addr}/external/cross-origin.html`);
|
|
580
|
-
const results = await new AxeBuilder(driver, axeSource + runPartialThrows)
|
|
581
|
-
.withRules(['frame-tested'])
|
|
582
|
-
.setLegacyMode()
|
|
583
|
-
.analyze();
|
|
584
|
-
|
|
585
|
-
const frameTested = results.incomplete.find(
|
|
586
|
-
({ id }) => id === 'frame-tested'
|
|
587
|
-
);
|
|
588
|
-
assert.ok(frameTested);
|
|
589
|
-
});
|
|
590
|
-
|
|
591
|
-
it('can be disabled again', async () => {
|
|
592
|
-
await driver.get(`${addr}/external/cross-origin.html`);
|
|
593
|
-
const results = await new AxeBuilder(driver)
|
|
594
|
-
.withRules(['frame-tested'])
|
|
595
|
-
.setLegacyMode()
|
|
596
|
-
.setLegacyMode(false)
|
|
597
|
-
.analyze();
|
|
598
|
-
|
|
599
|
-
const frameTested = results.incomplete.find(
|
|
600
|
-
({ id }) => id === 'frame-tested'
|
|
601
|
-
);
|
|
602
|
-
assert.isUndefined(frameTested);
|
|
603
|
-
});
|
|
604
|
-
});
|
|
605
|
-
|
|
606
|
-
describe('browser functions', () => {
|
|
607
|
-
it('serializes results', async () => {
|
|
608
|
-
await driver.get(`${addr}/external/nested-iframes.html`);
|
|
609
|
-
await driver.executeScript(`
|
|
610
|
-
window.axe = {
|
|
611
|
-
runPartial: (c, o) => Promise.resolve({ violations: [], passes: [] })
|
|
612
|
-
};
|
|
613
|
-
`);
|
|
614
|
-
const res = await axeRunPartial(driver, null as any, null as any);
|
|
615
|
-
assert.equal(typeof res, 'string');
|
|
616
|
-
});
|
|
617
|
-
});
|
|
618
|
-
describe('for versions without axe.runPartial', () => {
|
|
619
|
-
let axe403Source: string;
|
|
620
|
-
before(() => {
|
|
621
|
-
const axe403Path = path.resolve(
|
|
622
|
-
__dirname,
|
|
623
|
-
'fixtures',
|
|
624
|
-
'external',
|
|
625
|
-
'axe-core@legacy.js'
|
|
626
|
-
);
|
|
627
|
-
axe403Source = fs.readFileSync(axe403Path, 'utf8');
|
|
628
|
-
});
|
|
629
|
-
|
|
630
|
-
it('can run', async () => {
|
|
631
|
-
await driver.get(`${addr}/external/nested-iframes.html`);
|
|
632
|
-
const results = await new AxeBuilder(driver, axe403Source)
|
|
633
|
-
.options({ runOnly: ['label'] })
|
|
634
|
-
.analyze();
|
|
635
|
-
|
|
636
|
-
assert.equal(results.violations[0].id, 'label');
|
|
637
|
-
assert.lengthOf(results.violations[0].nodes, 4);
|
|
638
|
-
assert.equal(results.testEngine.version, '4.0.3');
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
it('throws if the top level errors', done => {
|
|
642
|
-
driver
|
|
643
|
-
.get(`${addr}/external/crash.html`)
|
|
644
|
-
.then(() => {
|
|
645
|
-
return new AxeBuilder(
|
|
646
|
-
driver,
|
|
647
|
-
axe403Source + axeCrasherSource
|
|
648
|
-
).analyze();
|
|
649
|
-
})
|
|
650
|
-
.then(
|
|
651
|
-
() => done(new Error('Expect async function to throw')),
|
|
652
|
-
() => done()
|
|
653
|
-
);
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
it('can be configured', async () => {
|
|
657
|
-
await driver.get(`${addr}/external/nested-iframes.html`);
|
|
658
|
-
const results = await new AxeBuilder(driver, axe403Source)
|
|
659
|
-
.configure(dylangConfig)
|
|
660
|
-
.analyze();
|
|
661
|
-
assert.equal(results.violations[0].id, 'dylang');
|
|
662
|
-
assert.equal(results.violations[0].nodes.length, 8);
|
|
663
|
-
});
|
|
664
|
-
|
|
665
|
-
it('reports frame-tested', async () => {
|
|
666
|
-
await driver.get(`${addr}/external/crash-parent.html`);
|
|
667
|
-
const results = await new AxeBuilder(
|
|
668
|
-
driver,
|
|
669
|
-
axe403Source + axeCrasherSource
|
|
670
|
-
)
|
|
671
|
-
.options({ runOnly: ['label', 'frame-tested'] })
|
|
672
|
-
.analyze();
|
|
673
|
-
assert.equal(results.incomplete[0].id, 'frame-tested');
|
|
674
|
-
assert.lengthOf(results.incomplete[0].nodes, 1);
|
|
675
|
-
assert.equal(results.violations[0].id, 'label');
|
|
676
|
-
assert.lengthOf(results.violations[0].nodes, 2);
|
|
677
|
-
});
|
|
678
|
-
|
|
679
|
-
it('tests cross-origin pages', async () => {
|
|
680
|
-
await driver.get(`${addr}/external/cross-origin.html`);
|
|
681
|
-
const results = await new AxeBuilder(driver, axe403Source)
|
|
682
|
-
.withRules(['frame-tested'])
|
|
683
|
-
.analyze();
|
|
684
|
-
|
|
685
|
-
const frameTested = results.incomplete.find(
|
|
686
|
-
({ id }) => id === 'frame-tested'
|
|
687
|
-
);
|
|
688
|
-
assert.isUndefined(frameTested);
|
|
689
|
-
});
|
|
690
|
-
});
|
|
691
|
-
});
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Context Test</title>
|
|
5
|
-
</head>
|
|
6
|
-
<body>
|
|
7
|
-
<h1>Context Test</h1>
|
|
8
|
-
<div class="include">include me</div>
|
|
9
|
-
<div class="include2">include me two</div>
|
|
10
|
-
<div class="exclude">exclude me</div>
|
|
11
|
-
<div class="exclude2">exclude me two</div>
|
|
12
|
-
|
|
13
|
-
<iframe src="iframe-one.html" id="ifr-one"></iframe>
|
|
14
|
-
</body>
|
|
15
|
-
</html>
|