@wdio/browser-runner 8.2.4 → 8.3.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 +5 -4
- package/build/constants.d.ts +9 -0
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +8 -0
- package/build/index.d.ts +2 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +77 -3
- package/build/types.d.ts +66 -0
- package/build/types.d.ts.map +1 -1
- package/build/utils.d.ts +4 -1
- package/build/utils.d.ts.map +1 -1
- package/build/utils.js +16 -0
- package/build/vite/constants.d.ts.map +1 -1
- package/build/vite/constants.js +3 -0
- package/build/vite/plugins/testrunner.d.ts.map +1 -1
- package/build/vite/plugins/testrunner.js +2 -11
- package/build/vite/server.d.ts +2 -1
- package/build/vite/server.d.ts.map +1 -1
- package/build/vite/server.js +20 -3
- package/package.json +16 -10
|
@@ -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":"AAiBA,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;CAmJ1B"}
|
package/build/browser/driver.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import stringify from 'fast-safe-stringify';
|
|
2
2
|
import { commands } from 'virtual:wdio';
|
|
3
|
-
import { webdriverMonad } from '@wdio/utils';
|
|
3
|
+
import { webdriverMonad, sessionEnvironmentDetector } from '@wdio/utils';
|
|
4
4
|
import { getEnvironmentVars } from 'webdriver';
|
|
5
5
|
import { MESSAGE_TYPES } from '../constants.js';
|
|
6
6
|
const COMMAND_TIMEOUT = 30 * 1000; // 30s
|
|
@@ -23,7 +23,8 @@ export default class ProxyDriver {
|
|
|
23
23
|
const socket = window.__wdioSocket__;
|
|
24
24
|
socket.addEventListener('message', this.#handleServerMessage.bind(this));
|
|
25
25
|
let commandId = 0;
|
|
26
|
-
const
|
|
26
|
+
const environment = sessionEnvironmentDetector({ capabilities: params.capabilities, requestedCapabilities: {} });
|
|
27
|
+
const environmentPrototype = getEnvironmentVars(environment);
|
|
27
28
|
// have debug command
|
|
28
29
|
const commandsProcessedInNodeWorld = [...commands, 'debug'];
|
|
29
30
|
const protocolCommands = commandsProcessedInNodeWorld.reduce((prev, commandName) => {
|
|
@@ -94,8 +95,8 @@ export default class ProxyDriver {
|
|
|
94
95
|
return console.error(`Unknown command id "${value.id}"`);
|
|
95
96
|
}
|
|
96
97
|
if (value.error) {
|
|
97
|
-
console.log(`[WDIO] ${(new Date()).toISOString()} - id: ${value.id} - ERROR: ${JSON.stringify(value.
|
|
98
|
-
return commandMessage.reject(value.error);
|
|
98
|
+
console.log(`[WDIO] ${(new Date()).toISOString()} - id: ${value.id} - ERROR: ${JSON.stringify(value.error.message)}`);
|
|
99
|
+
return commandMessage.reject(new Error(value.error.message || 'unknown error'));
|
|
99
100
|
}
|
|
100
101
|
if (commandMessage.commandTimeout) {
|
|
101
102
|
clearTimeout(commandMessage.commandTimeout);
|
package/build/constants.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Environment } from './types.js';
|
|
2
|
+
import type { ReportOptions } from 'istanbul-reports';
|
|
2
3
|
export declare const SESSIONS: Map<string, Environment>;
|
|
3
4
|
export declare const BROWSER_POOL: Map<string, WebdriverIO.Browser>;
|
|
4
5
|
export declare const EVENTS: {
|
|
@@ -21,4 +22,12 @@ export declare enum MESSAGE_TYPES {
|
|
|
21
22
|
hookTriggerMessage = 3,
|
|
22
23
|
hookResultMessage = 4
|
|
23
24
|
}
|
|
25
|
+
export declare const DEFAULT_INCLUDE: string[];
|
|
26
|
+
export declare const DEFAULT_FILE_EXTENSIONS: string[];
|
|
27
|
+
export declare const DEFAULT_REPORTS_DIRECTORY = "coverage";
|
|
28
|
+
export declare const SUMMARY_REPORTER = "json-summary";
|
|
29
|
+
export declare const COVERAGE_FACTORS: readonly ["lines", "functions", "branches", "statements"];
|
|
30
|
+
export declare const DEFAULT_COVERAGE_REPORTS: (keyof ReportOptions)[];
|
|
31
|
+
export declare const GLOBAL_TRESHOLD_REPORTING = "ERROR: Coverage for %s (%s%) does not meet global threshold (%s%)";
|
|
32
|
+
export declare const FILE_TRESHOLD_REPORTING = "ERROR: Coverage for %s (%s%) does not meet threshold (%s%) for %s";
|
|
24
33
|
//# sourceMappingURL=constants.d.ts.map
|
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;
|
|
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,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAa,CAAA;AAEvE,eAAO,MAAM,MAAM;;;;;;;;;;;CAWT,CAAA;AAEV,eAAO,MAAM,uBAAuB,wFAAsF,CAAA;AAE1H,oBAAY,aAAa;IACrB,cAAc,IAAI;IAClB,qBAAqB,IAAA;IACrB,sBAAsB,IAAA;IACtB,kBAAkB,IAAA;IAClB,iBAAiB,IAAA;CACpB;AAED,eAAO,MAAM,eAAe,UAAS,CAAA;AACrC,eAAO,MAAM,uBAAuB,UAAoF,CAAA;AACxH,eAAO,MAAM,yBAAyB,aAAa,CAAA;AACnD,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"}
|
package/build/constants.js
CHANGED
|
@@ -21,3 +21,11 @@ export var MESSAGE_TYPES;
|
|
|
21
21
|
MESSAGE_TYPES[MESSAGE_TYPES["hookTriggerMessage"] = 3] = "hookTriggerMessage";
|
|
22
22
|
MESSAGE_TYPES[MESSAGE_TYPES["hookResultMessage"] = 4] = "hookResultMessage";
|
|
23
23
|
})(MESSAGE_TYPES = MESSAGE_TYPES || (MESSAGE_TYPES = {}));
|
|
24
|
+
export const DEFAULT_INCLUDE = ['**'];
|
|
25
|
+
export const DEFAULT_FILE_EXTENSIONS = ['.js', '.cjs', '.mjs', '.ts', '.mts', '.cts', '.tsx', '.jsx', '.vue', '.svelte'];
|
|
26
|
+
export const DEFAULT_REPORTS_DIRECTORY = 'coverage';
|
|
27
|
+
export const SUMMARY_REPORTER = 'json-summary';
|
|
28
|
+
export const COVERAGE_FACTORS = ['lines', 'functions', 'branches', 'statements'];
|
|
29
|
+
export const DEFAULT_COVERAGE_REPORTS = ['text', 'html', 'clover', SUMMARY_REPORTER];
|
|
30
|
+
export const GLOBAL_TRESHOLD_REPORTING = 'ERROR: Coverage for %s (%s%) does not meet global threshold (%s%)';
|
|
31
|
+
export const FILE_TRESHOLD_REPORTING = 'ERROR: Coverage for %s (%s%) does not meet threshold (%s%) for %s';
|
package/build/index.d.ts
CHANGED
|
@@ -17,7 +17,8 @@ export default class BrowserRunner extends LocalRunner {
|
|
|
17
17
|
*
|
|
18
18
|
* @return {Promise} resolves when vite server has been shutdown
|
|
19
19
|
*/
|
|
20
|
-
shutdown(): Promise<
|
|
20
|
+
shutdown(): Promise<boolean>;
|
|
21
|
+
private _generateCoverageReports;
|
|
21
22
|
}
|
|
22
23
|
declare global {
|
|
23
24
|
namespace WebdriverIO {
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACjE,OAAO,WAAW,MAAM,oBAAoB,CAAA;AAQ5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAS1C,OAAO,KAAK,EAAE,oBAAoB,IAAI,0BAA0B,EAAmB,MAAM,YAAY,CAAA;AAGrG,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;;IAO9C,OAAO,CAAC,OAAO;IACf,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU;gBAD7B,OAAO,EAAE,0BAA0B,EACjC,OAAO,EAAE,OAAO,CAAC,UAAU;IAczC;;OAEG;IACG,UAAU;IAoBhB,GAAG,CAAE,OAAO,EAAE,OAAO,GAAG,cAAc;IAmDtC;;;;OAIG;IACG,QAAQ;YAMA,wBAAwB;CAmEzC;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,oBAAqB,SAAQ,0BAA0B;SAAG;KACvE;CACJ"}
|
package/build/index.js
CHANGED
|
@@ -1,15 +1,23 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import logger from '@wdio/logger';
|
|
2
4
|
import LocalRunner from '@wdio/local-runner';
|
|
3
5
|
import { attach } from 'webdriverio';
|
|
6
|
+
import libCoverage from 'istanbul-lib-coverage';
|
|
7
|
+
import libReport from 'istanbul-lib-report';
|
|
8
|
+
import libSourceMap from 'istanbul-lib-source-maps';
|
|
9
|
+
import reports from 'istanbul-reports';
|
|
4
10
|
import { ViteServer } from './vite/server.js';
|
|
5
|
-
import { FRAMEWORK_SUPPORT_ERROR, SESSIONS, BROWSER_POOL } from './constants.js';
|
|
6
|
-
import { makeHeadless } from './utils.js';
|
|
11
|
+
import { FRAMEWORK_SUPPORT_ERROR, SESSIONS, BROWSER_POOL, DEFAULT_COVERAGE_REPORTS, SUMMARY_REPORTER, DEFAULT_REPORTS_DIRECTORY } from './constants.js';
|
|
12
|
+
import { makeHeadless, getCoverageByFactor } from './utils.js';
|
|
7
13
|
const log = logger('@wdio/browser-runner');
|
|
8
14
|
export default class BrowserRunner extends LocalRunner {
|
|
9
15
|
options;
|
|
10
16
|
_config;
|
|
11
17
|
#config;
|
|
12
18
|
#server;
|
|
19
|
+
#coverageOptions;
|
|
20
|
+
#reportsDirectory;
|
|
13
21
|
constructor(options, _config) {
|
|
14
22
|
super(options, _config);
|
|
15
23
|
this.options = options;
|
|
@@ -17,8 +25,10 @@ export default class BrowserRunner extends LocalRunner {
|
|
|
17
25
|
if (_config.framework !== 'mocha') {
|
|
18
26
|
throw new Error(FRAMEWORK_SUPPORT_ERROR);
|
|
19
27
|
}
|
|
20
|
-
this.#server = new ViteServer(options);
|
|
28
|
+
this.#server = new ViteServer(options, _config);
|
|
21
29
|
this.#config = _config;
|
|
30
|
+
this.#coverageOptions = options.coverage || {};
|
|
31
|
+
this.#reportsDirectory = this.#coverageOptions.reportsDirectory || path.join(this.#config.rootDir, DEFAULT_REPORTS_DIRECTORY);
|
|
22
32
|
}
|
|
23
33
|
/**
|
|
24
34
|
* nothing to initialise when running locally
|
|
@@ -32,6 +42,13 @@ export default class BrowserRunner extends LocalRunner {
|
|
|
32
42
|
catch (err) {
|
|
33
43
|
throw new Error(`Vite server failed to start: ${err.stack}`);
|
|
34
44
|
}
|
|
45
|
+
if (typeof this.#coverageOptions.clean === 'undefined' || this.#coverageOptions.clean) {
|
|
46
|
+
const reportsDirectoryExist = await fs.access(this.#reportsDirectory)
|
|
47
|
+
.then(() => true, () => false);
|
|
48
|
+
if (reportsDirectoryExist) {
|
|
49
|
+
await fs.rm(this.#reportsDirectory, { recursive: true });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
35
52
|
await super.initialise();
|
|
36
53
|
}
|
|
37
54
|
run(runArgs) {
|
|
@@ -87,5 +104,62 @@ export default class BrowserRunner extends LocalRunner {
|
|
|
87
104
|
async shutdown() {
|
|
88
105
|
await super.shutdown();
|
|
89
106
|
await this.#server.close();
|
|
107
|
+
return this._generateCoverageReports();
|
|
108
|
+
}
|
|
109
|
+
async _generateCoverageReports() {
|
|
110
|
+
if (!this.#coverageOptions.enabled) {
|
|
111
|
+
return true;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* skip if no coverage directory was created
|
|
115
|
+
*/
|
|
116
|
+
const reportsDirectoryExist = await fs.access(this.#reportsDirectory)
|
|
117
|
+
.then(() => true, () => false);
|
|
118
|
+
if (!reportsDirectoryExist) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
const coverageIssues = [];
|
|
122
|
+
try {
|
|
123
|
+
const globalCoverageVar = JSON.parse((await fs.readFile(path.join(this.#reportsDirectory, 'out.json'))).toString());
|
|
124
|
+
const mapStore = libSourceMap.createSourceMapStore();
|
|
125
|
+
const coverageMap = await mapStore.transformCoverage(libCoverage.createCoverageMap(globalCoverageVar));
|
|
126
|
+
const context = libReport.createContext({
|
|
127
|
+
dir: this.#reportsDirectory,
|
|
128
|
+
defaultSummarizer: 'nested',
|
|
129
|
+
coverageMap
|
|
130
|
+
});
|
|
131
|
+
const reporter = this.#coverageOptions.reporter
|
|
132
|
+
? Array.isArray(this.#coverageOptions.reporter) ? this.#coverageOptions.reporter : [this.#coverageOptions.reporter]
|
|
133
|
+
: DEFAULT_COVERAGE_REPORTS;
|
|
134
|
+
/**
|
|
135
|
+
* ensure summary reporter is set as we need it for treshold comparison
|
|
136
|
+
*/
|
|
137
|
+
if (!reporter.includes(SUMMARY_REPORTER)) {
|
|
138
|
+
reporter.push(SUMMARY_REPORTER);
|
|
139
|
+
}
|
|
140
|
+
const reportBases = reporter.map((r) => reports.create(r, {
|
|
141
|
+
projectRoot: this.#config.rootDir,
|
|
142
|
+
subdir: 'html'
|
|
143
|
+
}));
|
|
144
|
+
reportBases.map((reportBase) => reportBase.execute(context));
|
|
145
|
+
log.info(`Successfully created coverage reports for ${reporter.join(', ')}`);
|
|
146
|
+
const summaryFilePath = path.join(this.#reportsDirectory, 'coverage-summary.json');
|
|
147
|
+
const summary = JSON.parse((await fs.readFile(summaryFilePath)).toString());
|
|
148
|
+
coverageIssues.push(...this.#coverageOptions.perFile
|
|
149
|
+
? Object.entries(summary)
|
|
150
|
+
.filter(([source]) => source !== 'total')
|
|
151
|
+
.map(([source, summary]) => (getCoverageByFactor(this.#coverageOptions, summary, source.replace(this.#config.rootDir, ''))))
|
|
152
|
+
.flat()
|
|
153
|
+
: getCoverageByFactor(this.#coverageOptions, summary.total));
|
|
154
|
+
}
|
|
155
|
+
catch (err) {
|
|
156
|
+
console.error(`Failed to generate code coverage report: ${err.message}`);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
if (coverageIssues.length) {
|
|
160
|
+
console.log(coverageIssues.join('\n'));
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
return true;
|
|
90
164
|
}
|
|
91
165
|
}
|
package/build/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { InlineConfig } from 'vite';
|
|
2
2
|
import type { Workers, Capabilities, Options } from '@wdio/types';
|
|
3
3
|
import type { MochaOpts } from '@wdio/mocha-framework';
|
|
4
|
+
import type { IstanbulPluginOptions } from 'vite-plugin-istanbul';
|
|
4
5
|
declare global {
|
|
5
6
|
interface Window {
|
|
6
7
|
__wdioEnv__: Environment;
|
|
@@ -8,6 +9,66 @@ declare global {
|
|
|
8
9
|
}
|
|
9
10
|
}
|
|
10
11
|
export type FrameworkPreset = 'react' | 'preact' | 'vue' | 'svelte' | 'lit' | 'solid';
|
|
12
|
+
type Arrayable<T> = T | Array<T>;
|
|
13
|
+
type CoverageReporter = 'clover' | 'cobertura' | 'html-spa' | 'html' | 'json-summary' | 'json' | 'lcov' | 'lcovonly' | 'none' | 'teamcity' | 'text-lcov' | 'text-summary' | 'text';
|
|
14
|
+
export interface CoverageOptions extends Omit<IstanbulPluginOptions, 'cypress' | 'checkProd' | 'forceBuildInstrument'> {
|
|
15
|
+
/**
|
|
16
|
+
* Enables coverage collection.
|
|
17
|
+
*
|
|
18
|
+
* @default false
|
|
19
|
+
*/
|
|
20
|
+
enabled: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Directory to write coverage report to.
|
|
23
|
+
*
|
|
24
|
+
* @default ./coverage
|
|
25
|
+
*/
|
|
26
|
+
reportsDirectory?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Coverage reporters to use.
|
|
29
|
+
* See [istanbul documentation](https://istanbul.js.org/docs/advanced/alternative-reporters/) for detailed list of all reporters.
|
|
30
|
+
*
|
|
31
|
+
* @default ['text', 'html', 'clover', 'json-summary']
|
|
32
|
+
*/
|
|
33
|
+
reporter?: Arrayable<CoverageReporter>;
|
|
34
|
+
/**
|
|
35
|
+
* Check thresholds per file.
|
|
36
|
+
* See `lines`, `functions`, `branches` and `statements` for the actual thresholds.
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
perFile?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Clean coverage results before running tests.
|
|
43
|
+
*
|
|
44
|
+
* @default true
|
|
45
|
+
*/
|
|
46
|
+
clean?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Threshold for lines
|
|
49
|
+
*
|
|
50
|
+
* @default undefined
|
|
51
|
+
*/
|
|
52
|
+
lines?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Threshold for functions
|
|
55
|
+
*
|
|
56
|
+
* @default undefined
|
|
57
|
+
*/
|
|
58
|
+
functions?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Threshold for branches
|
|
61
|
+
*
|
|
62
|
+
* @default undefined
|
|
63
|
+
*/
|
|
64
|
+
branches?: number;
|
|
65
|
+
/**
|
|
66
|
+
* Threshold for statements
|
|
67
|
+
*
|
|
68
|
+
* @default undefined
|
|
69
|
+
*/
|
|
70
|
+
statements?: number;
|
|
71
|
+
}
|
|
11
72
|
export interface BrowserRunnerOptions {
|
|
12
73
|
/**
|
|
13
74
|
* Project root directory
|
|
@@ -27,6 +88,10 @@ export interface BrowserRunnerOptions {
|
|
|
27
88
|
* @default false // true in CI environment
|
|
28
89
|
*/
|
|
29
90
|
headless?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* test coverage settings
|
|
93
|
+
*/
|
|
94
|
+
coverage?: CoverageOptions;
|
|
30
95
|
}
|
|
31
96
|
export interface RunArgs extends Workers.WorkerRunPayload {
|
|
32
97
|
command: string;
|
|
@@ -40,4 +105,5 @@ export interface Environment {
|
|
|
40
105
|
sessionId: string;
|
|
41
106
|
injectGlobals: boolean;
|
|
42
107
|
}
|
|
108
|
+
export {};
|
|
43
109
|
//# sourceMappingURL=types.d.ts.map
|
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,YAAY,EAAE,MAAM,MAAM,CAAA;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AACxC,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAEjE,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,WAAW,EAAE,WAAW,CAAA;QACxB,iBAAiB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;KAC9C;CACJ;AAED,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,KAAK,GAAG,OAAO,CAAA;AACrF,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;AAChC,KAAK,gBAAgB,GAAG,QAAQ,GAAG,WAAW,GAAG,UAAU,GAAG,MAAM,GAAG,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,cAAc,GAAG,MAAM,CAAA;AAClL,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,qBAAqB,EAAE,SAAS,GAAG,WAAW,GAAG,sBAAsB,CAAC;IAClH;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC,gBAAgB,CAAC,CAAA;IACtC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,OAAO,CAAA;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,oBAAoB;IACjC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;OAEG;IACH,MAAM,CAAC,EAAE,eAAe,CAAA;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,YAAY,CAAA;IACzB;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;CAC7B;AAED,MAAM,WAAW,OAAQ,SAAQ,OAAO,CAAC,gBAAgB;IACrD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,GAAG,CAAA;IACT,GAAG,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,OAAO,CAAC,UAAU,CAAA;IAC1B,YAAY,EAAE,YAAY,CAAC,gBAAgB,CAAA;IAC3C,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;CACzB"}
|
package/build/utils.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type { Capabilities } from '@wdio/types';
|
|
2
|
-
import type {
|
|
2
|
+
import type { CoverageSummary } from 'istanbul-lib-coverage';
|
|
3
|
+
import { COVERAGE_FACTORS } from './constants.js';
|
|
4
|
+
import type { BrowserRunnerOptions, CoverageOptions } from './types.js';
|
|
3
5
|
export declare function makeHeadless(options: BrowserRunnerOptions, caps: Capabilities.RemoteCapability): Capabilities.RemoteCapability;
|
|
6
|
+
export declare function getCoverageByFactor(options: Partial<CoverageOptions>, summary: Pick<CoverageSummary, (typeof COVERAGE_FACTORS)[number]>, fileName?: string): string[];
|
|
4
7
|
//# sourceMappingURL=utils.d.ts.map
|
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":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAE5D,OAAO,EAAE,gBAAgB,EAAsD,MAAM,gBAAgB,CAAA;AACrG,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAIvE,wBAAgB,YAAY,CAAE,OAAO,EAAE,oBAAoB,EAAE,IAAI,EAAE,YAAY,CAAC,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CA0C/H;AAED,wBAAgB,mBAAmB,CAC/B,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,EACjC,OAAO,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC,EACjE,QAAQ,CAAC,EAAE,MAAM,YAepB"}
|
package/build/utils.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
1
2
|
import { deepmerge } from 'deepmerge-ts';
|
|
2
3
|
import logger from '@wdio/logger';
|
|
4
|
+
import { COVERAGE_FACTORS, GLOBAL_TRESHOLD_REPORTING, FILE_TRESHOLD_REPORTING } from './constants.js';
|
|
3
5
|
const log = logger('@wdio/browser-runner');
|
|
4
6
|
export function makeHeadless(options, caps) {
|
|
5
7
|
const capability = caps.alwaysMatch || caps;
|
|
@@ -40,3 +42,17 @@ export function makeHeadless(options, caps) {
|
|
|
40
42
|
log.error(`Headless mode not supported for browser "${capability.browserName}"`);
|
|
41
43
|
return caps;
|
|
42
44
|
}
|
|
45
|
+
export function getCoverageByFactor(options, summary, fileName) {
|
|
46
|
+
return COVERAGE_FACTORS.map((factor) => {
|
|
47
|
+
const treshold = options[factor];
|
|
48
|
+
if (!treshold) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (summary[factor].pct >= treshold) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
return fileName
|
|
55
|
+
? util.format(FILE_TRESHOLD_REPORTING, factor, summary[factor].pct, treshold, fileName)
|
|
56
|
+
: util.format(GLOBAL_TRESHOLD_REPORTING, factor, summary[factor].pct, treshold);
|
|
57
|
+
}).filter(Boolean);
|
|
58
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/vite/constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAgB1F,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,YAAY,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/vite/constants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,CAgB1F,CAAA;AAED,eAAO,MAAM,mBAAmB,EAAE,OAAO,CAAC,YAAY,CAsBrD,CAAA"}
|
package/build/vite/constants.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testrunner.d.ts","sourceRoot":"","sources":["../../../src/vite/plugins/testrunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testrunner.d.ts","sourceRoot":"","sources":["../../../src/vite/plugins/testrunner.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAuClC,wBAAgB,UAAU,CAAE,OAAO,EAAE,WAAW,CAAC,oBAAoB,GAAG,MAAM,CA6G7E"}
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
import url from 'node:url';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import logger from '@wdio/logger';
|
|
4
|
+
import { deepmerge } from 'deepmerge-ts';
|
|
4
5
|
import { resolve } from 'import-meta-resolve';
|
|
5
6
|
import { WebDriverProtocol, MJsonWProtocol, JsonWProtocol, AppiumProtocol, ChromiumProtocol, SauceLabsProtocol, SeleniumProtocol, GeckoProtocol, WebDriverBidiProtocol } from '@wdio/protocols';
|
|
6
7
|
import { SESSIONS } from '../../constants.js';
|
|
7
8
|
import { getTemplate, getErrorTemplate } from '../utils.js';
|
|
8
9
|
const log = logger('@wdio/browser-runner:plugin');
|
|
9
10
|
const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
|
|
10
|
-
const commands =
|
|
11
|
-
...WebDriverProtocol,
|
|
12
|
-
...MJsonWProtocol,
|
|
13
|
-
...JsonWProtocol,
|
|
14
|
-
...AppiumProtocol,
|
|
15
|
-
...ChromiumProtocol,
|
|
16
|
-
...SauceLabsProtocol,
|
|
17
|
-
...SeleniumProtocol,
|
|
18
|
-
...GeckoProtocol,
|
|
19
|
-
...WebDriverBidiProtocol
|
|
20
|
-
};
|
|
11
|
+
const commands = deepmerge(WebDriverProtocol, MJsonWProtocol, JsonWProtocol, AppiumProtocol, ChromiumProtocol, SauceLabsProtocol, SeleniumProtocol, GeckoProtocol, WebDriverBidiProtocol);
|
|
21
12
|
const protocolCommandList = Object.values(commands).map((endpoint) => Object.values(endpoint).map(({ command }) => command)).flat();
|
|
22
13
|
const WDIO_PACKAGES = ['webdriverio', 'expect-webdriverio'];
|
|
23
14
|
const virtualModuleId = 'virtual:wdio';
|
package/build/vite/server.d.ts
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
import { EventEmitter } from 'node:events';
|
|
3
3
|
import { WebSocketServer } from 'ws';
|
|
4
4
|
import type { InlineConfig } from 'vite';
|
|
5
|
+
import type { Options } from '@wdio/types';
|
|
5
6
|
import type { HookTriggerEvent } from './types.js';
|
|
6
7
|
export declare class ViteServer extends EventEmitter {
|
|
7
8
|
#private;
|
|
8
9
|
get socketServer(): WebSocketServer | undefined;
|
|
9
10
|
get config(): Partial<InlineConfig>;
|
|
10
|
-
constructor(options: WebdriverIO.BrowserRunnerOptions);
|
|
11
|
+
constructor(options: WebdriverIO.BrowserRunnerOptions, config: Options.Testrunner);
|
|
11
12
|
start(): Promise<void>;
|
|
12
13
|
close(): Promise<void>;
|
|
13
14
|
private runWorkerHooks;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/vite/server.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM1C,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAGpC,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/vite/server.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM1C,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAGpC,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,MAAM,CAAA;AAGvD,OAAO,KAAK,EAAY,OAAO,EAAE,MAAM,aAAa,CAAA;AAMpD,OAAO,KAAK,EAAgB,gBAAgB,EAA6E,MAAM,YAAY,CAAA;AAY3I,qBAAa,UAAW,SAAQ,YAAY;;IAQxC,IAAI,YAAY,gCAEf;IAED,IAAI,MAAM,0BAET;gBAEY,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IA6B5E,KAAK;IAwCL,KAAK;IA2IX,OAAO,CAAC,cAAc;IAetB,WAAW,CAAE,MAAM,EAAE,gBAAgB;CAUxC"}
|
package/build/vite/server.js
CHANGED
|
@@ -6,10 +6,11 @@ import { WebSocketServer } from 'ws';
|
|
|
6
6
|
import { serializeError } from 'serialize-error';
|
|
7
7
|
import { executeHooksWithArgs } from '@wdio/utils';
|
|
8
8
|
import { createServer } from 'vite';
|
|
9
|
+
import istanbulPlugin from 'vite-plugin-istanbul';
|
|
9
10
|
import { testrunner } from './plugins/testrunner.js';
|
|
10
11
|
import { userfriendlyImport } from './utils.js';
|
|
11
12
|
import { PRESET_DEPENDENCIES, DEFAULT_VITE_CONFIG } from './constants.js';
|
|
12
|
-
import { MESSAGE_TYPES } from '../constants.js';
|
|
13
|
+
import { MESSAGE_TYPES, DEFAULT_INCLUDE, DEFAULT_FILE_EXTENSIONS } from '../constants.js';
|
|
13
14
|
import { BROWSER_POOL, SESSIONS } from '../constants.js';
|
|
14
15
|
const log = logger('@wdio/browser-runner:ViteServer');
|
|
15
16
|
const HOOK_TIMEOUT = 15 * 1000;
|
|
@@ -26,7 +27,7 @@ export class ViteServer extends EventEmitter {
|
|
|
26
27
|
get config() {
|
|
27
28
|
return this.#viteConfig;
|
|
28
29
|
}
|
|
29
|
-
constructor(options) {
|
|
30
|
+
constructor(options, config) {
|
|
30
31
|
super();
|
|
31
32
|
this.#options = options;
|
|
32
33
|
if (options.preset && options.viteConfig) {
|
|
@@ -36,6 +37,16 @@ export class ViteServer extends EventEmitter {
|
|
|
36
37
|
root: options.rootDir || process.cwd(),
|
|
37
38
|
plugins: [testrunner(options)]
|
|
38
39
|
});
|
|
40
|
+
if (options.coverage && options.coverage.enabled) {
|
|
41
|
+
log.info('Capturing test coverage enabled');
|
|
42
|
+
// @ts-expect-error
|
|
43
|
+
this.#viteConfig.plugins?.push(istanbulPlugin({
|
|
44
|
+
cwd: config.rootDir,
|
|
45
|
+
include: DEFAULT_INCLUDE,
|
|
46
|
+
extension: DEFAULT_FILE_EXTENSIONS,
|
|
47
|
+
...options.coverage
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
39
50
|
if (options.viteConfig) {
|
|
40
51
|
this.#viteConfig = deepmerge(this.#viteConfig, options.viteConfig);
|
|
41
52
|
}
|
|
@@ -139,7 +150,7 @@ export class ViteServer extends EventEmitter {
|
|
|
139
150
|
return ws.send(JSON.stringify(this.#hookResponse(result)));
|
|
140
151
|
}
|
|
141
152
|
async #handleCommand(ws, payload) {
|
|
142
|
-
log.
|
|
153
|
+
log.debug(`Received browser message: ${JSON.stringify(payload)}`);
|
|
143
154
|
const cid = payload.cid;
|
|
144
155
|
if (typeof cid !== 'string') {
|
|
145
156
|
const error = serializeError(new Error(`No "cid" property passed into command message with id "${payload.id}"`));
|
|
@@ -157,6 +168,12 @@ export class ViteServer extends EventEmitter {
|
|
|
157
168
|
if (payload.commandName === 'debug') {
|
|
158
169
|
this.emit('debugState', true);
|
|
159
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* double check if function is registered
|
|
173
|
+
*/
|
|
174
|
+
if (typeof browser[payload.commandName] !== 'function') {
|
|
175
|
+
throw new Error(`browser.${payload.commandName} is not a function`);
|
|
176
|
+
}
|
|
160
177
|
const result = await browser[payload.commandName](...payload.args);
|
|
161
178
|
const resultMsg = JSON.stringify(this.#commandResponse({ id: payload.id, result }));
|
|
162
179
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browser-runner",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.3.0",
|
|
4
4
|
"description": "A WebdriverIO runner to run unit tests tests in the browser.",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-browser-runner",
|
|
@@ -29,24 +29,30 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
31
31
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
32
|
+
"@types/istanbul-lib-source-maps": "^4.0.1",
|
|
32
33
|
"@types/node": "^18.11.18",
|
|
33
|
-
"@wdio/globals": "8.
|
|
34
|
-
"@wdio/local-runner": "8.
|
|
34
|
+
"@wdio/globals": "8.3.0",
|
|
35
|
+
"@wdio/local-runner": "8.3.0",
|
|
35
36
|
"@wdio/logger": "8.1.0",
|
|
36
|
-
"@wdio/mocha-framework": "8.
|
|
37
|
+
"@wdio/mocha-framework": "8.3.0",
|
|
37
38
|
"@wdio/protocols": "8.2.0",
|
|
38
|
-
"@wdio/types": "8.
|
|
39
|
-
"@wdio/utils": "8.
|
|
39
|
+
"@wdio/types": "8.3.0",
|
|
40
|
+
"@wdio/utils": "8.3.0",
|
|
40
41
|
"deepmerge-ts": "^4.2.2",
|
|
41
42
|
"expect-webdriverio": "^4.1.0",
|
|
42
43
|
"fast-safe-stringify": "^2.1.1",
|
|
43
44
|
"get-port": "^6.1.2",
|
|
44
45
|
"import-meta-resolve": "^2.2.1",
|
|
46
|
+
"istanbul-lib-coverage": "^3.2.0",
|
|
47
|
+
"istanbul-lib-report": "^3.0.0",
|
|
48
|
+
"istanbul-lib-source-maps": "^4.0.1",
|
|
49
|
+
"istanbul-reports": "^3.1.5",
|
|
45
50
|
"serialize-error": "^11.0.0",
|
|
46
51
|
"vite": "^4.0.4",
|
|
52
|
+
"vite-plugin-istanbul": "^4.0.0",
|
|
47
53
|
"vite-plugin-top-level-await": "^1.2.2",
|
|
48
|
-
"webdriver": "8.
|
|
49
|
-
"webdriverio": "8.
|
|
54
|
+
"webdriver": "8.3.0",
|
|
55
|
+
"webdriverio": "8.3.0",
|
|
50
56
|
"ws": "^8.12.0"
|
|
51
57
|
},
|
|
52
58
|
"scripts": {
|
|
@@ -57,7 +63,7 @@
|
|
|
57
63
|
},
|
|
58
64
|
"devDependencies": {
|
|
59
65
|
"@types/ws": "^8.5.4",
|
|
60
|
-
"@wdio/runner": "8.
|
|
66
|
+
"@wdio/runner": "8.3.0"
|
|
61
67
|
},
|
|
62
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "156a246e8117463cf3c762d2da5bf9eef3a476ea"
|
|
63
69
|
}
|