@axe-core/webdriverjs 4.3.3-alpha.224 → 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/src/index.ts DELETED
@@ -1,271 +0,0 @@
1
- import { WebDriver } from 'selenium-webdriver';
2
- import { RunOptions, Spec, AxeResults, ContextObject } from 'axe-core';
3
- import { source } from 'axe-core';
4
- import {
5
- CallbackFunction,
6
- BuilderOptions,
7
- PartialResults,
8
- Selector
9
- } from './types';
10
- import { normalizeContext } from './utils/index';
11
- import AxeInjector from './axe-injector';
12
- import {
13
- axeGetFrameContext,
14
- axeRunPartial,
15
- axeRunLegacy,
16
- axeSourceInject,
17
- axeFinishRun
18
- } from './browser';
19
- import * as assert from 'assert';
20
-
21
- class AxeBuilder {
22
- private driver: WebDriver;
23
- private axeSource: string;
24
- private includes: Selector[];
25
- private excludes: Selector[];
26
- private option: RunOptions;
27
- private config: Spec | null;
28
- private builderOptions: BuilderOptions;
29
- private legacyMode = false;
30
-
31
- constructor(
32
- driver: WebDriver,
33
- axeSource?: string | null,
34
- builderOptions?: BuilderOptions
35
- ) {
36
- this.driver = driver;
37
- this.axeSource = axeSource || source;
38
- this.includes = [];
39
- this.excludes = [];
40
- this.option = {};
41
- this.config = null;
42
- this.builderOptions = builderOptions || {};
43
- }
44
-
45
- /**
46
- * Selector to include in analysis.
47
- * This may be called any number of times.
48
- */
49
- public include(selector: Selector): this {
50
- selector = Array.isArray(selector) ? selector : [selector];
51
- this.includes.push(selector);
52
- return this;
53
- }
54
-
55
- /**
56
- * Selector to exclude in analysis.
57
- * This may be called any number of times.
58
- */
59
- public exclude(selector: Selector): this {
60
- selector = Array.isArray(selector) ? selector : [selector];
61
- this.excludes.push(selector);
62
- return this;
63
- }
64
-
65
- /**
66
- * Set options to be passed into axe-core
67
- */
68
- public options(options: RunOptions): this {
69
- this.option = options;
70
- return this;
71
- }
72
-
73
- /**
74
- * Limit analysis to only the specified rules.
75
- * Cannot be used with `AxeBuilder#withTags`
76
- */
77
- public withRules(rules: string | string[]): this {
78
- rules = Array.isArray(rules) ? rules : [rules];
79
- this.option.runOnly = {
80
- type: 'rule',
81
- values: rules
82
- };
83
-
84
- return this;
85
- }
86
-
87
- /**
88
- * Limit analysis to only specified tags.
89
- * Cannot be used with `AxeBuilder#withRules`
90
- */
91
- public withTags(tags: string | string[]): this {
92
- tags = Array.isArray(tags) ? tags : [tags];
93
- this.option.runOnly = {
94
- type: 'tag',
95
- values: tags
96
- };
97
- return this;
98
- }
99
-
100
- /**
101
- * Set the list of rules to skip when running an analysis.
102
- */
103
- public disableRules(rules: string | string[]): this {
104
- rules = Array.isArray(rules) ? rules : [rules];
105
- this.option.rules = {};
106
- for (const rule of rules) {
107
- this.option.rules[rule] = { enabled: false };
108
- }
109
- return this;
110
- }
111
-
112
- /**
113
- * Set configuration for `axe-core`.
114
- * This value is passed directly to `axe.configure()`
115
- */
116
- public configure(config: Spec): this {
117
- if (typeof config !== 'object') {
118
- throw new Error(
119
- 'AxeBuilder needs an object to configure. See axe-core configure API.'
120
- );
121
- }
122
- this.config = config;
123
- return this;
124
- }
125
-
126
- /**
127
- * Performs an analysis and retrieves results.
128
- */
129
- public async analyze(callback?: CallbackFunction): Promise<AxeResults> {
130
- return new Promise((resolve, reject) => {
131
- return this.analyzePromise()
132
- .then((results: AxeResults) => {
133
- callback?.(null, results);
134
- resolve(results);
135
- })
136
- .catch((err: Error) => {
137
- // When using a callback, do *not* reject the wrapping Promise. This prevents having to handle the same error twice.
138
- if (callback) {
139
- callback(err.message, null);
140
- } else {
141
- reject(err);
142
- }
143
- });
144
- });
145
- }
146
-
147
- /**
148
- * Use frameMessenger with <same_origin_only>
149
- *
150
- * This disables use of axe.runPartial() which is called in each frame, and
151
- * axe.finishRun() which is called in a blank page. This uses axe.run() instead,
152
- * but with the restriction that cross-origin frames will not be tested.
153
- */
154
- public setLegacyMode(legacyMode = true): AxeBuilder {
155
- this.legacyMode = legacyMode;
156
- return this;
157
- }
158
-
159
- /**
160
- * Analyzes the page, returning a promise
161
- */
162
- private async analyzePromise(): Promise<AxeResults> {
163
- const context = normalizeContext(this.includes, this.excludes);
164
- await this.driver.switchTo().defaultContent();
165
- const { runPartialSupported } = await axeSourceInject(
166
- this.driver,
167
- this.axeSource,
168
- this.config
169
- );
170
- if (runPartialSupported !== true || this.legacyMode) {
171
- return this.runLegacy(context);
172
- }
173
-
174
- const partials = await this.runPartialRecursive(context, true);
175
-
176
- try {
177
- return await this.finishRun(partials);
178
- } catch (error) {
179
- throw new Error(
180
- `${
181
- (error as Error).message
182
- }\n Please check out https://github.com/dequelabs/axe-core-npm/blob/develop/packages/webdriverjs/error-handling.md`
183
- );
184
- }
185
- }
186
-
187
- /**
188
- * Use axe.run() to get results from the page
189
- */
190
- private async runLegacy(context: ContextObject): Promise<AxeResults> {
191
- const { driver, axeSource, builderOptions } = this;
192
- let config = this.config;
193
- if (this.legacyMode !== true) {
194
- config = {
195
- ...(config || {}),
196
- allowedOrigins: ['<unsafe_all_origins>']
197
- };
198
- }
199
- const injector = new AxeInjector({
200
- driver,
201
- axeSource,
202
- config,
203
- builderOptions
204
- });
205
- await injector.injectIntoAllFrames();
206
- return axeRunLegacy(this.driver, context, this.option, this.config);
207
- }
208
-
209
- /**
210
- * Get partial results from the current context and its child frames
211
- */
212
- private async runPartialRecursive(
213
- context: ContextObject,
214
- initiator = false
215
- ): Promise<string[]> {
216
- if (!initiator) {
217
- await axeSourceInject(this.driver, this.axeSource, this.config);
218
- }
219
- // IMPORTANT: axeGetFrameContext MUST be called before axeRunPartial
220
- const frameContexts = await axeGetFrameContext(this.driver, context);
221
- const partials: string[] = [
222
- await axeRunPartial(this.driver, context, this.option)
223
- ];
224
-
225
- for (const { frameContext, frameSelector, frame } of frameContexts) {
226
- let switchedFrame = false;
227
- try {
228
- assert(frame, `Expect frame of "${frameSelector}" to be defined`);
229
- await this.driver.switchTo().frame(frame);
230
- switchedFrame = true;
231
- partials.push(...(await this.runPartialRecursive(frameContext)));
232
- await this.driver.switchTo().parentFrame();
233
- } catch {
234
- if (switchedFrame) {
235
- await this.driver.switchTo().parentFrame();
236
- }
237
- partials.push('null');
238
- }
239
- }
240
- return partials;
241
- }
242
-
243
- /**
244
- * Use axe.finishRun() to turn partial results into actual results
245
- */
246
- private async finishRun(partials: string[]): Promise<AxeResults> {
247
- const { driver, axeSource, config, option } = this;
248
-
249
- const win = await driver.getWindowHandle();
250
-
251
- try {
252
- await driver.executeScript(`window.open('about:blank')`);
253
- const handlers = await driver.getAllWindowHandles();
254
- await driver.switchTo().window(handlers[handlers.length - 1]);
255
- await driver.get('about:blank');
256
- } catch (error) {
257
- throw new Error(
258
- `switchTo failed. Are you using updated browser drivers? \nDriver reported:\n${error}`
259
- );
260
- }
261
- // Make sure we're on a blank page, even if window.open isn't functioning properly.
262
- const res = await axeFinishRun(driver, axeSource, config, partials, option);
263
- await driver.close();
264
- await driver.switchTo().window(win);
265
- return res;
266
- }
267
- }
268
-
269
- exports = module.exports = AxeBuilder;
270
-
271
- export default AxeBuilder;
package/src/types.ts DELETED
@@ -1,29 +0,0 @@
1
- import type { WebDriver } from 'selenium-webdriver';
2
- import type { Spec, AxeResults, BaseSelector } from 'axe-core';
3
- import * as axe from 'axe-core';
4
-
5
- export interface Options {
6
- driver: WebDriver;
7
- axeSource?: string;
8
- builderOptions?: BuilderOptions;
9
- }
10
-
11
- export interface BuilderOptions {
12
- noSandbox?: boolean;
13
- logIframeErrors?: boolean;
14
- }
15
-
16
- export interface AxeInjectorParams extends Options {
17
- config?: Spec | null;
18
- }
19
-
20
- export type CallbackFunction = (
21
- error: string | null,
22
- results: AxeResults | null
23
- ) => void;
24
-
25
- export type InjectCallback = (err?: Error) => void;
26
-
27
- export type PartialResults = Parameters<typeof axe.finishRun>[0];
28
-
29
- export type Selector = BaseSelector | BaseSelector[];
@@ -1,21 +0,0 @@
1
- import type { ContextObject } from 'axe-core';
2
- import { Selector } from '../types';
3
-
4
- /**
5
- * Get running context
6
- */
7
- export const normalizeContext = (
8
- include: Selector[],
9
- exclude: Selector[]
10
- ): ContextObject => {
11
- const base: ContextObject = {
12
- exclude: []
13
- };
14
- if (exclude.length && Array.isArray(base.exclude)) {
15
- base.exclude.push(...exclude);
16
- }
17
- if (include.length) {
18
- base.include = include;
19
- }
20
- return base;
21
- };