@wdio/runner 9.0.0-alpha.78 → 9.0.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.d.ts +3 -4
- package/build/browser.d.ts.map +1 -1
- package/build/index.d.ts +0 -5
- package/build/index.d.ts.map +1 -1
- package/build/index.js +874 -432
- package/build/reporter.d.ts +2 -2
- package/build/reporter.d.ts.map +1 -1
- package/build/types.d.ts +2 -10
- package/build/types.d.ts.map +1 -1
- package/build/utils.d.ts +4 -4
- package/build/utils.d.ts.map +1 -1
- package/package.json +15 -13
- package/build/browser.js +0 -385
- package/build/reporter.js +0 -192
- package/build/types.js +0 -1
- package/build/utils.js +0 -152
- /package/{LICENSE-MIT → LICENSE} +0 -0
package/build/reporter.d.ts
CHANGED
|
@@ -8,10 +8,10 @@ export default class BaseReporter {
|
|
|
8
8
|
#private;
|
|
9
9
|
private _config;
|
|
10
10
|
private _cid;
|
|
11
|
-
caps: Capabilities.
|
|
11
|
+
caps: Capabilities.RequestedStandaloneCapabilities | Capabilities.RequestedMultiremoteCapabilities;
|
|
12
12
|
private _reporters;
|
|
13
13
|
private listeners;
|
|
14
|
-
constructor(_config: Options.Testrunner, _cid: string, caps: Capabilities.
|
|
14
|
+
constructor(_config: Options.Testrunner, _cid: string, caps: Capabilities.RequestedStandaloneCapabilities | Capabilities.RequestedMultiremoteCapabilities);
|
|
15
15
|
initReporters(): Promise<void>;
|
|
16
16
|
/**
|
|
17
17
|
* emit events to all registered reporter and wdio launcer
|
package/build/reporter.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAa,MAAM,aAAa,CAAA;AAKnE;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;;IAKzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACL,IAAI,EAAE,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAa,MAAM,aAAa,CAAA;AAKnE;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;;IAKzB,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,IAAI;IACL,IAAI,EAAE,YAAY,CAAC,+BAA+B,GAAG,YAAY,CAAC,gCAAgC;IAN7G,OAAO,CAAC,UAAU,CAAmC;IACrD,OAAO,CAAC,SAAS,CAA4B;gBAGjC,OAAO,EAAE,OAAO,CAAC,UAAU,EAC3B,IAAI,EAAE,MAAM,EACb,IAAI,EAAE,YAAY,CAAC,+BAA+B,GAAG,YAAY,CAAC,gCAAgC;IAGvG,aAAa;IAMnB;;;;;OAKG;IACH,IAAI,CAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG;IAuB7B,SAAS,CAAE,QAAQ,EAAE,CAAC,EAAE,EAAE,GAAG,KAAK,IAAI;IAItC,UAAU,CAAE,IAAI,EAAE,MAAM;IAuCxB;;OAEG;IACH,oBAAoB,CAAE,QAAQ,EAAE,MAAM;yBAEc,OAAO;;IAoB3D;;;OAGG;IACH,WAAW;IA2BX;;OAEG;YACW,aAAa;CAoE9B"}
|
package/build/types.d.ts
CHANGED
|
@@ -12,23 +12,15 @@ export type RunParams = {
|
|
|
12
12
|
cid: string;
|
|
13
13
|
args: Args;
|
|
14
14
|
specs: string[];
|
|
15
|
-
caps: Capabilities.
|
|
15
|
+
caps: Capabilities.RequestedStandaloneCapabilities | Capabilities.RequestedMultiremoteCapabilities;
|
|
16
16
|
configFile: string;
|
|
17
17
|
retries: number;
|
|
18
18
|
};
|
|
19
19
|
export interface TestFramework {
|
|
20
|
-
init: (cid: string, config: Options.Testrunner, specs: string[], capabilities: Capabilities.
|
|
20
|
+
init: (cid: string, config: Options.Testrunner, specs: string[], capabilities: Capabilities.RequestedStandaloneCapabilities | Capabilities.RequestedMultiremoteCapabilities, reporter: BaseReporter) => TestFramework;
|
|
21
21
|
run(): Promise<number>;
|
|
22
22
|
hasTests(): boolean;
|
|
23
23
|
}
|
|
24
|
-
type SingleCapability = {
|
|
25
|
-
capabilities: Capabilities.RemoteCapability;
|
|
26
|
-
};
|
|
27
|
-
export interface SingleConfigOption extends Omit<Options.Testrunner, 'capabilities'>, SingleCapability {
|
|
28
|
-
}
|
|
29
|
-
export type MultiRemoteCaps = Record<string, (Capabilities.DesiredCapabilities | Capabilities.W3CCapabilities) & {
|
|
30
|
-
sessionId?: string;
|
|
31
|
-
}>;
|
|
32
24
|
export interface SessionStartedMessage {
|
|
33
25
|
origin: 'worker';
|
|
34
26
|
name: 'sessionStarted';
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAC3E,OAAO,KAAK,YAAY,MAAM,eAAe,CAAA;AAE7C,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;AAC/E,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;AAC7E,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,eAAe,CAAC,CAAC,CAAA;AAC7F,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,cAAc,CAAC,CAAC,CAAA;AAE3F,UAAU,IAAK,SAAQ,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;IAC9C,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;IAChC,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,MAAM,SAAS,GAAG;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,IAAI,CAAA;IACV,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,IAAI,EAAE,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/build/utils.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import type { Options, Capabilities } from '@wdio/types';
|
|
2
|
-
export interface ConfigWithSessionId extends
|
|
2
|
+
export interface ConfigWithSessionId extends Options.Testrunner {
|
|
3
3
|
sessionId?: string;
|
|
4
|
-
capabilities: Capabilities.
|
|
4
|
+
capabilities: Capabilities.RequestedStandaloneCapabilities;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
7
|
* sanitizes wdio config from capability properties
|
|
8
8
|
* @param {Object} caps desired session capabilities
|
|
9
9
|
* @return {Object} sanitized caps
|
|
10
10
|
*/
|
|
11
|
-
export declare function sanitizeCaps(
|
|
11
|
+
export declare function sanitizeCaps(capabilities: Capabilities.RequestedStandaloneCapabilities, filterOut?: boolean): Omit<WebdriverIO.Capabilities, 'logLevel'>;
|
|
12
12
|
/**
|
|
13
13
|
* initialize browser instance depending whether remote or multiremote is requested
|
|
14
14
|
* @param {Object} config configuration of sessions
|
|
@@ -16,7 +16,7 @@ export declare function sanitizeCaps(caps: Capabilities.RemoteCapability, filter
|
|
|
16
16
|
* @param {boolean} isMultiremote isMultiremote
|
|
17
17
|
* @return {Promise} resolves with browser object
|
|
18
18
|
*/
|
|
19
|
-
export declare function initializeInstance(config: ConfigWithSessionId, capabilities: Capabilities.
|
|
19
|
+
export declare function initializeInstance(config: ConfigWithSessionId | Options.Testrunner, capabilities: Capabilities.RequestedStandaloneCapabilities | Capabilities.RequestedMultiremoteCapabilities, isMultiremote?: boolean): Promise<WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser>;
|
|
20
20
|
/**
|
|
21
21
|
* Filter logTypes based on filter
|
|
22
22
|
* @param {string[]} excludeDriverLogs logTypes filter
|
package/build/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKxD,MAAM,WAAW,mBAAoB,SAAQ,OAAO,CAAC,UAAU;IAC3D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,YAAY,CAAC,+BAA+B,CAAA;CAC7D;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CACxB,YAAY,EAAE,YAAY,CAAC,+BAA+B,EAC1D,SAAS,CAAC,EAAE,OAAO,GACpB,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,UAAU,CAAC,CAqB5C;AAED;;;;;;GAMG;AACH,wBAAsB,kBAAkB,CACpC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,EAChD,YAAY,EAAE,YAAY,CAAC,+BAA+B,GAAG,YAAY,CAAC,gCAAgC,EAC1G,aAAa,CAAC,EAAE,OAAO,GACxB,OAAO,CAAC,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB,CAAC,CAkE/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC1B,iBAAiB,EAAE,MAAM,EAAE,EAC3B,cAAc,EAAE,MAAM,EAAE,YAa3B;AAED,KAAK,WAAW,GAAG;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,OAAO,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACtC,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAC5B,OAAO,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,kBAAkB,EAC7D,aAAa,EAAE,OAAO,oDAgBzB;AAYD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAE,GAAG,EAAE,GAAG,OAa5C"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/runner",
|
|
3
|
-
"version": "9.0.0
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"description": "A WebdriverIO service that runs tests in arbitrary environments",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-runner",
|
|
@@ -24,25 +24,27 @@
|
|
|
24
24
|
"type": "module",
|
|
25
25
|
"types": "./build/index.d.ts",
|
|
26
26
|
"exports": {
|
|
27
|
-
".":
|
|
28
|
-
|
|
27
|
+
".": {
|
|
28
|
+
"types": "./build/index.d.ts",
|
|
29
|
+
"import": "./build/index.js"
|
|
30
|
+
}
|
|
29
31
|
},
|
|
30
32
|
"typeScriptVersion": "3.8.3",
|
|
31
33
|
"dependencies": {
|
|
32
34
|
"@types/node": "^20.11.28",
|
|
33
|
-
"@wdio/config": "9.0.0
|
|
34
|
-
"@wdio/globals": "9.0.0
|
|
35
|
-
"@wdio/logger": "9.0.0
|
|
36
|
-
"@wdio/types": "9.0.0
|
|
37
|
-
"@wdio/utils": "9.0.0
|
|
38
|
-
"deepmerge-ts": "^
|
|
39
|
-
"expect-webdriverio": "
|
|
35
|
+
"@wdio/config": "9.0.0",
|
|
36
|
+
"@wdio/globals": "9.0.0",
|
|
37
|
+
"@wdio/logger": "9.0.0",
|
|
38
|
+
"@wdio/types": "9.0.0",
|
|
39
|
+
"@wdio/utils": "9.0.0",
|
|
40
|
+
"deepmerge-ts": "^7.0.3",
|
|
41
|
+
"expect-webdriverio": "5.0.0-alpha.2",
|
|
40
42
|
"gaze": "^1.1.3",
|
|
41
|
-
"webdriver": "9.0.0
|
|
42
|
-
"webdriverio": "9.0.0
|
|
43
|
+
"webdriver": "9.0.0",
|
|
44
|
+
"webdriverio": "9.0.0"
|
|
43
45
|
},
|
|
44
46
|
"publishConfig": {
|
|
45
47
|
"access": "public"
|
|
46
48
|
},
|
|
47
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "957693463371a4cb329395dcdbce8fb0c930ab93"
|
|
48
50
|
}
|
package/build/browser.js
DELETED
|
@@ -1,385 +0,0 @@
|
|
|
1
|
-
import url from 'node:url';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import logger from '@wdio/logger';
|
|
4
|
-
import { browser } from '@wdio/globals';
|
|
5
|
-
import { executeHooksWithArgs } from '@wdio/utils';
|
|
6
|
-
import { matchers } from 'expect-webdriverio';
|
|
7
|
-
import { ELEMENT_KEY } from 'webdriver';
|
|
8
|
-
import { MESSAGE_TYPES } from '@wdio/types';
|
|
9
|
-
import { transformExpectArgs } from './utils.js';
|
|
10
|
-
const log = logger('@wdio/runner');
|
|
11
|
-
const sep = '\n - ';
|
|
12
|
-
const ERROR_CHECK_INTERVAL = 500;
|
|
13
|
-
const DEFAULT_TIMEOUT = 60 * 1000;
|
|
14
|
-
export default class BrowserFramework {
|
|
15
|
-
_cid;
|
|
16
|
-
_config;
|
|
17
|
-
_specs;
|
|
18
|
-
_capabilities;
|
|
19
|
-
_reporter;
|
|
20
|
-
#runnerOptions; // `any` here because we don't want to create a dependency to @wdio/browser-runner
|
|
21
|
-
#resolveTestStatePromise;
|
|
22
|
-
constructor(_cid, _config, _specs, _capabilities, _reporter) {
|
|
23
|
-
this._cid = _cid;
|
|
24
|
-
this._config = _config;
|
|
25
|
-
this._specs = _specs;
|
|
26
|
-
this._capabilities = _capabilities;
|
|
27
|
-
this._reporter = _reporter;
|
|
28
|
-
// listen on testrunner events
|
|
29
|
-
process.on('message', this.#processMessage.bind(this));
|
|
30
|
-
const [, runnerOptions] = Array.isArray(_config.runner) ? _config.runner : [];
|
|
31
|
-
this.#runnerOptions = runnerOptions || {};
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* always return true as it is irrelevant for component testing
|
|
35
|
-
*/
|
|
36
|
-
hasTests() {
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
39
|
-
init() {
|
|
40
|
-
return undefined;
|
|
41
|
-
}
|
|
42
|
-
async run() {
|
|
43
|
-
try {
|
|
44
|
-
const failures = await this.#loop();
|
|
45
|
-
return failures;
|
|
46
|
-
}
|
|
47
|
-
catch (err) {
|
|
48
|
-
if (err.message.includes('net::ERR_CONNECTION_REFUSE')) {
|
|
49
|
-
err.message = `Failed to load test page to run tests, make sure your browser can access "${browser.options.baseUrl}"`;
|
|
50
|
-
}
|
|
51
|
-
log.error(`Failed to run browser tests with cid ${this._cid}: ${err.stack}`);
|
|
52
|
-
process.send({
|
|
53
|
-
origin: 'worker',
|
|
54
|
-
name: 'error',
|
|
55
|
-
content: { name: err.name, message: err.message, stack: err.stack }
|
|
56
|
-
});
|
|
57
|
-
return 1;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
async #loop() {
|
|
61
|
-
/**
|
|
62
|
-
* start tests
|
|
63
|
-
*/
|
|
64
|
-
let failures = 0;
|
|
65
|
-
for (const spec of this._specs) {
|
|
66
|
-
failures += await this.#runSpec(spec);
|
|
67
|
-
}
|
|
68
|
-
return failures;
|
|
69
|
-
}
|
|
70
|
-
async #runSpec(spec, retried = false) {
|
|
71
|
-
const timeout = this._config.mochaOpts?.timeout || DEFAULT_TIMEOUT;
|
|
72
|
-
log.info(`Run spec file ${spec} for cid ${this._cid}`);
|
|
73
|
-
/**
|
|
74
|
-
* create promise to resolve test state which is being sent through the socket
|
|
75
|
-
* connection from the browser through the main process to the worker
|
|
76
|
-
*/
|
|
77
|
-
const testStatePromise = new Promise((resolve) => {
|
|
78
|
-
this.#resolveTestStatePromise = resolve;
|
|
79
|
-
});
|
|
80
|
-
/**
|
|
81
|
-
* if a `sessionId` is part of `this._config` it means we are in watch mode and are
|
|
82
|
-
* re-using a previous session. Since Vite has already a hot-reload feature, there
|
|
83
|
-
* is no need to call the url command again
|
|
84
|
-
*/
|
|
85
|
-
if (!this._config.sessionId) {
|
|
86
|
-
await browser.url(`/?cid=${this._cid}&spec=${url.parse(spec).pathname}`);
|
|
87
|
-
}
|
|
88
|
-
// await browser.debug()
|
|
89
|
-
/**
|
|
90
|
-
* set spec and cid as cookie so the Vite plugin can detect session even without
|
|
91
|
-
* query parameters
|
|
92
|
-
*/
|
|
93
|
-
await browser.setCookies([
|
|
94
|
-
{ name: 'WDIO_SPEC', value: url.fileURLToPath(spec) },
|
|
95
|
-
{ name: 'WDIO_CID', value: this._cid }
|
|
96
|
-
]);
|
|
97
|
-
/**
|
|
98
|
-
* wait for test results or page errors
|
|
99
|
-
*/
|
|
100
|
-
const testTimeout = setTimeout(() => this.#onTestTimeout(`Timed out after ${timeout / 1000}s waiting for test results`), timeout);
|
|
101
|
-
/**
|
|
102
|
-
* run checks for errors here to avoid breakage in communication with the browser
|
|
103
|
-
*/
|
|
104
|
-
const errorInterval = setInterval(this.#checkForTestError.bind(this), ERROR_CHECK_INTERVAL);
|
|
105
|
-
const state = await testStatePromise;
|
|
106
|
-
clearTimeout(testTimeout);
|
|
107
|
-
clearInterval(errorInterval);
|
|
108
|
-
/**
|
|
109
|
-
* capture coverage if enabled
|
|
110
|
-
*/
|
|
111
|
-
if (this.#runnerOptions.coverage?.enabled && process.send) {
|
|
112
|
-
const coverageMap = await browser.execute(() => (window.__coverage__ || {}));
|
|
113
|
-
const workerEvent = {
|
|
114
|
-
origin: 'worker',
|
|
115
|
-
name: 'workerEvent',
|
|
116
|
-
args: {
|
|
117
|
-
type: MESSAGE_TYPES.coverageMap,
|
|
118
|
-
value: coverageMap
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
process.send(workerEvent);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* let runner fail if we detect an error
|
|
125
|
-
*/
|
|
126
|
-
if (state.errors?.length) {
|
|
127
|
-
const errors = state.errors.map((ev) => state.hasViteError
|
|
128
|
-
? `${ev.message}\n${(ev.error ? ev.error.split('\n').slice(1).join('\n') : '')}`
|
|
129
|
-
: `${path.basename(ev.filename || spec)}: ${ev.message}\n${(ev.error ? ev.error.split('\n').slice(1).join('\n') : '')}`);
|
|
130
|
-
/**
|
|
131
|
-
* retry Vite dynamic import errors once
|
|
132
|
-
*/
|
|
133
|
-
if (!retried && errors.some((err) => (err.includes('Failed to fetch dynamically imported module') ||
|
|
134
|
-
err.includes('the server responded with a status of 504 (Outdated Optimize Dep)')))) {
|
|
135
|
-
log.info('Retry test run due to dynamic import error');
|
|
136
|
-
return this.#runSpec(spec, true);
|
|
137
|
-
}
|
|
138
|
-
const { name, message, stack } = new Error(state.hasViteError
|
|
139
|
-
? `Test failed due to the following error: ${errors.join('\n\n')}`
|
|
140
|
-
: `Test failed due to following error(s):${sep}${errors.join(sep)}`);
|
|
141
|
-
process.send({
|
|
142
|
-
origin: 'worker',
|
|
143
|
-
name: 'error',
|
|
144
|
-
content: { name, message, stack }
|
|
145
|
-
});
|
|
146
|
-
return 1;
|
|
147
|
-
}
|
|
148
|
-
/**
|
|
149
|
-
* report browser events to WebdriverIO reporter
|
|
150
|
-
*/
|
|
151
|
-
for (const ev of (state.events || [])) {
|
|
152
|
-
if ((ev.type === 'suite:start' || ev.type === 'suite:end') && ev.title === '') {
|
|
153
|
-
continue;
|
|
154
|
-
}
|
|
155
|
-
this._reporter.emit(ev.type, {
|
|
156
|
-
...ev,
|
|
157
|
-
file: spec,
|
|
158
|
-
uid: `${this._cid}-${Buffer.from(ev.fullTitle).toString('base64')}`,
|
|
159
|
-
cid: this._cid
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
return state.failures || 0;
|
|
163
|
-
}
|
|
164
|
-
async #processMessage(cmd) {
|
|
165
|
-
if (cmd.command !== 'workerRequest' || !process.send) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
const { message, id } = cmd.args;
|
|
169
|
-
if (message.type === MESSAGE_TYPES.hookTriggerMessage) {
|
|
170
|
-
return this.#handleHook(id, message.value);
|
|
171
|
-
}
|
|
172
|
-
if (message.type === MESSAGE_TYPES.consoleMessage) {
|
|
173
|
-
return this.#handleConsole(message.value);
|
|
174
|
-
}
|
|
175
|
-
if (message.type === MESSAGE_TYPES.commandRequestMessage) {
|
|
176
|
-
return this.#handleCommand(id, message.value);
|
|
177
|
-
}
|
|
178
|
-
if (message.type === MESSAGE_TYPES.expectRequestMessage) {
|
|
179
|
-
return this.#handleExpectation(id, message.value);
|
|
180
|
-
}
|
|
181
|
-
if (message.type === MESSAGE_TYPES.browserTestResult) {
|
|
182
|
-
return this.#handleTestFinish(message.value);
|
|
183
|
-
}
|
|
184
|
-
if (message.type === MESSAGE_TYPES.expectMatchersRequest) {
|
|
185
|
-
return this.#sendWorkerResponse(id, this.#expectMatcherResponse({ matchers: Array.from(matchers.keys()) }));
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
async #handleHook(id, payload) {
|
|
189
|
-
const error = await executeHooksWithArgs(payload.name, this._config[payload.name], payload.args).then(() => undefined, (err) => err);
|
|
190
|
-
if (error) {
|
|
191
|
-
log.warn(`Failed running "${payload.name}" hook for cid ${payload.cid}: ${error.message}`);
|
|
192
|
-
}
|
|
193
|
-
return this.#sendWorkerResponse(id, this.#hookResponse({ id: payload.id, error }));
|
|
194
|
-
}
|
|
195
|
-
#expectMatcherResponse(value) {
|
|
196
|
-
return {
|
|
197
|
-
type: MESSAGE_TYPES.expectMatchersResponse,
|
|
198
|
-
value
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
#hookResponse(value) {
|
|
202
|
-
return {
|
|
203
|
-
type: MESSAGE_TYPES.hookResultMessage,
|
|
204
|
-
value
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
#sendWorkerResponse(id, message) {
|
|
208
|
-
if (!process.send) {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
const response = {
|
|
212
|
-
origin: 'worker',
|
|
213
|
-
name: 'workerResponse',
|
|
214
|
-
args: { id, message }
|
|
215
|
-
};
|
|
216
|
-
process.send(response);
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Print console message executed in browser to the terminal
|
|
220
|
-
* @param message console.log message args
|
|
221
|
-
* @returns void
|
|
222
|
-
*/
|
|
223
|
-
#handleConsole(message) {
|
|
224
|
-
const isWDIOLog = Boolean(typeof message.args[0] === 'string' && message.args[0].startsWith('[WDIO]') && message.type !== 'error');
|
|
225
|
-
if (message.name !== 'consoleEvent' || isWDIOLog) {
|
|
226
|
-
return;
|
|
227
|
-
}
|
|
228
|
-
console[message.type](...(message.args || []));
|
|
229
|
-
}
|
|
230
|
-
async #handleCommand(id, payload) {
|
|
231
|
-
log.debug(`Received browser message: ${JSON.stringify(payload)}`);
|
|
232
|
-
const cid = payload.cid;
|
|
233
|
-
if (typeof cid !== 'string') {
|
|
234
|
-
const { message, stack } = new Error(`No "cid" property passed into command message with id "${payload.id}"`);
|
|
235
|
-
const error = { message, stack, name: 'Error' };
|
|
236
|
-
return this.#sendWorkerResponse(id, this.#commandResponse({ id: payload.id, error }));
|
|
237
|
-
}
|
|
238
|
-
try {
|
|
239
|
-
/**
|
|
240
|
-
* user either the browser instance or an element based on whether or not
|
|
241
|
-
* a scope property was passed in
|
|
242
|
-
*/
|
|
243
|
-
const scope = payload.scope
|
|
244
|
-
? await browser.$({ [ELEMENT_KEY]: payload.scope })
|
|
245
|
-
: browser;
|
|
246
|
-
/**
|
|
247
|
-
* double check if function is registered
|
|
248
|
-
*/
|
|
249
|
-
if (typeof scope[payload.commandName] !== 'function') {
|
|
250
|
-
throw new Error(`${payload.scope ? 'element' : 'browser'}.${payload.commandName} is not a function`);
|
|
251
|
-
}
|
|
252
|
-
let result = await scope[payload.commandName](...payload.args);
|
|
253
|
-
/**
|
|
254
|
-
* if result is an element, transform it into an element reference
|
|
255
|
-
*/
|
|
256
|
-
if (result?.constructor?.name === 'Element') {
|
|
257
|
-
result = result.elementId
|
|
258
|
-
? { [ELEMENT_KEY]: result.elementId }
|
|
259
|
-
: result.error
|
|
260
|
-
? { message: result.error.message, stack: result.error.stack, name: result.error.name }
|
|
261
|
-
: undefined;
|
|
262
|
-
/**
|
|
263
|
-
* if result is an array of elements, transform it into an array of element references
|
|
264
|
-
*/
|
|
265
|
-
}
|
|
266
|
-
else if (result?.foundWith) {
|
|
267
|
-
/**
|
|
268
|
-
* need await here since ElementArray functions return a promise
|
|
269
|
-
*/
|
|
270
|
-
result = (await result.map((res) => ({
|
|
271
|
-
[ELEMENT_KEY]: res.elementId
|
|
272
|
-
}))).filter(Boolean);
|
|
273
|
-
}
|
|
274
|
-
const resultMsg = this.#commandResponse({ id: payload.id, result });
|
|
275
|
-
log.debug(`Return command result: ${resultMsg}`);
|
|
276
|
-
return this.#sendWorkerResponse(id, resultMsg);
|
|
277
|
-
}
|
|
278
|
-
catch (error) {
|
|
279
|
-
const { message, stack, name } = error;
|
|
280
|
-
return this.#sendWorkerResponse(id, this.#commandResponse({ id: payload.id, error: { message, stack, name } }));
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
#commandResponse(value) {
|
|
284
|
-
return {
|
|
285
|
-
type: MESSAGE_TYPES.commandResponseMessage,
|
|
286
|
-
value
|
|
287
|
-
};
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* handle expectation assertions within the worker process
|
|
291
|
-
* @param id message id from communicator
|
|
292
|
-
* @param payload information about the expectation to run
|
|
293
|
-
* @returns void
|
|
294
|
-
*/
|
|
295
|
-
async #handleExpectation(id, payload) {
|
|
296
|
-
log.debug(`Received expectation message: ${JSON.stringify(payload)}`);
|
|
297
|
-
const cid = payload.cid;
|
|
298
|
-
/**
|
|
299
|
-
* check if payload contains `cid` needed to get a browser instance from the pool
|
|
300
|
-
*/
|
|
301
|
-
if (typeof cid !== 'string') {
|
|
302
|
-
const message = `No "cid" property passed into expect request message with id "${payload.id}"`;
|
|
303
|
-
return this.#sendWorkerResponse(id, this.#expectResponse({ id: payload.id, pass: false, message }));
|
|
304
|
-
}
|
|
305
|
-
/**
|
|
306
|
-
* find matcher, e.g. `toBeDisplayed` or `toHaveTitle`
|
|
307
|
-
*/
|
|
308
|
-
const matcher = matchers.get(payload.matcherName);
|
|
309
|
-
if (!matcher) {
|
|
310
|
-
const message = `Couldn't find matcher with name "${payload.matcherName}"`;
|
|
311
|
-
return this.#sendWorkerResponse(id, this.#expectResponse({ id: payload.id, pass: false, message }));
|
|
312
|
-
}
|
|
313
|
-
try {
|
|
314
|
-
const context = payload.element
|
|
315
|
-
? Array.isArray(payload.element)
|
|
316
|
-
? await browser.$$(payload.element)
|
|
317
|
-
/**
|
|
318
|
-
* check if element contains an `elementId` property, if so the element was already
|
|
319
|
-
* found, so we can transform it into an `WebdriverIO.Element` object, if not we
|
|
320
|
-
* need to find it first, so we pass in the selector.
|
|
321
|
-
*/
|
|
322
|
-
: payload.element.elementId
|
|
323
|
-
? await browser.$(payload.element)
|
|
324
|
-
: await browser.$(payload.element.selector)
|
|
325
|
-
: payload.context || browser;
|
|
326
|
-
const result = await matcher.apply(payload.scope, [context, ...payload.args.map(transformExpectArgs)]);
|
|
327
|
-
return this.#sendWorkerResponse(id, this.#expectResponse({
|
|
328
|
-
id: payload.id,
|
|
329
|
-
pass: result.pass,
|
|
330
|
-
message: result.message()
|
|
331
|
-
}));
|
|
332
|
-
}
|
|
333
|
-
catch (err) {
|
|
334
|
-
const errorMessage = err instanceof Error ? err.stack : err;
|
|
335
|
-
const message = `Failed to execute expect command "${payload.matcherName}": ${errorMessage}`;
|
|
336
|
-
return this.#sendWorkerResponse(id, this.#expectResponse({ id: payload.id, pass: false, message }));
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
#expectResponse(value) {
|
|
340
|
-
return {
|
|
341
|
-
type: MESSAGE_TYPES.expectResponseMessage,
|
|
342
|
-
value
|
|
343
|
-
};
|
|
344
|
-
}
|
|
345
|
-
#handleTestFinish(payload) {
|
|
346
|
-
this.#resolveTestStatePromise({ failures: payload.failures, events: payload.events });
|
|
347
|
-
}
|
|
348
|
-
#onTestTimeout(message) {
|
|
349
|
-
return this.#resolveTestStatePromise?.({
|
|
350
|
-
events: [],
|
|
351
|
-
failures: 1,
|
|
352
|
-
errors: [{ message }]
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
async #checkForTestError() {
|
|
356
|
-
const testError = await browser.execute(function fetchExecutionState() {
|
|
357
|
-
let viteError;
|
|
358
|
-
const viteErrorElem = document.querySelector('vite-error-overlay');
|
|
359
|
-
if (viteErrorElem && viteErrorElem.shadowRoot) {
|
|
360
|
-
const errorElements = Array.from(viteErrorElem.shadowRoot.querySelectorAll('pre'));
|
|
361
|
-
if (errorElements.length) {
|
|
362
|
-
viteError = [{ message: errorElements.map((elem) => elem.innerText).join('\n') }];
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
const loadError = (typeof window.__wdioErrors__ === 'undefined' &&
|
|
366
|
-
document.title !== 'WebdriverIO Browser Test' &&
|
|
367
|
-
!document.querySelector('mocha-framework'))
|
|
368
|
-
? [{ message: `Failed to load test page (title = "${document.title}", source: ${document.documentElement.innerHTML})` }]
|
|
369
|
-
: null;
|
|
370
|
-
const errors = viteError || window.__wdioErrors__ || loadError;
|
|
371
|
-
return { errors, hasViteError: Boolean(viteError) };
|
|
372
|
-
});
|
|
373
|
-
if ((testError.errors && testError.errors.length > 0) || testError.hasViteError) {
|
|
374
|
-
this.#resolveTestStatePromise?.({
|
|
375
|
-
events: [],
|
|
376
|
-
failures: 1,
|
|
377
|
-
...testError
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
static init(cid, config, specs, caps, reporter) {
|
|
382
|
-
const framework = new BrowserFramework(cid, config, specs, caps, reporter);
|
|
383
|
-
return framework;
|
|
384
|
-
}
|
|
385
|
-
}
|