Skip to content

Commit 0511338

Browse files
strakerZidious
andauthored
fix(webdriverio): fix types between v8 and <v8 (#962)
* fix(webdriverio): fix types between v8 and <v8 * fix tests and pin to same version * latest wdio * drop cli to use chromedriver 119 to fix 120 problem * Update packages/webdriverio/src/utils.ts Co-authored-by: Gabe <41127686+Zidious@users.noreply.github.com> * suggestions --------- Co-authored-by: Gabe <41127686+Zidious@users.noreply.github.com>
1 parent 4eec517 commit 0511338

File tree

9 files changed

+522
-1425
lines changed

9 files changed

+522
-1425
lines changed

.github/workflows/tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
- run: npm ci
6060
# HACK: Force a TTY to enable browser-driver-manager to manipulate stdout.
6161
- shell: 'script -q -e -c "bash {0}"'
62-
run: npx browser-driver-manager install chromedriver --verbose
62+
run: npx browser-driver-manager install chromedriver=119 --verbose
6363
working-directory: packages/cli
6464
- run: npm run coverage --workspace=packages/cli
6565

package-lock.json

Lines changed: 441 additions & 1384 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/webdriverio/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,9 @@
5656
"@types/chromedriver": "^81.0.1",
5757
"@types/cssesc": "^3.0.0",
5858
"@types/express": "^4.17.14",
59-
"@types/mocha": "^10.0.0",
59+
"@types/mocha": "^10.0.6",
6060
"@types/node": "^20.8.10",
61+
"@wdio/globals": "^8.27.0",
6162
"async-listen": "^3.0.1",
6263
"axe-test-fixtures": "github:dequelabs/axe-test-fixtures#v1",
6364
"chai": "^4.3.6",

packages/webdriverio/src/index.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@ import {
1616
import { getFilename } from 'cross-dirname';
1717
import { pathToFileURL } from 'url';
1818

19-
import type { Browser, Element } from 'webdriverio';
2019
import type {
2120
RunOptions,
2221
AxeResults,
2322
SerialContextObject,
2423
SerialSelectorList,
2524
SerialFrameSelector
2625
} from 'axe-core';
27-
import type { Options, CallbackFunction, PartialResults } from './types';
26+
import type {
27+
Options,
28+
CallbackFunction,
29+
PartialResults,
30+
WdioBrowser,
31+
WdioElement
32+
} from './types';
2833

2934
let axeCorePath = '';
3035
async function loadAxePath() {
@@ -43,7 +48,7 @@ async function loadAxePath() {
4348
loadAxePath();
4449

4550
export default class AxeBuilder {
46-
private client: Browser;
51+
private client: WdioBrowser;
4752
private axeSource: string;
4853
private includes: SerialSelectorList = [];
4954
private excludes: SerialSelectorList = [];
@@ -199,7 +204,9 @@ export default class AxeBuilder {
199204
/**
200205
* Injects `axe-core` into all frames.
201206
*/
202-
private async inject(browsingContext: Element | null = null): Promise<void> {
207+
private async inject(
208+
browsingContext: WdioElement | null = null
209+
): Promise<void> {
203210
await this.setBrowsingContext(browsingContext);
204211
const runPartialSupported = await axeSourceInject(
205212
this.client,
@@ -246,15 +253,15 @@ export default class AxeBuilder {
246253
// ensure we fail quickly if an iframe cannot be loaded (instead of waiting
247254
// the default length of 30 seconds)
248255
const { pageLoad } = await this.client.getTimeouts();
249-
this.client.setTimeout({
256+
(this.client as WebdriverIO.Browser).setTimeout({
250257
pageLoad: FRAME_LOAD_TIMEOUT
251258
});
252259

253260
let partials: PartialResults | null;
254261
try {
255262
partials = await this.runPartialRecursive(context);
256263
} finally {
257-
this.client.setTimeout({
264+
(this.client as WebdriverIO.Browser).setTimeout({
258265
pageLoad
259266
});
260267
}
@@ -301,7 +308,7 @@ export default class AxeBuilder {
301308
* - https://webdriver.io/docs/api/webdriver.html#switchtoframe
302309
*/
303310
private async setBrowsingContext(
304-
id: null | Element | Browser = null
311+
id: null | WdioElement | WdioBrowser = null
305312
): Promise<void> {
306313
if (id) {
307314
await this.client.switchToFrame(id);
@@ -317,7 +324,7 @@ export default class AxeBuilder {
317324

318325
private async runPartialRecursive(
319326
context: SerialContextObject,
320-
frameStack: Element[] = []
327+
frameStack: WdioElement[] = []
321328
): Promise<PartialResults> {
322329
const frameContexts = await axeGetFrameContext(this.client, context);
323330
const partials: PartialResults = [
@@ -362,7 +369,7 @@ export default class AxeBuilder {
362369

363370
try {
364371
await client.switchToWindow(newWindow.handle);
365-
await client.url('about:blank');
372+
await (client as WebdriverIO.Browser).url('about:blank');
366373
} catch (error) {
367374
throw new Error(
368375
`switchToWindow failed. Are you using updated browser drivers? \nDriver reported:\n${

packages/webdriverio/src/types.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,43 @@
1-
import type { Browser } from 'webdriverio';
21
import type { AxeResults, BaseSelector } from 'axe-core';
32
import * as axe from 'axe-core';
3+
import { type Browser, type Element } from 'webdriverio';
4+
5+
/*
6+
This type allows both webdriverio v8 and <=v7 Browser types
7+
to work in the same codebase. The types are incompatible with
8+
each other, but are compatible with the functions that we use.
9+
Every new feature that we use from the Browser type will need
10+
to be added to the Pick list
11+
*/
12+
export type WdioBrowser =
13+
| Browser
14+
| Pick<
15+
WebdriverIO.Browser,
16+
| '$$'
17+
| '$'
18+
| 'switchToFrame'
19+
| 'switchToParentFrame'
20+
| 'getWindowHandles'
21+
| 'getWindowHandle'
22+
| 'switchToWindow'
23+
| 'createWindow'
24+
| 'url'
25+
| 'getTimeouts'
26+
| 'setTimeout'
27+
| 'closeWindow'
28+
| 'executeAsync'
29+
| 'execute'
30+
>;
31+
32+
export type WdioElement = Element | WebdriverIO.Element;
433

534
export type CallbackFunction = (
635
error: string | null,
736
results: AxeResults | null
837
) => void;
938

1039
export interface Options {
11-
client: Browser;
40+
client: WdioBrowser;
1241
axeSource?: string;
1342
}
1443

packages/webdriverio/src/utils.ts

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import assert from 'assert';
2-
import type { Browser } from 'webdriverio';
32
import type {
43
AxeResults,
54
PartialResult,
@@ -9,13 +8,14 @@ import type {
98
SerialSelectorList,
109
SerialContextObject
1110
} from 'axe-core';
11+
import type { WdioBrowser } from './types';
1212

1313
export const FRAME_LOAD_TIMEOUT = 1000;
1414

1515
/**
1616
* Validates that the client provided is WebdriverIO v5+.
1717
*/
18-
export const isWebdriverClient = (client: Browser): boolean => {
18+
export const isWebdriverClient = (client: WdioBrowser): boolean => {
1919
if (!client) {
2020
return false;
2121
}
@@ -82,14 +82,14 @@ const promisify = <T>(thenable: Promise<T>): Promise<T> => {
8282
};
8383

8484
export const axeSourceInject = async (
85-
client: Browser,
85+
client: WdioBrowser,
8686
axeSource: string
8787
): Promise<{ runPartialSupported: boolean }> => {
8888
await assertFrameReady(client);
8989
return promisify(
9090
// Had to use executeAsync() because we could not use multiline statements in client.execute()
9191
// we were able to return a single boolean in a line but not when assigned to a variable.
92-
client.executeAsync(`
92+
(client as WebdriverIO.Browser).executeAsync(`
9393
var callback = arguments[arguments.length - 1];
9494
${axeSource};
9595
window.axe.configure({
@@ -101,7 +101,7 @@ export const axeSourceInject = async (
101101
);
102102
};
103103

104-
async function assertFrameReady(client: Browser): Promise<void> {
104+
async function assertFrameReady(client: WdioBrowser): Promise<void> {
105105
// Wait so that we know there is an execution context.
106106
// Assume that if we have an html node we have an execution context.
107107
try {
@@ -119,7 +119,7 @@ async function assertFrameReady(client: Browser): Promise<void> {
119119
reject();
120120
}, FRAME_LOAD_TIMEOUT);
121121
});
122-
const executePromise = client.execute(() => {
122+
const executePromise = (client as WebdriverIO.Browser).execute(() => {
123123
return document.readyState === 'complete';
124124
});
125125
const readyState = await Promise.race([timeoutPromise, executePromise]);
@@ -130,13 +130,13 @@ async function assertFrameReady(client: Browser): Promise<void> {
130130
}
131131

132132
export const axeRunPartial = (
133-
client: Browser,
133+
client: WdioBrowser,
134134
context?: SerialContextObject,
135135
options?: RunOptions
136136
): Promise<PartialResult> => {
137137
return promisify(
138-
client
139-
.executeAsync<string, []>(
138+
(client as WebdriverIO.Browser)
139+
.executeAsync(
140140
`
141141
var callback = arguments[arguments.length - 1];
142142
var context = ${JSON.stringify(context)} || document;
@@ -145,20 +145,20 @@ export const axeRunPartial = (
145145
callback(JSON.stringify(partials))
146146
});`
147147
)
148-
.then((r: string) => deserialize<PartialResult>(r))
148+
.then(r => deserialize<PartialResult>(r as string))
149149
);
150150
};
151151

152152
export const axeGetFrameContext = (
153-
client: Browser,
153+
client: WdioBrowser,
154154
context: SerialContextObject
155155
// TODO: add proper types
156156
// eslint-disable-next-line @typescript-eslint/no-explicit-any
157157
): Promise<any[]> => {
158158
return promisify(
159159
// Had to use executeAsync() because we could not use multiline statements in client.execute()
160160
// we were able to return a single boolean in a line but not when assigned to a variable.
161-
client.executeAsync(`
161+
(client as WebdriverIO.Browser).executeAsync(`
162162
var callback = arguments[arguments.length - 1];
163163
var context = ${JSON.stringify(context)};
164164
var frameContexts = window.axe.utils.getFrameContexts(context);
@@ -168,14 +168,14 @@ export const axeGetFrameContext = (
168168
};
169169

170170
export const axeRunLegacy = (
171-
client: Browser,
171+
client: WdioBrowser,
172172
context: SerialContextObject,
173173
options: RunOptions,
174174
config?: Spec
175175
): Promise<AxeResults> => {
176176
return promisify(
177-
client
178-
.executeAsync<string, []>(
177+
(client as WebdriverIO.Browser)
178+
.executeAsync(
179179
`var callback = arguments[arguments.length - 1];
180180
var context = ${JSON.stringify(context)} || document;
181181
var options = ${JSON.stringify(options)} || {};
@@ -187,12 +187,12 @@ export const axeRunLegacy = (
187187
callback(JSON.stringify(axeResults))
188188
});`
189189
)
190-
.then((r: string) => deserialize<AxeResults>(r))
190+
.then(r => deserialize<AxeResults>(r as string))
191191
);
192192
};
193193

194194
export const axeFinishRun = (
195-
client: Browser,
195+
client: WdioBrowser,
196196
axeSource: string,
197197
partialResults: PartialResults,
198198
options: RunOptions
@@ -207,7 +207,7 @@ export const axeFinishRun = (
207207
function chunkResults(result: string): Promise<void> {
208208
const chunk = JSON.stringify(result.substring(0, sizeLimit));
209209
return promisify(
210-
client.execute(
210+
(client as WebdriverIO.Browser).execute(
211211
`
212212
window.partialResults ??= '';
213213
window.partialResults += ${chunk};
@@ -223,7 +223,7 @@ export const axeFinishRun = (
223223
return chunkResults(partialString)
224224
.then(() => {
225225
return promisify(
226-
client.executeAsync<string, []>(
226+
(client as WebdriverIO.Browser).executeAsync(
227227
`var callback = arguments[arguments.length - 1];
228228
${axeSource};
229229
window.axe.configure({
@@ -238,12 +238,12 @@ export const axeFinishRun = (
238238
)
239239
);
240240
})
241-
.then((r: string) => deserialize<AxeResults>(r));
241+
.then(r => deserialize<AxeResults>(r as string));
242242
};
243243

244-
export const configureAllowedOrigins = (client: Browser): Promise<void> => {
244+
export const configureAllowedOrigins = (client: WdioBrowser): Promise<void> => {
245245
return promisify(
246-
client.execute(`
246+
(client as WebdriverIO.Browser).execute(`
247247
window.axe.configure({ allowedOrigins: ['<unsafe_all_origins>'] })
248248
`)
249249
);

packages/webdriverio/test/axe-webdriverio.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ describe('@axe-core/webdriverio', () => {
7171
describe(`WebdriverIO Async (${protocol} protocol)`, () => {
7272
let server: Server;
7373
let addr: string;
74-
let client: webdriverio.Browser;
74+
let client: WebdriverIO.Browser;
7575
const axePath = require.resolve('axe-core');
7676
const axeSource = fs.readFileSync(axePath, 'utf8');
7777
const axeLegacySource = fs.readFileSync(

packages/webdriverio/tsconfig.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"extends": "../../tsconfig.json",
3+
"compilerOptions": {
4+
"types": ["node", "mocha", "@wdio/globals/types"]
5+
},
36
"include": ["src"],
47
"exclude": ["test"]
58
}

test/wdio/package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
"@axe-core/webdriverio": "^4.8.2",
1010
"@types/chai": "^4.3.9",
1111
"@types/mocha": "^10.0.3",
12-
"@wdio/cli": "^8.20.2",
13-
"@wdio/globals": "^8.20.0",
14-
"@wdio/local-runner": "^8.20.0",
15-
"@wdio/mocha-framework": "^8.20.0",
16-
"@wdio/spec-reporter": "^8.20.0",
12+
"@wdio/cli": "^8.27.0",
13+
"@wdio/globals": "^8.27.0",
14+
"@wdio/local-runner": "^8.27.0",
15+
"@wdio/mocha-framework": "^8.27.0",
16+
"@wdio/spec-reporter": "^8.27.0",
1717
"async-listen": "^3.0.1",
1818
"axe-test-fixtures": "github:dequelabs/axe-test-fixtures#v1",
1919
"chai": "^4.3.10",

0 commit comments

Comments
 (0)