@wdio/browser-runner 8.27.0 → 8.28.0
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/build/browser/driver.d.ts.map +1 -1
- package/build/browser/driver.js +85 -66
- package/build/browser/expect.d.ts +3 -0
- package/build/browser/expect.d.ts.map +1 -0
- package/build/browser/expect.js +88 -0
- package/build/browser/frameworks/mocha.d.ts +1 -1
- package/build/browser/frameworks/mocha.d.ts.map +1 -1
- package/build/browser/frameworks/mocha.js +15 -20
- package/build/browser/setup.d.ts +1 -3
- package/build/browser/setup.d.ts.map +1 -1
- package/build/browser/setup.js +3 -13
- package/build/communicator.d.ts +11 -0
- package/build/communicator.d.ts.map +1 -0
- package/build/communicator.js +82 -0
- package/build/constants.d.ts +1 -8
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +1 -9
- package/build/index.d.ts +4 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +15 -55
- package/build/vite/constants.d.ts.map +1 -1
- package/build/vite/constants.js +3 -4
- package/build/vite/plugins/testrunner.d.ts.map +1 -1
- package/build/vite/plugins/testrunner.js +23 -5
- package/build/vite/plugins/worker.d.ts +8 -0
- package/build/vite/plugins/worker.d.ts.map +1 -0
- package/build/vite/plugins/worker.js +12 -0
- package/build/vite/server.d.ts +5 -5
- package/build/vite/server.d.ts.map +1 -1
- package/build/vite/server.js +14 -164
- package/build/vite/types.d.ts +0 -43
- package/build/vite/types.d.ts.map +1 -1
- package/build/vite/utils.d.ts.map +1 -1
- package/build/vite/utils.js +2 -3
- package/package.json +15 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/browser/driver.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"driver.d.ts","sourceRoot":"","sources":["../../src/browser/driver.ts"],"names":[],"mappings":"AAqBA,MAAM,CAAC,OAAO,OAAO,WAAW;;IAG5B,MAAM,CAAC,UAAU,CACb,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,KAAK,EACf,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,EACjD,cAAc,EAAE,GAAG;CAoL1B"}
|
package/build/browser/driver.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import stringify from 'fast-safe-stringify';
|
|
2
1
|
import { commands } from 'virtual:wdio';
|
|
3
2
|
import { webdriverMonad, sessionEnvironmentDetector } from '@wdio/utils';
|
|
4
3
|
import { getEnvironmentVars } from 'webdriver';
|
|
4
|
+
import { MESSAGE_TYPES } from '@wdio/types';
|
|
5
|
+
import { browser } from '@wdio/globals';
|
|
5
6
|
import { getCID } from './utils.js';
|
|
6
|
-
import {
|
|
7
|
+
import { WDIO_EVENT_NAME } from '../constants.js';
|
|
7
8
|
const COMMAND_TIMEOUT = 30 * 1000; // 30s
|
|
8
9
|
const CONSOLE_METHODS = ['log', 'info', 'warn', 'error', 'debug'];
|
|
9
10
|
const HIDE_REPORTER_FOR_COMMANDS = ['saveScreenshot', 'savePDF'];
|
|
10
11
|
const mochaFramework = document.querySelector('mocha-framework');
|
|
12
|
+
let id = 0;
|
|
11
13
|
export default class ProxyDriver {
|
|
12
14
|
static #commandMessages = new Map();
|
|
13
15
|
static newSession(params, modifier, userPrototype, commandWrapper) {
|
|
@@ -18,49 +20,22 @@ export default class ProxyDriver {
|
|
|
18
20
|
/**
|
|
19
21
|
* log all console events once connected
|
|
20
22
|
*/
|
|
21
|
-
|
|
22
|
-
connectPromise.then(this.#wrapConsolePrototype.bind(this, cid));
|
|
23
|
+
this.#wrapConsolePrototype(cid);
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
+
* listen on socket events from testrunner
|
|
25
26
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
import.meta.hot?.on(WDIO_EVENT_NAME, this.#handleServerMessage.bind(this));
|
|
28
|
+
import.meta.hot?.send(WDIO_EVENT_NAME, {
|
|
29
|
+
type: MESSAGE_TYPES.initiateBrowserStateRequest,
|
|
30
|
+
value: { cid }
|
|
31
|
+
});
|
|
29
32
|
const environment = sessionEnvironmentDetector({ capabilities: params.capabilities, requestedCapabilities: {} });
|
|
30
33
|
const environmentPrototype = getEnvironmentVars(environment);
|
|
31
34
|
// have debug command
|
|
32
35
|
const commandsProcessedInNodeWorld = [...commands, 'debug', 'saveScreenshot', 'savePDF'];
|
|
33
36
|
const protocolCommands = commandsProcessedInNodeWorld.reduce((prev, commandName) => {
|
|
34
|
-
const isDebugCommand = commandName === 'debug';
|
|
35
37
|
prev[commandName] = {
|
|
36
|
-
value:
|
|
37
|
-
if (socket.readyState !== 1) {
|
|
38
|
-
await connectPromise;
|
|
39
|
-
}
|
|
40
|
-
commandId++;
|
|
41
|
-
/**
|
|
42
|
-
* print information which command is executed (except for debug commands)
|
|
43
|
-
*/
|
|
44
|
-
console.log(...(isDebugCommand
|
|
45
|
-
? ['[WDIO] %cDebug Mode Enabled', 'background: #ea5906; color: #fff; padding: 3px; border-radius: 5px;']
|
|
46
|
-
: [`[WDIO] ${(new Date()).toISOString()} - id: ${commandId} - COMMAND: ${commandName}(${args.join(', ')})`]));
|
|
47
|
-
if (HIDE_REPORTER_FOR_COMMANDS.includes(commandName) && mochaFramework) {
|
|
48
|
-
mochaFramework.setAttribute('style', 'display: none');
|
|
49
|
-
}
|
|
50
|
-
socket.send(JSON.stringify(this.#commandRequest({
|
|
51
|
-
commandName,
|
|
52
|
-
cid,
|
|
53
|
-
id: commandId.toString(),
|
|
54
|
-
args
|
|
55
|
-
})));
|
|
56
|
-
return new Promise((resolve, reject) => {
|
|
57
|
-
let commandTimeout;
|
|
58
|
-
if (!isDebugCommand) {
|
|
59
|
-
commandTimeout = setTimeout(() => reject(new Error(`Command "${commandName}" timed out`)), COMMAND_TIMEOUT);
|
|
60
|
-
}
|
|
61
|
-
this.#commandMessages.set(commandId.toString(), { resolve, reject, commandTimeout, commandName });
|
|
62
|
-
});
|
|
63
|
-
}
|
|
38
|
+
value: this.#getMockedCommand(cid, commandName)
|
|
64
39
|
};
|
|
65
40
|
return prev;
|
|
66
41
|
}, {});
|
|
@@ -89,48 +64,92 @@ export default class ProxyDriver {
|
|
|
89
64
|
const monad = webdriverMonad(params, modifier, prototype);
|
|
90
65
|
return monad(window.__wdioEnv__.sessionId, commandWrapper);
|
|
91
66
|
}
|
|
92
|
-
static #
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
}
|
|
98
|
-
if (!value.id) {
|
|
99
|
-
return console.error(`Message without id: ${JSON.stringify(ev.data)}`);
|
|
100
|
-
}
|
|
101
|
-
const commandMessage = this.#commandMessages.get(value.id);
|
|
102
|
-
if (!commandMessage) {
|
|
103
|
-
return console.error(`Unknown command id "${value.id}"`);
|
|
67
|
+
static #getMockedCommand(cid, commandName) {
|
|
68
|
+
const isDebugCommand = commandName === 'debug';
|
|
69
|
+
return async (...args) => {
|
|
70
|
+
if (!import.meta.hot) {
|
|
71
|
+
throw new Error('Could not connect to testrunner');
|
|
104
72
|
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
if (
|
|
113
|
-
|
|
73
|
+
id++;
|
|
74
|
+
/**
|
|
75
|
+
* print information which command is executed (except for debug commands)
|
|
76
|
+
*/
|
|
77
|
+
console.log(...(isDebugCommand
|
|
78
|
+
? ['[WDIO] %cDebug Mode Enabled', 'background: #ea5906; color: #fff; padding: 3px; border-radius: 5px;']
|
|
79
|
+
: [`[WDIO] ${(new Date()).toISOString()} - id: ${id} - COMMAND: ${commandName}(${args.join(', ')})`]));
|
|
80
|
+
if (HIDE_REPORTER_FOR_COMMANDS.includes(commandName) && mochaFramework) {
|
|
81
|
+
mochaFramework.setAttribute('style', 'display: none');
|
|
114
82
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
83
|
+
import.meta.hot.send(WDIO_EVENT_NAME, this.#commandRequest({
|
|
84
|
+
commandName,
|
|
85
|
+
cid,
|
|
86
|
+
id,
|
|
87
|
+
args
|
|
88
|
+
}));
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
let commandTimeout;
|
|
91
|
+
if (!isDebugCommand) {
|
|
92
|
+
commandTimeout = setTimeout(() => reject(new Error(`Command "${commandName}" timed out`)), COMMAND_TIMEOUT);
|
|
93
|
+
}
|
|
94
|
+
this.#commandMessages.set(id, { resolve, reject, commandTimeout, commandName });
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
static #handleServerMessage(payload) {
|
|
99
|
+
if (payload.type === MESSAGE_TYPES.commandResponseMessage) {
|
|
100
|
+
return this.#handleCommandResponse(payload.value);
|
|
101
|
+
}
|
|
102
|
+
if (payload.type === MESSAGE_TYPES.initiateBrowserStateResponse) {
|
|
103
|
+
return this.#handleBrowserInitiation(payload.value);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
static #handleCommandResponse(value) {
|
|
107
|
+
if (!value.id) {
|
|
108
|
+
return console.error(`Message without id: ${JSON.stringify(value)}`);
|
|
109
|
+
}
|
|
110
|
+
const commandMessage = this.#commandMessages.get(value.id);
|
|
111
|
+
if (!commandMessage) {
|
|
112
|
+
return console.error(`Unknown command id "${value.id}"`);
|
|
113
|
+
}
|
|
114
|
+
if (HIDE_REPORTER_FOR_COMMANDS.includes(commandMessage.commandName) && mochaFramework) {
|
|
115
|
+
mochaFramework.removeAttribute('style');
|
|
116
|
+
}
|
|
117
|
+
if (value.error) {
|
|
118
|
+
console.log(`[WDIO] ${(new Date()).toISOString()} - id: ${value.id} - ERROR: ${JSON.stringify(value.error.message)}`);
|
|
119
|
+
return commandMessage.reject(new Error(value.error.message || 'unknown error'));
|
|
120
|
+
}
|
|
121
|
+
if (commandMessage.commandTimeout) {
|
|
122
|
+
clearTimeout(commandMessage.commandTimeout);
|
|
123
|
+
}
|
|
124
|
+
console.log(`[WDIO] ${(new Date()).toISOString()} - id: ${value.id} - RESULT: ${JSON.stringify(value.result)}`);
|
|
125
|
+
commandMessage.resolve(value.result);
|
|
126
|
+
this.#commandMessages.delete(value.id);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Initiate browser states even in case page loads happen. This is necessary so we can
|
|
130
|
+
* add a custom command that was added in the Node.js environment to the browser scope
|
|
131
|
+
* within the browser so the instance is aware of it and can translate the command
|
|
132
|
+
* request back to the worker process
|
|
133
|
+
*/
|
|
134
|
+
static #handleBrowserInitiation(value) {
|
|
135
|
+
const cid = getCID();
|
|
136
|
+
if (!cid) {
|
|
137
|
+
return;
|
|
118
138
|
}
|
|
119
|
-
|
|
120
|
-
|
|
139
|
+
for (const commandName of value.customCommands) {
|
|
140
|
+
browser.addCommand(commandName, this.#getMockedCommand(cid, commandName));
|
|
121
141
|
}
|
|
122
142
|
}
|
|
123
143
|
static #wrapConsolePrototype(cid) {
|
|
124
|
-
const socket = window.__wdioSocket__;
|
|
125
144
|
for (const method of CONSOLE_METHODS) {
|
|
126
145
|
const origCommand = console[method].bind(console);
|
|
127
146
|
console[method] = (...args) => {
|
|
128
|
-
|
|
147
|
+
import.meta.hot?.send(WDIO_EVENT_NAME, this.#consoleMessage({
|
|
129
148
|
name: 'consoleEvent',
|
|
130
149
|
type: method,
|
|
131
150
|
args,
|
|
132
151
|
cid
|
|
133
|
-
}))
|
|
152
|
+
}));
|
|
134
153
|
origCommand(...args);
|
|
135
154
|
};
|
|
136
155
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expect.d.ts","sourceRoot":"","sources":["../../src/browser/expect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAA2E,MAAM,QAAQ,CAAA;AAkHxG,OAAO,EAAE,MAAM,EAAE,CAAA"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { expect } from 'expect';
|
|
2
|
+
import { MESSAGE_TYPES } from '@wdio/types';
|
|
3
|
+
import { matchers } from 'virtual:wdio';
|
|
4
|
+
import { $ } from '@wdio/globals';
|
|
5
|
+
import { getCID } from './utils.js';
|
|
6
|
+
import { WDIO_EVENT_NAME } from '../constants.js';
|
|
7
|
+
const asymmetricMatcher = typeof Symbol === 'function' && Symbol.for
|
|
8
|
+
? Symbol.for('jest.asymmetricMatcher')
|
|
9
|
+
: 1267621;
|
|
10
|
+
let matcherRequestCount = 0;
|
|
11
|
+
const matcherRequests = new Map();
|
|
12
|
+
const COMMAND_TIMEOUT = 30 * 1000; // 30s
|
|
13
|
+
/**
|
|
14
|
+
* Set up expect-webdriverio matchers for the browser environment.
|
|
15
|
+
* Every assertion is send to the testrunner via a websocket connection
|
|
16
|
+
* and is executed in the Node.js environment. This allows us to enable
|
|
17
|
+
* matchers that require Node.js specific modules like `fs` or `child_process`,
|
|
18
|
+
* for visual regression or snapshot testing for example.
|
|
19
|
+
*/
|
|
20
|
+
expect.extend(matchers.reduce((acc, matcherName) => {
|
|
21
|
+
acc[matcherName] = async function (context, ...args) {
|
|
22
|
+
const cid = getCID();
|
|
23
|
+
if (!import.meta.hot || !cid) {
|
|
24
|
+
return {
|
|
25
|
+
pass: false,
|
|
26
|
+
message: () => 'Could not connect to testrunner'
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (typeof args[0] === 'object' && '$$typeof' in args[0] && args[0].$$typeof === asymmetricMatcher && args[0].asymmetricMatch) {
|
|
30
|
+
args[0] = {
|
|
31
|
+
$$typeof: args[0].toString(),
|
|
32
|
+
sample: args[0].sample,
|
|
33
|
+
inverse: args[0].inverse
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const expectRequest = {
|
|
37
|
+
id: matcherRequestCount++,
|
|
38
|
+
cid,
|
|
39
|
+
scope: this,
|
|
40
|
+
matcherName,
|
|
41
|
+
args: args
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Check if context is an WebdriverIO.Element
|
|
45
|
+
*/
|
|
46
|
+
if ('elementId' in context && typeof context.elementId === 'string') {
|
|
47
|
+
expectRequest.element = context;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Check if context is ChainablePromiseElement
|
|
51
|
+
*/
|
|
52
|
+
if ('then' in context && typeof context.selector === 'object') {
|
|
53
|
+
expectRequest.element = await context;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if context is a `Element` and transtform it into a WebdriverIO.Element
|
|
57
|
+
*/
|
|
58
|
+
if (context instanceof Element) {
|
|
59
|
+
expectRequest.element = await $(context);
|
|
60
|
+
}
|
|
61
|
+
import.meta.hot.send(WDIO_EVENT_NAME, { type: MESSAGE_TYPES.expectRequestMessage, value: expectRequest });
|
|
62
|
+
const contextString = 'elementId' in context ? 'WebdriverIO.Element' : 'WebdriverIO.Browser';
|
|
63
|
+
return new Promise((resolve, reject) => {
|
|
64
|
+
const commandTimeout = setTimeout(() => reject(new Error(`Assertion expect(${contextString}).${matcherName}(...) timed out`)), COMMAND_TIMEOUT);
|
|
65
|
+
matcherRequests.set(expectRequest.id, { resolve, commandTimeout });
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
return acc;
|
|
69
|
+
}, {}));
|
|
70
|
+
/**
|
|
71
|
+
* listen on assertion results from testrunner
|
|
72
|
+
*/
|
|
73
|
+
import.meta.hot?.on(WDIO_EVENT_NAME, (message) => {
|
|
74
|
+
if (message.type !== MESSAGE_TYPES.expectResponseMessage) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const payload = matcherRequests.get(message.value.id);
|
|
78
|
+
if (!payload) {
|
|
79
|
+
return console.warn(`Couldn't find payload for assertion result with id ${message.value.id}`);
|
|
80
|
+
}
|
|
81
|
+
clearTimeout(payload.commandTimeout);
|
|
82
|
+
matcherRequests.delete(message.value.id);
|
|
83
|
+
payload.resolve({
|
|
84
|
+
pass: message.value.pass,
|
|
85
|
+
message: () => message.value.message
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
export { expect };
|
|
@@ -5,6 +5,6 @@ export declare class MochaFramework extends HTMLElement {
|
|
|
5
5
|
get spec(): string;
|
|
6
6
|
connectedCallback(): void;
|
|
7
7
|
attributeChangedCallback(name: string, oldValue: unknown, newValue: unknown): void;
|
|
8
|
-
run(
|
|
8
|
+
run(): Promise<void>;
|
|
9
9
|
}
|
|
10
10
|
//# sourceMappingURL=mocha.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mocha.d.ts","sourceRoot":"","sources":["../../../src/browser/frameworks/mocha.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mocha.d.ts","sourceRoot":"","sources":["../../../src/browser/frameworks/mocha.ts"],"names":[],"mappings":"AA6BA,qBAAa,cAAe,SAAQ,WAAW;;;IAyB3C,MAAM,KAAK,kBAAkB,aAE5B;IAED,IAAI,IAAI,WAEP;IAED,iBAAiB;IAWjB,wBAAwB,CAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO;IAatE,GAAG;CAgIZ"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import safeStringify from 'safe-stringify';
|
|
2
2
|
import { setupEnv, formatMessage } from '@wdio/mocha-framework/common';
|
|
3
|
+
import { MESSAGE_TYPES } from '@wdio/types';
|
|
3
4
|
import { getCID } from '../utils.js';
|
|
4
|
-
import {
|
|
5
|
+
import { EVENTS, WDIO_EVENT_NAME } from '../../constants.js';
|
|
5
6
|
const startTime = Date.now();
|
|
6
7
|
if (!window.Mocha) {
|
|
7
8
|
throw new Error('Can\'t find Mocha attached to the `window` scope, was it installed? Run `npm install mocha` and run again!');
|
|
@@ -23,7 +24,6 @@ class HTMLReporter extends BaseReporter {
|
|
|
23
24
|
export class MochaFramework extends HTMLElement {
|
|
24
25
|
#root;
|
|
25
26
|
#spec;
|
|
26
|
-
#socket;
|
|
27
27
|
#require;
|
|
28
28
|
#hookResolver = new Map();
|
|
29
29
|
#runnerEvents = [];
|
|
@@ -69,7 +69,7 @@ export class MochaFramework extends HTMLElement {
|
|
|
69
69
|
document.body.style.width = `calc(100% - ${this.#isMinified ? '65px' : '500px'})`;
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
|
-
async run(
|
|
72
|
+
async run() {
|
|
73
73
|
const globalTeardownScripts = [];
|
|
74
74
|
const globalSetupScripts = [];
|
|
75
75
|
for (const r of this.#require) {
|
|
@@ -92,8 +92,10 @@ export class MochaFramework extends HTMLElement {
|
|
|
92
92
|
for (const setupScript of globalSetupScripts) {
|
|
93
93
|
await setupScript();
|
|
94
94
|
}
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
/**
|
|
96
|
+
* listen on socket events from testrunner
|
|
97
|
+
*/
|
|
98
|
+
import.meta.hot?.on(WDIO_EVENT_NAME, this.#handleSocketMessage.bind(this));
|
|
97
99
|
const cid = getCID();
|
|
98
100
|
if (!cid) {
|
|
99
101
|
throw new Error('"cid" query parameter is missing');
|
|
@@ -145,16 +147,9 @@ export class MochaFramework extends HTMLElement {
|
|
|
145
147
|
window.__wdioFailures__ = failures;
|
|
146
148
|
console.log(`[WDIO] Finished test suite in ${Date.now() - startTime}ms`);
|
|
147
149
|
}
|
|
148
|
-
#handleSocketMessage(
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (message.type === MESSAGE_TYPES.hookResultMessage) {
|
|
152
|
-
return this.#handleHookResult(message.value);
|
|
153
|
-
}
|
|
154
|
-
// no-op
|
|
155
|
-
}
|
|
156
|
-
catch (err) {
|
|
157
|
-
console.error(`Failed handling message from Vite server: ${err.stack}`);
|
|
150
|
+
#handleSocketMessage(message) {
|
|
151
|
+
if (message.type === MESSAGE_TYPES.hookResultMessage) {
|
|
152
|
+
return this.#handleHookResult(message.value);
|
|
158
153
|
}
|
|
159
154
|
}
|
|
160
155
|
#handleHookResult(result) {
|
|
@@ -170,19 +165,19 @@ export class MochaFramework extends HTMLElement {
|
|
|
170
165
|
}
|
|
171
166
|
#getHook(name) {
|
|
172
167
|
return (...args) => new Promise((resolve, reject) => {
|
|
173
|
-
const id =
|
|
168
|
+
const id = this.#hookResolver.size + 1;
|
|
174
169
|
const cid = getCID();
|
|
175
170
|
if (!cid) {
|
|
176
171
|
return reject(new Error('"cid" query parameter is missing'));
|
|
177
172
|
}
|
|
178
|
-
this.#hookResolver.set(id
|
|
179
|
-
|
|
173
|
+
this.#hookResolver.set(id, { resolve, reject });
|
|
174
|
+
import.meta.hot?.send(WDIO_EVENT_NAME, this.#hookTrigger({ name, id, cid, args }));
|
|
180
175
|
});
|
|
181
176
|
}
|
|
182
177
|
#hookTrigger(value) {
|
|
183
178
|
return {
|
|
184
179
|
type: MESSAGE_TYPES.hookTriggerMessage,
|
|
185
|
-
value
|
|
180
|
+
value: JSON.parse(safeStringify(value))
|
|
186
181
|
};
|
|
187
182
|
}
|
|
188
183
|
}
|
package/build/browser/setup.d.ts
CHANGED
|
@@ -3,16 +3,14 @@ type WDIOErrorEvent = Pick<ErrorEvent, 'filename' | 'message'>;
|
|
|
3
3
|
declare global {
|
|
4
4
|
interface Window {
|
|
5
5
|
Mocha?: any;
|
|
6
|
+
WDIO_EVENT_NAME: string;
|
|
6
7
|
__wdioErrors__: WDIOErrorEvent[];
|
|
7
8
|
__wdioSpec__: string;
|
|
8
9
|
__wdioFailures__: number;
|
|
9
10
|
__wdioEvents__: any[];
|
|
10
|
-
__wdioSocket__: WebSocket;
|
|
11
11
|
__wdioConnectPromise__: Promise<WebSocket>;
|
|
12
12
|
__wdioMockCache__: Map<string, any>;
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
|
-
export declare const socket: WebSocket;
|
|
16
|
-
export declare const connectPromise: Promise<WebSocket>;
|
|
17
15
|
export {};
|
|
18
16
|
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/browser/setup.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/browser/setup.ts"],"names":[],"mappings":"AAOA,OAAO,uBAAuB,CAAA;AAI9B,KAAK,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC,CAAA;AAC9D,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,KAAK,CAAC,EAAE,GAAG,CAAA;QACX,eAAe,EAAE,MAAM,CAAA;QACvB,cAAc,EAAE,cAAc,EAAE,CAAA;QAChC,YAAY,EAAE,MAAM,CAAA;QACpB,gBAAgB,EAAE,MAAM,CAAA;QACxB,cAAc,EAAE,GAAG,EAAE,CAAA;QACrB,sBAAsB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;QAC1C,iBAAiB,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KACtC;CACJ"}
|
package/build/browser/setup.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="vite/client" />
|
|
1
2
|
import { automationProtocolPath } from 'virtual:wdio';
|
|
2
3
|
import { expect } from 'expect-webdriverio';
|
|
3
4
|
import { remote } from 'webdriverio';
|
|
@@ -7,16 +8,6 @@ import { showPopupWarning } from './utils.js';
|
|
|
7
8
|
globalThis.alert = showPopupWarning('alert', undefined);
|
|
8
9
|
globalThis.confirm = showPopupWarning('confirm', false, true);
|
|
9
10
|
globalThis.prompt = showPopupWarning('prompt', null, 'your value');
|
|
10
|
-
/**
|
|
11
|
-
* create connection to Vite server
|
|
12
|
-
*/
|
|
13
|
-
const wsUrl = 'ws://' + window.location.host + '/ws';
|
|
14
|
-
console.log(`[WDIO] Connect to testrunner: ${wsUrl}`);
|
|
15
|
-
export const socket = window.__wdioSocket__ = new WebSocket(wsUrl);
|
|
16
|
-
export const connectPromise = window.__wdioConnectPromise__ = new Promise((resolve) => {
|
|
17
|
-
console.log('[WDIO] Connected to testrunner');
|
|
18
|
-
socket.addEventListener('open', () => resolve(socket));
|
|
19
|
-
});
|
|
20
11
|
/**
|
|
21
12
|
* Setup fake browser instance and attach to global scope if necessary
|
|
22
13
|
*/
|
|
@@ -30,12 +21,11 @@ _setGlobal('expect', expect, window.__wdioEnv__.injectGlobals);
|
|
|
30
21
|
_setGlobal('$', browser.$.bind(browser), window.__wdioEnv__.injectGlobals);
|
|
31
22
|
_setGlobal('$$', browser.$$.bind(browser), window.__wdioEnv__.injectGlobals);
|
|
32
23
|
/**
|
|
33
|
-
* run framework
|
|
24
|
+
* run framework immediately on page load
|
|
34
25
|
*/
|
|
35
26
|
const mochaFramework = document.querySelector('mocha-framework');
|
|
36
27
|
if (mochaFramework) {
|
|
37
|
-
|
|
38
|
-
mochaFramework.run(socket).catch((err) => {
|
|
28
|
+
mochaFramework.run().catch((err) => {
|
|
39
29
|
/**
|
|
40
30
|
* On MacOS importing the spec file might fail with a null error object.
|
|
41
31
|
* This is Vite doing a hot reload and the error is not relevant for us.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CoverageMap } from 'istanbul-lib-coverage';
|
|
2
|
+
import type { WorkerInstance } from '@wdio/local-runner';
|
|
3
|
+
import { type Options } from '@wdio/types';
|
|
4
|
+
import type { ViteServer } from './vite/server.js';
|
|
5
|
+
export declare class ServerWorkerCommunicator {
|
|
6
|
+
#private;
|
|
7
|
+
coverageMaps: CoverageMap[];
|
|
8
|
+
constructor(config: Options.Testrunner);
|
|
9
|
+
register(server: ViteServer, worker: WorkerInstance): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=communicator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"communicator.d.ts","sourceRoot":"","sources":["../src/communicator.ts"],"names":[],"mappings":"AACA,OAAoB,EAAE,KAAK,WAAW,EAAwB,MAAM,uBAAuB,CAAA;AAI3F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAiB,KAAK,OAAO,EAAgB,MAAM,aAAa,CAAA;AAKvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAWlD,qBAAa,wBAAwB;;IAe1B,YAAY,EAAE,WAAW,EAAE,CAAK;gBAE1B,MAAM,EAAE,OAAO,CAAC,UAAU;IAIvC,QAAQ,CAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc;CAmEvD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import libSourceMap from 'istanbul-lib-source-maps';
|
|
2
|
+
import libCoverage from 'istanbul-lib-coverage';
|
|
3
|
+
import logger from '@wdio/logger';
|
|
4
|
+
import { MESSAGE_TYPES } from '@wdio/types';
|
|
5
|
+
import { SESSIONS } from './constants.js';
|
|
6
|
+
import { WDIO_EVENT_NAME } from './constants.js';
|
|
7
|
+
const log = logger('@wdio/browser-runner');
|
|
8
|
+
export class ServerWorkerCommunicator {
|
|
9
|
+
#mapStore = libSourceMap.createSourceMapStore();
|
|
10
|
+
#config;
|
|
11
|
+
#msgId = 0;
|
|
12
|
+
/**
|
|
13
|
+
* keep track of custom commands per session
|
|
14
|
+
*/
|
|
15
|
+
#customCommands = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* keep track of request/response messages on browser/worker level
|
|
18
|
+
*/
|
|
19
|
+
#pendingMessages = new Map();
|
|
20
|
+
coverageMaps = [];
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.#config = config;
|
|
23
|
+
}
|
|
24
|
+
register(server, worker) {
|
|
25
|
+
server.onBrowserEvent((data, client) => this.#onBrowserEvent(data, client, worker));
|
|
26
|
+
worker.on('message', this.#onWorkerMessage.bind(this));
|
|
27
|
+
}
|
|
28
|
+
async #onWorkerMessage(payload) {
|
|
29
|
+
if (payload.name === 'sessionStarted' && !SESSIONS.has(payload.cid)) {
|
|
30
|
+
SESSIONS.set(payload.cid, {
|
|
31
|
+
args: this.#config.mochaOpts || {},
|
|
32
|
+
config: this.#config,
|
|
33
|
+
capabilities: payload.content.capabilities,
|
|
34
|
+
sessionId: payload.content.sessionId,
|
|
35
|
+
injectGlobals: payload.content.injectGlobals
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
if (payload.name === 'sessionEnded') {
|
|
39
|
+
SESSIONS.delete(payload.cid);
|
|
40
|
+
}
|
|
41
|
+
if (payload.name === 'workerEvent' && payload.args.type === MESSAGE_TYPES.coverageMap) {
|
|
42
|
+
const coverageMapData = payload.args.value;
|
|
43
|
+
this.coverageMaps.push(await this.#mapStore.transformCoverage(libCoverage.createCoverageMap(coverageMapData)));
|
|
44
|
+
}
|
|
45
|
+
if (payload.name === 'workerEvent' && payload.args.type === MESSAGE_TYPES.customCommand) {
|
|
46
|
+
const { commandName, cid } = payload.args.value;
|
|
47
|
+
if (!this.#customCommands.has(cid)) {
|
|
48
|
+
this.#customCommands.set(cid, new Set());
|
|
49
|
+
}
|
|
50
|
+
const customCommands = this.#customCommands.get(cid) || new Set();
|
|
51
|
+
customCommands.add(commandName);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
if (payload.name === 'workerResponse') {
|
|
55
|
+
const msg = this.#pendingMessages.get(payload.args.id);
|
|
56
|
+
if (!msg) {
|
|
57
|
+
return log.error(`Couldn't find message with id ${payload.args.id} from type ${payload.args.message.type}`);
|
|
58
|
+
}
|
|
59
|
+
this.#pendingMessages.delete(payload.args.id);
|
|
60
|
+
return msg.client.send(WDIO_EVENT_NAME, payload.args.message);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
#onBrowserEvent(message, client, worker) {
|
|
64
|
+
/**
|
|
65
|
+
* some browser events don't need to go through the worker process
|
|
66
|
+
*/
|
|
67
|
+
if (message.type === MESSAGE_TYPES.initiateBrowserStateRequest) {
|
|
68
|
+
const result = {
|
|
69
|
+
type: MESSAGE_TYPES.initiateBrowserStateResponse,
|
|
70
|
+
value: {
|
|
71
|
+
customCommands: [...(this.#customCommands.get(message.value.cid) || [])]
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
return client.send(WDIO_EVENT_NAME, result);
|
|
75
|
+
}
|
|
76
|
+
const id = this.#msgId++;
|
|
77
|
+
const msg = { id, client };
|
|
78
|
+
this.#pendingMessages.set(id, msg);
|
|
79
|
+
const args = { id, message };
|
|
80
|
+
return worker.postMessage('workerRequest', args, true);
|
|
81
|
+
}
|
|
82
|
+
}
|
package/build/constants.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Environment } from './types.js';
|
|
2
2
|
import type { ReportOptions } from 'istanbul-reports';
|
|
3
3
|
export declare const SESSIONS: Map<string, Environment>;
|
|
4
|
-
export declare const
|
|
4
|
+
export declare const WDIO_EVENT_NAME = "wdio:workerMessage";
|
|
5
5
|
export declare const EVENTS: {
|
|
6
6
|
readonly suite: "suite:start";
|
|
7
7
|
readonly 'suite end': "suite:end";
|
|
@@ -15,13 +15,6 @@ export declare const EVENTS: {
|
|
|
15
15
|
readonly pending: "test:pending";
|
|
16
16
|
};
|
|
17
17
|
export declare const FRAMEWORK_SUPPORT_ERROR = "Currently only \"mocha\" is supported as framework when using @wdio/browser-runner.";
|
|
18
|
-
export declare enum MESSAGE_TYPES {
|
|
19
|
-
consoleMessage = 0,
|
|
20
|
-
commandRequestMessage = 1,
|
|
21
|
-
commandResponseMessage = 2,
|
|
22
|
-
hookTriggerMessage = 3,
|
|
23
|
-
hookResultMessage = 4
|
|
24
|
-
}
|
|
25
18
|
export declare const DEFAULT_INCLUDE: string[];
|
|
26
19
|
export declare const DEFAULT_FILE_EXTENSIONS: string[];
|
|
27
20
|
export declare const DEFAULT_REPORTS_DIRECTORY = "coverage";
|
package/build/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,eAAO,MAAM,QAAQ,0BAAiC,CAAA;AACtD,eAAO,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,eAAO,MAAM,QAAQ,0BAAiC,CAAA;AACtD,eAAO,MAAM,eAAe,uBAAuB,CAAA;AAEnD,eAAO,MAAM,MAAM;;;;;;;;;;;CAWT,CAAA;AAEV,eAAO,MAAM,uBAAuB,wFAAsF,CAAA;AAE1H,eAAO,MAAM,eAAe,UAAS,CAAA;AACrC,eAAO,MAAM,uBAAuB,UAAoF,CAAA;AACxH,eAAO,MAAM,yBAAyB,aAAa,CAAA;AACnD,eAAO,MAAM,gBAAgB,OAAO,CAAA;AACpC,eAAO,MAAM,sBAAsB,cAAc,CAAA;AACjD,eAAO,MAAM,gBAAgB,iBAAiB,CAAA;AAC9C,eAAO,MAAM,gBAAgB,2DAA4D,CAAA;AACzF,eAAO,MAAM,wBAAwB,EAAE,CAAC,MAAM,aAAa,CAAC,EAAiD,CAAA;AAC7G,eAAO,MAAM,yBAAyB,sEAAsE,CAAA;AAC5G,eAAO,MAAM,uBAAuB,sEAAsE,CAAA;AAE1G,eAAO,MAAM,eAAe,irEA+D3B,CAAA"}
|
package/build/constants.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const SESSIONS = new Map();
|
|
2
|
-
export const
|
|
2
|
+
export const WDIO_EVENT_NAME = 'wdio:workerMessage';
|
|
3
3
|
export const EVENTS = {
|
|
4
4
|
'suite': 'suite:start',
|
|
5
5
|
'suite end': 'suite:end',
|
|
@@ -13,14 +13,6 @@ export const EVENTS = {
|
|
|
13
13
|
'pending': 'test:pending'
|
|
14
14
|
};
|
|
15
15
|
export const FRAMEWORK_SUPPORT_ERROR = 'Currently only "mocha" is supported as framework when using @wdio/browser-runner.';
|
|
16
|
-
export var MESSAGE_TYPES;
|
|
17
|
-
(function (MESSAGE_TYPES) {
|
|
18
|
-
MESSAGE_TYPES[MESSAGE_TYPES["consoleMessage"] = 0] = "consoleMessage";
|
|
19
|
-
MESSAGE_TYPES[MESSAGE_TYPES["commandRequestMessage"] = 1] = "commandRequestMessage";
|
|
20
|
-
MESSAGE_TYPES[MESSAGE_TYPES["commandResponseMessage"] = 2] = "commandResponseMessage";
|
|
21
|
-
MESSAGE_TYPES[MESSAGE_TYPES["hookTriggerMessage"] = 3] = "hookTriggerMessage";
|
|
22
|
-
MESSAGE_TYPES[MESSAGE_TYPES["hookResultMessage"] = 4] = "hookResultMessage";
|
|
23
|
-
})(MESSAGE_TYPES || (MESSAGE_TYPES = {}));
|
|
24
16
|
export const DEFAULT_INCLUDE = ['**'];
|
|
25
17
|
export const DEFAULT_FILE_EXTENSIONS = ['.js', '.cjs', '.mjs', '.ts', '.mts', '.cts', '.tsx', '.jsx', '.vue', '.svelte'];
|
|
26
18
|
export const DEFAULT_REPORTS_DIRECTORY = 'coverage';
|
package/build/index.d.ts
CHANGED
|
@@ -7,8 +7,11 @@ export default class BrowserRunner extends LocalRunner {
|
|
|
7
7
|
#private;
|
|
8
8
|
private options;
|
|
9
9
|
protected _config: Options.Testrunner;
|
|
10
|
-
private _coverageMaps;
|
|
11
10
|
constructor(options: BrowserRunnerOptionsImport, _config: Options.Testrunner);
|
|
11
|
+
/**
|
|
12
|
+
* for testing purposes
|
|
13
|
+
*/
|
|
14
|
+
private _servers;
|
|
12
15
|
/**
|
|
13
16
|
* nothing to initialize when running locally
|
|
14
17
|
*/
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,WAAW,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,WAAW,MAAM,oBAAoB,CAAA;AAK5C,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAU/G,OAAO,KAAK,EAAE,oBAAoB,IAAI,0BAA0B,EAAmB,qBAAqB,EAAE,MAAM,YAAY,CAAA;AAI5H,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;;IAU9C,OAAO,CAAC,OAAO;IACf,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU;gBAD7B,OAAO,EAAE,0BAA0B,EACjC,OAAO,EAAE,OAAO,CAAC,UAAU;IAwBzC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAgB;IAEhC;;OAEG;IACG,UAAU;IAsBV,GAAG,CAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC;IAuBrD;;;;OAIG;IACG,QAAQ;YAQA,wBAAwB;CA4DzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,oBAAqB,SAAQ,0BAA0B;SAAG;KACvE;CACJ;AAED;;GAEG;AACH,cAAc,aAAa,CAAA;AAE3B;;;GAGG;AAEH;;;;;;;;;;;;GAYG;AAEH,wBAAgB,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,QAAI;AAEvE;;;;GAIG;AAEH,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,QAAI;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;AACnE,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,eAAe,CAAC,CAAC,CAAC,CAAA;AACpE,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE;IACxC,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,IAAI,CAAC,EAAE,KAAK,CAAC;CAChB,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;AACnB,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE;IACxC,OAAO,CAAC,EAAE,KAAK,CAAC;IAChB,IAAI,EAAE,IAAI,CAAC;CACd,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;AACvB,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC;CAChB,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;AAC5B,wBAAgB,MAAM,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE;IACxC,OAAO,EAAE,IAAI,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;CACd,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAA"}
|