@wdio/browser-runner 8.3.11 → 8.4.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/frameworks/mocha.d.ts.map +1 -1
- package/build/browser/frameworks/mocha.js +1 -2
- package/build/browser/setup.d.ts +1 -0
- package/build/browser/setup.d.ts.map +1 -1
- package/build/browser/spy.d.ts +3 -0
- package/build/browser/spy.d.ts.map +1 -1
- package/build/browser/spy.js +53 -0
- package/build/constants.d.ts +5 -1
- package/build/constants.d.ts.map +1 -1
- package/build/constants.js +4 -0
- package/build/types.d.ts +10 -0
- package/build/types.d.ts.map +1 -1
- package/build/vite/mock.d.ts +16 -0
- package/build/vite/mock.d.ts.map +1 -0
- package/build/vite/mock.js +53 -0
- package/build/vite/plugins/mockHoisting.d.ts +4 -0
- package/build/vite/plugins/mockHoisting.d.ts.map +1 -0
- package/build/vite/plugins/mockHoisting.js +192 -0
- package/build/vite/plugins/testrunner.d.ts.map +1 -1
- package/build/vite/plugins/testrunner.js +1 -2
- package/build/vite/server.d.ts.map +1 -1
- package/build/vite/server.js +15 -1
- package/build/vite/types.d.ts +10 -0
- package/build/vite/types.d.ts.map +1 -1
- package/build/vite/utils.d.ts +4 -1
- package/build/vite/utils.d.ts.map +1 -1
- package/build/vite/utils.js +43 -3
- package/package.json +14 -11
|
@@ -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":"AASA,qBAAa,cAAc;;gBAKV,MAAM,EAAE,SAAS;IA+B9B,GAAG;CA+DN"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import Mocha from 'mocha';
|
|
2
1
|
import stringify from 'fast-safe-stringify';
|
|
3
2
|
import { setupEnv, formatMessage } from '@wdio/mocha-framework/common';
|
|
4
3
|
import { MESSAGE_TYPES, EVENTS } from '../../constants.js';
|
|
@@ -95,7 +94,7 @@ const BaseReporter = window.Mocha.reporters.html;
|
|
|
95
94
|
class HTMLReporter extends BaseReporter {
|
|
96
95
|
addCodeToggle() { }
|
|
97
96
|
}
|
|
98
|
-
|
|
97
|
+
mocha.setup({
|
|
99
98
|
...window.__wdioEnv__.args,
|
|
100
99
|
reporter: HTMLReporter
|
|
101
100
|
});
|
package/build/browser/setup.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/browser/setup.ts"],"names":[],"mappings":"AAQA,KAAK,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC,CAAA;AAC9D,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,cAAc,EAAE,cAAc,EAAE,CAAA;QAChC,YAAY,EAAE,MAAM,CAAA;QACpB,gBAAgB,EAAE,MAAM,CAAA;QACxB,cAAc,EAAE,GAAG,EAAE,CAAA;QACrB,cAAc,EAAE,SAAS,CAAA;QACzB,sBAAsB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;KAC7C;CACJ;AAOD,eAAO,MAAM,MAAM,WAA+C,CAAA;AAClE,eAAO,MAAM,cAAc,oBAGzB,CAAA"}
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/browser/setup.ts"],"names":[],"mappings":"AAQA,KAAK,cAAc,GAAG,IAAI,CAAC,UAAU,EAAE,UAAU,GAAG,SAAS,CAAC,CAAA;AAC9D,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,MAAM;QACZ,cAAc,EAAE,cAAc,EAAE,CAAA;QAChC,YAAY,EAAE,MAAM,CAAA;QACpB,gBAAgB,EAAE,MAAM,CAAA;QACxB,cAAc,EAAE,GAAG,EAAE,CAAA;QACrB,cAAc,EAAE,SAAS,CAAA;QACzB,sBAAsB,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;QAC1C,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAC7C;CACJ;AAOD,eAAO,MAAM,MAAM,WAA+C,CAAA;AAClE,eAAO,MAAM,cAAc,oBAGzB,CAAA"}
|
package/build/browser/spy.d.ts
CHANGED
|
@@ -2,4 +2,7 @@
|
|
|
2
2
|
* re-export mock module
|
|
3
3
|
*/
|
|
4
4
|
export * from '@vitest/spy';
|
|
5
|
+
type MockFactoryWithHelper = (importOriginal: <T = unknown>() => Promise<T>) => any;
|
|
6
|
+
export declare function mock(path: string, factory?: MockFactoryWithHelper): Promise<unknown>;
|
|
7
|
+
export declare function unmock(moduleName: string): void;
|
|
5
8
|
//# sourceMappingURL=spy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spy.d.ts","sourceRoot":"","sources":["../../src/browser/spy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"spy.d.ts","sourceRoot":"","sources":["../../src/browser/spy.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,cAAc,aAAa,CAAA;AAE3B,KAAK,qBAAqB,GAAG,CAAC,cAAc,EAAE,CAAC,CAAC,GAAG,OAAO,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;AAapF,wBAAsB,IAAI,CAAE,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,oBA4BxE;AAGD,wBAAgB,MAAM,CAAC,UAAU,EAAE,MAAM,QAExC"}
|
package/build/browser/spy.js
CHANGED
|
@@ -1,4 +1,57 @@
|
|
|
1
|
+
import { MESSAGE_TYPES } from '../constants.js';
|
|
1
2
|
/**
|
|
2
3
|
* re-export mock module
|
|
3
4
|
*/
|
|
4
5
|
export * from '@vitest/spy';
|
|
6
|
+
const a = document.createElement('a');
|
|
7
|
+
function resolveUrl(path) {
|
|
8
|
+
a.href = path;
|
|
9
|
+
return a.href;
|
|
10
|
+
}
|
|
11
|
+
const ERROR_MESSAGE = '[wdio] There was an error, when mocking a module. If you are using the "mock" factory, make sure there are no top level variables inside, since this call is hoisted to top of the file. Read more: https://webdriver.io/docs/component-testing/mocking';
|
|
12
|
+
const socket = window.__wdioSocket__;
|
|
13
|
+
const mockResolver = new Map();
|
|
14
|
+
const origin = window.__wdioSpec__.split('/').slice(0, -1).join('/');
|
|
15
|
+
window.__wdioMockFactories__ = [];
|
|
16
|
+
export async function mock(path, factory) {
|
|
17
|
+
/**
|
|
18
|
+
* mock calls without factory parameter should get removed from the source code
|
|
19
|
+
* by the mock hoisting plugin
|
|
20
|
+
*/
|
|
21
|
+
if (!factory) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const mockLocalFile = path.startsWith('/') || path.startsWith('./');
|
|
25
|
+
const mockPath = mockLocalFile
|
|
26
|
+
? (new URL(resolveUrl(window.__wdioSpec__.split('/').slice(0, -1).join('/') + '/' + path))).pathname
|
|
27
|
+
: path;
|
|
28
|
+
try {
|
|
29
|
+
const resolvedMock = await factory(() => (import(mockLocalFile ? `/@mock${mockPath}` : `/node_modules/.vite/deps/${mockPath}.js`)));
|
|
30
|
+
socket.send(JSON.stringify({
|
|
31
|
+
type: MESSAGE_TYPES.mockRequest,
|
|
32
|
+
value: { path: mockPath, origin, namedExports: Object.keys(resolvedMock) }
|
|
33
|
+
}));
|
|
34
|
+
window.__wdioMockFactories__[mockPath] = resolvedMock;
|
|
35
|
+
return new Promise((resolve) => mockResolver.set(mockPath, resolve));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
throw new Error(ERROR_MESSAGE + '\n' + err.stack);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
42
|
+
export function unmock(moduleName) {
|
|
43
|
+
// NO-OP: call gets removed by recast
|
|
44
|
+
}
|
|
45
|
+
socket.addEventListener('message', (ev) => {
|
|
46
|
+
try {
|
|
47
|
+
const { type, value } = JSON.parse(ev.data);
|
|
48
|
+
const resolver = mockResolver.get(value.path);
|
|
49
|
+
if (type !== MESSAGE_TYPES.mockResponse || !resolver) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
return resolver(null);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// ignore
|
|
56
|
+
}
|
|
57
|
+
});
|
package/build/constants.d.ts
CHANGED
|
@@ -20,11 +20,15 @@ export declare enum MESSAGE_TYPES {
|
|
|
20
20
|
commandRequestMessage = 1,
|
|
21
21
|
commandResponseMessage = 2,
|
|
22
22
|
hookTriggerMessage = 3,
|
|
23
|
-
hookResultMessage = 4
|
|
23
|
+
hookResultMessage = 4,
|
|
24
|
+
mockRequest = 5,
|
|
25
|
+
mockResponse = 6
|
|
24
26
|
}
|
|
25
27
|
export declare const DEFAULT_INCLUDE: string[];
|
|
26
28
|
export declare const DEFAULT_FILE_EXTENSIONS: string[];
|
|
27
29
|
export declare const DEFAULT_REPORTS_DIRECTORY = "coverage";
|
|
30
|
+
export declare const DEFAULT_AUTOMOCK = true;
|
|
31
|
+
export declare const DEFAULT_MOCK_DIRECTORY = "__mocks__";
|
|
28
32
|
export declare const SUMMARY_REPORTER = "json-summary";
|
|
29
33
|
export declare const COVERAGE_FACTORS: readonly ["lines", "functions", "branches", "statements"];
|
|
30
34
|
export declare const DEFAULT_COVERAGE_REPORTS: (keyof ReportOptions)[];
|
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,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;
|
|
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;IACjB,WAAW,IAAA;IACX,YAAY,IAAA;CACf;AAED,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"}
|
package/build/constants.js
CHANGED
|
@@ -20,10 +20,14 @@ export var MESSAGE_TYPES;
|
|
|
20
20
|
MESSAGE_TYPES[MESSAGE_TYPES["commandResponseMessage"] = 2] = "commandResponseMessage";
|
|
21
21
|
MESSAGE_TYPES[MESSAGE_TYPES["hookTriggerMessage"] = 3] = "hookTriggerMessage";
|
|
22
22
|
MESSAGE_TYPES[MESSAGE_TYPES["hookResultMessage"] = 4] = "hookResultMessage";
|
|
23
|
+
MESSAGE_TYPES[MESSAGE_TYPES["mockRequest"] = 5] = "mockRequest";
|
|
24
|
+
MESSAGE_TYPES[MESSAGE_TYPES["mockResponse"] = 6] = "mockResponse";
|
|
23
25
|
})(MESSAGE_TYPES || (MESSAGE_TYPES = {}));
|
|
24
26
|
export const DEFAULT_INCLUDE = ['**'];
|
|
25
27
|
export const DEFAULT_FILE_EXTENSIONS = ['.js', '.cjs', '.mjs', '.ts', '.mts', '.cts', '.tsx', '.jsx', '.vue', '.svelte'];
|
|
26
28
|
export const DEFAULT_REPORTS_DIRECTORY = 'coverage';
|
|
29
|
+
export const DEFAULT_AUTOMOCK = true;
|
|
30
|
+
export const DEFAULT_MOCK_DIRECTORY = '__mocks__';
|
|
27
31
|
export const SUMMARY_REPORTER = 'json-summary';
|
|
28
32
|
export const COVERAGE_FACTORS = ['lines', 'functions', 'branches', 'statements'];
|
|
29
33
|
export const DEFAULT_COVERAGE_REPORTS = ['text', 'html', 'clover', SUMMARY_REPORTER];
|
package/build/types.d.ts
CHANGED
|
@@ -92,6 +92,16 @@ export interface BrowserRunnerOptions {
|
|
|
92
92
|
* test coverage settings
|
|
93
93
|
*/
|
|
94
94
|
coverage?: CoverageOptions;
|
|
95
|
+
/**
|
|
96
|
+
* If set to `true` WebdriverIO will automatically mock dependencies within the `automockDir` directory
|
|
97
|
+
* @default true
|
|
98
|
+
*/
|
|
99
|
+
automock?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Path of auto-mock directory. This tells WebdriverIO where to look for dependencies to mock out.
|
|
102
|
+
* @default ./__mocks__
|
|
103
|
+
*/
|
|
104
|
+
automockDir?: string;
|
|
95
105
|
}
|
|
96
106
|
export interface RunArgs extends Workers.WorkerRunPayload {
|
|
97
107
|
command: string;
|
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;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;
|
|
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;IAC1B;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Options } from '@wdio/types';
|
|
2
|
+
import type { MockRequestEvent } from './types';
|
|
3
|
+
export declare class MockHandler {
|
|
4
|
+
#private;
|
|
5
|
+
manualMocks: string[];
|
|
6
|
+
constructor(options: WebdriverIO.BrowserRunnerOptions, config: Options.Testrunner);
|
|
7
|
+
get mocks(): Map<string, MockRequestEvent>;
|
|
8
|
+
addMock(mock: MockRequestEvent): void;
|
|
9
|
+
unmock(moduleName: string): void;
|
|
10
|
+
resolveId(id: string): Promise<string | undefined>;
|
|
11
|
+
/**
|
|
12
|
+
* reset manual mocks between tests
|
|
13
|
+
*/
|
|
14
|
+
resetMocks(): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=mock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock.d.ts","sourceRoot":"","sources":["../../src/vite/mock.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAI1C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAI/C,qBAAa,WAAW;;IAOpB,WAAW,EAAE,MAAM,EAAE,CAAK;gBAEb,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IAMlF,IAAI,KAAK,kCAER;IAED,OAAO,CAAE,IAAI,EAAE,gBAAgB;IAI/B,MAAM,CAAE,UAAU,EAAE,MAAM;IAIpB,SAAS,CAAE,EAAE,EAAE,MAAM;IAwB3B;;OAEG;IACH,UAAU;CAIb"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getManualMocks } from './utils.js';
|
|
3
|
+
import { DEFAULT_MOCK_DIRECTORY, DEFAULT_AUTOMOCK } from '../constants.js';
|
|
4
|
+
const FIXTURE_PREFIX = '/@fixture/';
|
|
5
|
+
export class MockHandler {
|
|
6
|
+
#automock;
|
|
7
|
+
#automockDir;
|
|
8
|
+
#manualMocksList;
|
|
9
|
+
#mocks = new Map();
|
|
10
|
+
#unmocked = [];
|
|
11
|
+
manualMocks = [];
|
|
12
|
+
constructor(options, config) {
|
|
13
|
+
this.#automock = typeof options.automock === 'boolean' ? options.automock : DEFAULT_AUTOMOCK;
|
|
14
|
+
this.#automockDir = path.resolve(config.rootDir, options.automockDir || DEFAULT_MOCK_DIRECTORY);
|
|
15
|
+
this.#manualMocksList = getManualMocks(this.#automockDir);
|
|
16
|
+
}
|
|
17
|
+
get mocks() {
|
|
18
|
+
return this.#mocks;
|
|
19
|
+
}
|
|
20
|
+
addMock(mock) {
|
|
21
|
+
this.#mocks.set(mock.path, mock);
|
|
22
|
+
}
|
|
23
|
+
unmock(moduleName) {
|
|
24
|
+
this.#unmocked.push(moduleName);
|
|
25
|
+
}
|
|
26
|
+
async resolveId(id) {
|
|
27
|
+
const manualMocksList = await this.#manualMocksList;
|
|
28
|
+
const mockPath = manualMocksList.find((m) => (
|
|
29
|
+
// e.g. someModule
|
|
30
|
+
id === m[1].replace(path.sep, '/') ||
|
|
31
|
+
// e.g. @some/module
|
|
32
|
+
id.slice(1) === m[1].replace(path.sep, '/')));
|
|
33
|
+
/**
|
|
34
|
+
* return manual mock if `automock` is enabled or a manual mock was set via `mock('module')`
|
|
35
|
+
*/
|
|
36
|
+
if ((this.manualMocks.includes(id) || this.#automock) && mockPath && !this.#unmocked.includes(id)) {
|
|
37
|
+
return mockPath[0];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* return fixture
|
|
41
|
+
*/
|
|
42
|
+
if (id.startsWith(FIXTURE_PREFIX)) {
|
|
43
|
+
return path.resolve(this.#automockDir, id.slice(FIXTURE_PREFIX.length));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* reset manual mocks between tests
|
|
48
|
+
*/
|
|
49
|
+
resetMocks() {
|
|
50
|
+
this.manualMocks = [];
|
|
51
|
+
this.#unmocked = [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mockHoisting.d.ts","sourceRoot":"","sources":["../../../src/vite/plugins/mockHoisting.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAM7C,wBAAgB,YAAY,CAAC,WAAW,EAAE,WAAW,GAAG,MAAM,EAAE,CAwM/D"}
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import url from 'node:url';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import logger from '@wdio/logger';
|
|
6
|
+
import { parse, print, visit, types } from 'recast';
|
|
7
|
+
import typescriptParser from 'recast/parsers/typescript.js';
|
|
8
|
+
const log = logger('@wdio/browser-runner:mockHoisting');
|
|
9
|
+
const b = types.builders;
|
|
10
|
+
const MOCK_PREFIX = '/@mock';
|
|
11
|
+
export function mockHoisting(mockHandler) {
|
|
12
|
+
let spec = null;
|
|
13
|
+
return [{
|
|
14
|
+
name: 'wdio:mockHoisting:pre',
|
|
15
|
+
enforce: 'pre',
|
|
16
|
+
resolveId: mockHandler.resolveId.bind(mockHandler),
|
|
17
|
+
load: async function (id) {
|
|
18
|
+
if (id.startsWith(MOCK_PREFIX)) {
|
|
19
|
+
try {
|
|
20
|
+
const orig = await fs.readFile(id.slice(MOCK_PREFIX.length + (os.platform() === 'win32' ? 1 : 0)));
|
|
21
|
+
return orig.toString();
|
|
22
|
+
}
|
|
23
|
+
catch (err) {
|
|
24
|
+
log.error(`Failed to read file (${id}) for mocking: ${err.message}`);
|
|
25
|
+
return '';
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
const mockedMod = (
|
|
29
|
+
// mocked file
|
|
30
|
+
mockHandler.mocks.get(os.platform() === 'win32' ? `/${id}` : id) ||
|
|
31
|
+
// mocked dependency
|
|
32
|
+
mockHandler.mocks.get(path.basename(id, path.extname(id))));
|
|
33
|
+
if (mockedMod) {
|
|
34
|
+
const newCode = mockedMod.namedExports.map((ne) => {
|
|
35
|
+
if (ne === 'default') {
|
|
36
|
+
return /*js*/ `export default window.__wdioMockFactories__['${mockedMod.path}'].default;`;
|
|
37
|
+
}
|
|
38
|
+
return /*js*/ `export const ${ne} = window.__wdioMockFactories__['${mockedMod.path}']['${ne}'];`;
|
|
39
|
+
});
|
|
40
|
+
if (!mockedMod.namedExports.includes('default')) {
|
|
41
|
+
newCode.push(/*js*/ `export default window.__wdioMockFactories__['${mockedMod.path}'];`);
|
|
42
|
+
}
|
|
43
|
+
log.debug(`Resolve mock for module "${mockedMod.path}"`);
|
|
44
|
+
return newCode.join('\n');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}, {
|
|
48
|
+
name: 'wdio:mockHoisting',
|
|
49
|
+
enforce: 'post',
|
|
50
|
+
transform(code, id) {
|
|
51
|
+
/**
|
|
52
|
+
* only transform when spec file is transformed
|
|
53
|
+
*/
|
|
54
|
+
if (id !== spec) {
|
|
55
|
+
return { code };
|
|
56
|
+
}
|
|
57
|
+
const ast = parse(code, {
|
|
58
|
+
parser: typescriptParser,
|
|
59
|
+
sourceFileName: id,
|
|
60
|
+
sourceRoot: path.dirname(id)
|
|
61
|
+
});
|
|
62
|
+
let mockFunctionName;
|
|
63
|
+
let unmockFunctionName;
|
|
64
|
+
const mockCalls = [];
|
|
65
|
+
/**
|
|
66
|
+
* rewrite import statements into variable declarations, e.g. from
|
|
67
|
+
*
|
|
68
|
+
* import React, { RC } from 'react'
|
|
69
|
+
*
|
|
70
|
+
* to
|
|
71
|
+
*
|
|
72
|
+
* var { default: React, RC: RC } = await import("react")
|
|
73
|
+
*
|
|
74
|
+
* so we can hoist the mock call
|
|
75
|
+
*/
|
|
76
|
+
visit(ast, {
|
|
77
|
+
visitImportDeclaration: function (path) {
|
|
78
|
+
const dec = path.value;
|
|
79
|
+
const source = dec.source.value;
|
|
80
|
+
/**
|
|
81
|
+
* get name of mock function variable
|
|
82
|
+
*/
|
|
83
|
+
if (source === '@wdio/browser-runner') {
|
|
84
|
+
const mockSpecifier = dec.specifiers
|
|
85
|
+
.filter((s) => s.type === types.namedTypes.ImportSpecifier.toString())
|
|
86
|
+
.find((s) => s.imported.name === 'mock');
|
|
87
|
+
if (mockSpecifier && mockSpecifier.local) {
|
|
88
|
+
mockFunctionName = mockSpecifier.local.name;
|
|
89
|
+
}
|
|
90
|
+
const unmockSpecifier = dec.specifiers
|
|
91
|
+
.filter((s) => s.type === types.namedTypes.ImportSpecifier.toString())
|
|
92
|
+
.find((s) => s.imported.name === 'unmock');
|
|
93
|
+
if (unmockSpecifier && unmockSpecifier.local) {
|
|
94
|
+
unmockFunctionName = unmockSpecifier.local.name;
|
|
95
|
+
}
|
|
96
|
+
mockCalls.push(dec);
|
|
97
|
+
path.prune();
|
|
98
|
+
return this.traverse(path);
|
|
99
|
+
}
|
|
100
|
+
const newNode = b.variableDeclaration('const', [
|
|
101
|
+
b.variableDeclarator((dec.specifiers?.length === 1 && dec.specifiers[0].type === types.namedTypes.ImportNamespaceSpecifier.toString())
|
|
102
|
+
/**
|
|
103
|
+
* we deal with a ImportNamespaceSpecifier, e.g.:
|
|
104
|
+
* import * as foo from 'bar'
|
|
105
|
+
*/
|
|
106
|
+
? dec.specifiers[0].local
|
|
107
|
+
/**
|
|
108
|
+
* we deal with default or named import, e.g.
|
|
109
|
+
* import foo from 'bar'
|
|
110
|
+
* or
|
|
111
|
+
* import { foo } from 'bar'
|
|
112
|
+
*/
|
|
113
|
+
: b.objectPattern(dec.specifiers.map((s) => {
|
|
114
|
+
if (s.type === types.namedTypes.ImportDefaultSpecifier.toString()) {
|
|
115
|
+
return b.property('init', b.identifier('default'), b.identifier(s.local.name));
|
|
116
|
+
}
|
|
117
|
+
return b.property('init', b.identifier(s.imported.name), b.identifier(s.local.name));
|
|
118
|
+
})), b.awaitExpression(b.importExpression(b.literal(source))))
|
|
119
|
+
]);
|
|
120
|
+
path.replace(newNode);
|
|
121
|
+
this.traverse(path);
|
|
122
|
+
},
|
|
123
|
+
visitExpressionStatement: function (path) {
|
|
124
|
+
const exp = path.value;
|
|
125
|
+
if (exp.expression.type !== types.namedTypes.CallExpression.toString()) {
|
|
126
|
+
return this.traverse(path);
|
|
127
|
+
}
|
|
128
|
+
const callExp = exp.expression;
|
|
129
|
+
const isUnmockCall = unmockFunctionName && callExp.callee.name === unmockFunctionName;
|
|
130
|
+
const isMockCall = mockFunctionName && callExp.callee.name === mockFunctionName;
|
|
131
|
+
if (!isMockCall && !isUnmockCall) {
|
|
132
|
+
return this.traverse(path);
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* hoist unmock calls
|
|
136
|
+
*/
|
|
137
|
+
if (isUnmockCall && callExp.arguments[0] && typeof callExp.arguments[0].value === 'string') {
|
|
138
|
+
mockHandler.unmock(callExp.arguments[0].value);
|
|
139
|
+
}
|
|
140
|
+
else if (isMockCall) {
|
|
141
|
+
/**
|
|
142
|
+
* if only one mock argument is set, we take the fixture from the automock directory
|
|
143
|
+
*/
|
|
144
|
+
const mockCall = exp.expression;
|
|
145
|
+
if (mockCall.arguments.length === 1) {
|
|
146
|
+
/**
|
|
147
|
+
* enable manual mock
|
|
148
|
+
*/
|
|
149
|
+
mockHandler.manualMocks.push(mockCall.arguments[0].value);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
/**
|
|
153
|
+
* hoist mock calls
|
|
154
|
+
*/
|
|
155
|
+
mockCalls.push(exp);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
path.prune();
|
|
159
|
+
this.traverse(path);
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
ast.program.body.unshift(...mockCalls.map((mc) => {
|
|
163
|
+
const exp = mc;
|
|
164
|
+
if (exp.expression && exp.expression.type === types.namedTypes.CallExpression.toString()) {
|
|
165
|
+
return b.expressionStatement(b.awaitExpression(exp.expression));
|
|
166
|
+
}
|
|
167
|
+
return mc;
|
|
168
|
+
}));
|
|
169
|
+
const newCode = print(ast, {
|
|
170
|
+
sourceMapName: id
|
|
171
|
+
});
|
|
172
|
+
return newCode;
|
|
173
|
+
},
|
|
174
|
+
configureServer(server) {
|
|
175
|
+
return () => {
|
|
176
|
+
server.middlewares.use('/', async (req, res, next) => {
|
|
177
|
+
if (!req.url) {
|
|
178
|
+
return next();
|
|
179
|
+
}
|
|
180
|
+
const urlParsed = url.parse(req.url);
|
|
181
|
+
const urlParamString = new URLSearchParams(urlParsed.query || '');
|
|
182
|
+
const specParam = urlParamString.get('spec');
|
|
183
|
+
if (specParam) {
|
|
184
|
+
mockHandler.resetMocks();
|
|
185
|
+
spec = os.platform() === 'win32' ? specParam.slice(1) : specParam;
|
|
186
|
+
}
|
|
187
|
+
return next();
|
|
188
|
+
});
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
}];
|
|
192
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testrunner.d.ts","sourceRoot":"","sources":["../../../src/vite/plugins/testrunner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"testrunner.d.ts","sourceRoot":"","sources":["../../../src/vite/plugins/testrunner.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AA0ClC,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,oBAAoB,GAAG,MAAM,EAAE,CAgI9E"}
|
|
@@ -25,8 +25,7 @@ const POLYFILLS = [
|
|
|
25
25
|
const FETCH_FROM_ESM = [
|
|
26
26
|
'serialize-error', 'minimatch', 'css-shorthand-properties', 'lodash.merge', 'lodash.zip',
|
|
27
27
|
'lodash.clonedeep', 'lodash.pickby', 'lodash.flattendeep', 'aria-query', 'grapheme-splitter',
|
|
28
|
-
'css-value', 'rgb2hex', 'p-iteration', 'fast-safe-stringify', 'deepmerge-ts'
|
|
29
|
-
'mocha'
|
|
28
|
+
'css-value', 'rgb2hex', 'p-iteration', 'fast-safe-stringify', 'deepmerge-ts'
|
|
30
29
|
];
|
|
31
30
|
export function testrunner(options) {
|
|
32
31
|
const automationProtocolPath = `/@fs${url.pathToFileURL(path.resolve(__dirname, '..', '..', 'browser', 'driver.js')).pathname}`;
|
|
@@ -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;AAGvD,OAAO,KAAK,EAAY,OAAO,EAAE,MAAM,aAAa,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;AAQpD,OAAO,KAAK,EACM,gBAAgB,EAEjC,MAAM,YAAY,CAAA;AAYnB,qBAAa,UAAW,SAAQ,YAAY;;IASxC,IAAI,YAAY,gCAEf;IAED,IAAI,MAAM,0BAET;gBAEY,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IAiC5E,KAAK;IAwCL,KAAK;IAkJX,OAAO,CAAC,cAAc;IAetB,WAAW,CAAE,MAAM,EAAE,gBAAgB;CAUxC"}
|
package/build/vite/server.js
CHANGED
|
@@ -8,7 +8,9 @@ import { executeHooksWithArgs } from '@wdio/utils';
|
|
|
8
8
|
import { createServer } from 'vite';
|
|
9
9
|
import istanbulPlugin from 'vite-plugin-istanbul';
|
|
10
10
|
import { testrunner } from './plugins/testrunner.js';
|
|
11
|
+
import { mockHoisting } from './plugins/mockHoisting.js';
|
|
11
12
|
import { userfriendlyImport } from './utils.js';
|
|
13
|
+
import { MockHandler } from './mock.js';
|
|
12
14
|
import { PRESET_DEPENDENCIES, DEFAULT_VITE_CONFIG } from './constants.js';
|
|
13
15
|
import { MESSAGE_TYPES, DEFAULT_INCLUDE, DEFAULT_FILE_EXTENSIONS } from '../constants.js';
|
|
14
16
|
import { BROWSER_POOL, SESSIONS } from '../constants.js';
|
|
@@ -21,6 +23,7 @@ export class ViteServer extends EventEmitter {
|
|
|
21
23
|
#viteConfig;
|
|
22
24
|
#wss;
|
|
23
25
|
#server;
|
|
26
|
+
#mockHandler;
|
|
24
27
|
get socketServer() {
|
|
25
28
|
return this.#wss;
|
|
26
29
|
}
|
|
@@ -30,12 +33,16 @@ export class ViteServer extends EventEmitter {
|
|
|
30
33
|
constructor(options, config) {
|
|
31
34
|
super();
|
|
32
35
|
this.#options = options;
|
|
36
|
+
this.#mockHandler = new MockHandler(options, config);
|
|
33
37
|
if (options.preset && options.viteConfig) {
|
|
34
38
|
throw new Error('Invalid runner configuration: "preset" and "viteConfig" options are defined but only one of each can be used at the same time');
|
|
35
39
|
}
|
|
36
40
|
this.#viteConfig = deepmerge(DEFAULT_VITE_CONFIG, {
|
|
37
41
|
root: options.rootDir || process.cwd(),
|
|
38
|
-
plugins: [
|
|
42
|
+
plugins: [
|
|
43
|
+
testrunner(options),
|
|
44
|
+
mockHoisting(this.#mockHandler)
|
|
45
|
+
]
|
|
39
46
|
});
|
|
40
47
|
if (options.coverage && options.coverage.enabled) {
|
|
41
48
|
log.info('Capturing test coverage enabled');
|
|
@@ -110,6 +117,13 @@ export class ViteServer extends EventEmitter {
|
|
|
110
117
|
if (payload.type === MESSAGE_TYPES.commandRequestMessage) {
|
|
111
118
|
return this.#handleCommand(ws, payload.value);
|
|
112
119
|
}
|
|
120
|
+
if (payload.type === MESSAGE_TYPES.mockRequest) {
|
|
121
|
+
this.#mockHandler.addMock(payload.value);
|
|
122
|
+
return ws.send(JSON.stringify({
|
|
123
|
+
type: MESSAGE_TYPES.mockResponse,
|
|
124
|
+
value: payload.value
|
|
125
|
+
}));
|
|
126
|
+
}
|
|
113
127
|
throw new Error(`Unknown socket message ${JSON.stringify(payload)}`);
|
|
114
128
|
}
|
|
115
129
|
catch (err) {
|
package/build/vite/types.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export type SocketMessageValue = {
|
|
|
10
10
|
[MESSAGE_TYPES.commandResponseMessage]: CommandResponseEvent;
|
|
11
11
|
[MESSAGE_TYPES.hookTriggerMessage]: HookTriggerEvent;
|
|
12
12
|
[MESSAGE_TYPES.hookResultMessage]: HookResultEvent;
|
|
13
|
+
[MESSAGE_TYPES.mockRequest]: MockRequestEvent;
|
|
14
|
+
[MESSAGE_TYPES.mockResponse]: MockResponseEvent;
|
|
13
15
|
};
|
|
14
16
|
export type SocketMessagePayload<T extends MESSAGE_TYPES> = T extends any ? SocketMessagePayloadType<T> : never;
|
|
15
17
|
export type SocketMessage = SocketMessagePayload<MESSAGE_TYPES>;
|
|
@@ -40,5 +42,13 @@ export interface CommandResponseEvent {
|
|
|
40
42
|
result?: unknown;
|
|
41
43
|
error?: ErrorObject;
|
|
42
44
|
}
|
|
45
|
+
export interface MockRequestEvent {
|
|
46
|
+
path: string;
|
|
47
|
+
origin: string;
|
|
48
|
+
namedExports: string[];
|
|
49
|
+
}
|
|
50
|
+
export interface MockResponseEvent {
|
|
51
|
+
path: string;
|
|
52
|
+
}
|
|
43
53
|
export {};
|
|
44
54
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vite/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,UAAU,wBAAwB,CAAC,CAAC,SAAS,aAAa;IACtD,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAA;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC7B,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;IAC5C,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE,mBAAmB,CAAA;IAC1D,CAAC,aAAa,CAAC,sBAAsB,CAAC,EAAE,oBAAoB,CAAA;IAC5D,CAAC,aAAa,CAAC,kBAAkB,CAAC,EAAE,gBAAgB,CAAA;IACpD,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/vite/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAEpD,UAAU,wBAAwB,CAAC,CAAC,SAAS,aAAa;IACtD,IAAI,EAAE,CAAC,CAAC;IACR,KAAK,EAAE,kBAAkB,CAAC,CAAC,CAAC,CAAA;CAC/B;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC7B,CAAC,aAAa,CAAC,cAAc,CAAC,EAAE,YAAY,CAAA;IAC5C,CAAC,aAAa,CAAC,qBAAqB,CAAC,EAAE,mBAAmB,CAAA;IAC1D,CAAC,aAAa,CAAC,sBAAsB,CAAC,EAAE,oBAAoB,CAAA;IAC5D,CAAC,aAAa,CAAC,kBAAkB,CAAC,EAAE,gBAAgB,CAAA;IACpD,CAAC,aAAa,CAAC,iBAAiB,CAAC,EAAE,eAAe,CAAA;IAClD,CAAC,aAAa,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAA;IAC7C,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAA;CAClD,CAAA;AAED,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,aAAa,IAAI,CAAC,SAAS,GAAG,GACnE,wBAAwB,CAAC,CAAC,CAAC,GAC3B,KAAK,CAAA;AAEX,MAAM,MAAM,aAAa,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAA;AAE/D,MAAM,WAAW,YAAY;IACzB,IAAI,EAAE,cAAc,CAAA;IACpB,IAAI,EAAE,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;IACjD,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,GAAG,EAAE,MAAM,CAAA;CACd;AAED,UAAU,2BAA2B;IACjC,EAAE,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,gBAAiB,SAAQ,2BAA2B;IACjE,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,OAAO,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,eAAgB,SAAQ,2BAA2B;IAChE,KAAK,CAAC,EAAE,WAAW,CAAA;CACtB;AAED,MAAM,WAAW,mBAAoB,SAAQ,2BAA2B;IACpE,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,OAAO,EAAE,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,KAAK,CAAC,EAAE,WAAW,CAAA;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,EAAE,MAAM,EAAE,CAAA;CACzB;AAED,MAAM,WAAW,iBAAiB;IAC9B,IAAI,EAAE,MAAM,CAAA;CACf"}
|
package/build/vite/utils.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import type { Environment, FrameworkPreset } from '../types.js';
|
|
2
|
-
export declare function getTemplate(options: WebdriverIO.BrowserRunnerOptions, env: Environment, spec: string): Promise<string>;
|
|
3
|
+
export declare function getTemplate(options: WebdriverIO.BrowserRunnerOptions, env: Environment, spec: string, processEnv?: NodeJS.ProcessEnv): Promise<string>;
|
|
3
4
|
export declare function userfriendlyImport(preset: FrameworkPreset, pkg?: string): Promise<any>;
|
|
4
5
|
export declare function normalizeId(id: string, base?: string): string;
|
|
6
|
+
export declare function getFilesFromDirectory(dir: string): Promise<string[]>;
|
|
7
|
+
export declare function getManualMocks(automockDir: string): Promise<[string, string][]>;
|
|
5
8
|
export declare function getErrorTemplate(filename: string, error: Error): string;
|
|
6
9
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/vite/utils.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE/D,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/vite/utils.ts"],"names":[],"mappings":";AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAE/D,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,oBAAc,mBAsFpI;AAED,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,MAAM,gBAa7E;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAY7D;AAED,wBAAsB,qBAAqB,CAAE,GAAG,EAAE,MAAM,qBAavD;AAGD,wBAAsB,cAAc,CAAC,WAAW,EAAE,MAAM,+BAgBvD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,UAU9D"}
|
package/build/vite/utils.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import url from 'node:url';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { resolve } from 'import-meta-resolve';
|
|
5
|
-
export async function getTemplate(options, env, spec) {
|
|
5
|
+
export async function getTemplate(options, env, spec, processEnv = process.env) {
|
|
6
6
|
const root = options.rootDir || process.cwd();
|
|
7
7
|
const rootFileUrl = url.pathToFileURL(root).href;
|
|
8
8
|
let vueDeps = '';
|
|
@@ -30,14 +30,19 @@ export async function getTemplate(options, env, spec) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
const mochaCSSHref = await resolve('mocha', `${rootFileUrl}/node_modules`).then((p) => path.join(url.fileURLToPath(path.dirname(p)), 'mocha.css'), () => 'https://unpkg.com/mocha@10.0.0/mocha.css');
|
|
33
|
+
const mochaJSSrc = await resolve('mocha', `${rootFileUrl}/node_modules`).then((p) => path.join(url.fileURLToPath(path.dirname(p)), 'mocha.js'), () => 'https://unpkg.com/mocha@10.0.0/mocha.js');
|
|
34
|
+
const sourceMapSupportDir = path.dirname(url.fileURLToPath(await resolve('source-map-support', import.meta.url)));
|
|
33
35
|
return /* html */ `
|
|
34
36
|
<!doctype html>
|
|
35
37
|
<html>
|
|
36
38
|
<head>
|
|
37
39
|
<title>WebdriverIO Browser Test</title>
|
|
38
40
|
<link rel="icon" type="image/x-icon" href="https://webdriver.io/img/favicon.png">
|
|
39
|
-
<link rel="stylesheet" href="${mochaCSSHref}">
|
|
41
|
+
<link rel="stylesheet" href="${mochaCSSHref}"><script type="module" src="${mochaJSSrc}"></script>
|
|
42
|
+
<script src="/@fs/${sourceMapSupportDir}/browser-source-map-support.js"></script>
|
|
40
43
|
<script type="module">
|
|
44
|
+
sourceMapSupport.install()
|
|
45
|
+
|
|
41
46
|
/**
|
|
42
47
|
* Inject environment variables
|
|
43
48
|
*/
|
|
@@ -50,7 +55,8 @@ export async function getTemplate(options, env, spec) {
|
|
|
50
55
|
window.__wdioErrors__ = []
|
|
51
56
|
addEventListener('error', (ev) => window.__wdioErrors__.push({
|
|
52
57
|
filename: ev.filename,
|
|
53
|
-
message: ev.message
|
|
58
|
+
message: ev.message,
|
|
59
|
+
error: ev.error.stack
|
|
54
60
|
}))
|
|
55
61
|
/**
|
|
56
62
|
* mock process
|
|
@@ -65,6 +71,9 @@ export async function getTemplate(options, env, spec) {
|
|
|
65
71
|
<body>
|
|
66
72
|
<div id="mocha"></div>
|
|
67
73
|
<script async type="module" src="@wdio/browser-runner/setup"></script>
|
|
74
|
+
<script type="module">
|
|
75
|
+
window.process.env = ${JSON.stringify(processEnv)}
|
|
76
|
+
</script>
|
|
68
77
|
</body>
|
|
69
78
|
</html>`;
|
|
70
79
|
}
|
|
@@ -92,6 +101,37 @@ export function normalizeId(id, base) {
|
|
|
92
101
|
.replace(/[?&]v=\w+/, '?') // remove ?v= query
|
|
93
102
|
.replace(/\?$/, ''); // remove end query mark
|
|
94
103
|
}
|
|
104
|
+
export async function getFilesFromDirectory(dir) {
|
|
105
|
+
let files = await fs.readdir(dir);
|
|
106
|
+
files = (await Promise.all(files.map(async (file) => {
|
|
107
|
+
const filePath = path.join(dir, file);
|
|
108
|
+
const stats = await fs.stat(filePath);
|
|
109
|
+
if (stats.isDirectory()) {
|
|
110
|
+
return getFilesFromDirectory(filePath);
|
|
111
|
+
}
|
|
112
|
+
else if (stats.isFile()) {
|
|
113
|
+
return filePath;
|
|
114
|
+
}
|
|
115
|
+
}))).filter(Boolean);
|
|
116
|
+
return files.reduce((all, folderContents) => all.concat(folderContents), []);
|
|
117
|
+
}
|
|
118
|
+
let mockedModulesList;
|
|
119
|
+
export async function getManualMocks(automockDir) {
|
|
120
|
+
/**
|
|
121
|
+
* read available mocks only one time
|
|
122
|
+
*/
|
|
123
|
+
if (!mockedModulesList) {
|
|
124
|
+
mockedModulesList = (await getFilesFromDirectory(automockDir))
|
|
125
|
+
/**
|
|
126
|
+
* seperate to module name and actual path
|
|
127
|
+
*/
|
|
128
|
+
.map((filePath) => [
|
|
129
|
+
filePath,
|
|
130
|
+
filePath.slice(automockDir.length + 1).slice(0, -path.extname(filePath).length)
|
|
131
|
+
]);
|
|
132
|
+
}
|
|
133
|
+
return mockedModulesList;
|
|
134
|
+
}
|
|
95
135
|
export function getErrorTemplate(filename, error) {
|
|
96
136
|
return /*html*/ `
|
|
97
137
|
<pre>${error.stack}</pre>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/browser-runner",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.4.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",
|
|
@@ -31,14 +31,15 @@
|
|
|
31
31
|
"@originjs/vite-plugin-commonjs": "^1.0.3",
|
|
32
32
|
"@types/istanbul-lib-source-maps": "^4.0.1",
|
|
33
33
|
"@types/node": "^18.14.0",
|
|
34
|
-
"@vitest/spy": "^0.
|
|
35
|
-
"@wdio/globals": "8.
|
|
36
|
-
"@wdio/local-runner": "8.
|
|
34
|
+
"@vitest/spy": "^0.29.1",
|
|
35
|
+
"@wdio/globals": "8.4.0",
|
|
36
|
+
"@wdio/local-runner": "8.4.0",
|
|
37
37
|
"@wdio/logger": "8.1.0",
|
|
38
|
-
"@wdio/mocha-framework": "8.
|
|
38
|
+
"@wdio/mocha-framework": "8.4.0",
|
|
39
39
|
"@wdio/protocols": "8.3.11",
|
|
40
|
-
"@wdio/types": "8.
|
|
41
|
-
"@wdio/utils": "8.
|
|
40
|
+
"@wdio/types": "8.4.0",
|
|
41
|
+
"@wdio/utils": "8.4.0",
|
|
42
|
+
"ast-types": "^0.14.2",
|
|
42
43
|
"deepmerge-ts": "^4.3.0",
|
|
43
44
|
"expect-webdriverio": "^4.1.2",
|
|
44
45
|
"fast-safe-stringify": "^2.1.1",
|
|
@@ -49,12 +50,14 @@
|
|
|
49
50
|
"istanbul-lib-source-maps": "^4.0.1",
|
|
50
51
|
"istanbul-reports": "^3.1.5",
|
|
51
52
|
"modern-node-polyfills": "^0.1.0",
|
|
53
|
+
"recast": "^0.22.0",
|
|
52
54
|
"serialize-error": "^11.0.0",
|
|
55
|
+
"source-map-support": "^0.5.21",
|
|
53
56
|
"vite": "^4.1.3",
|
|
54
57
|
"vite-plugin-istanbul": "^4.0.0",
|
|
55
58
|
"vite-plugin-top-level-await": "^1.2.4",
|
|
56
|
-
"webdriver": "8.
|
|
57
|
-
"webdriverio": "8.
|
|
59
|
+
"webdriver": "8.4.0",
|
|
60
|
+
"webdriverio": "8.4.0",
|
|
58
61
|
"ws": "^8.12.1"
|
|
59
62
|
},
|
|
60
63
|
"scripts": {
|
|
@@ -65,7 +68,7 @@
|
|
|
65
68
|
},
|
|
66
69
|
"devDependencies": {
|
|
67
70
|
"@types/ws": "^8.5.4",
|
|
68
|
-
"@wdio/runner": "8.
|
|
71
|
+
"@wdio/runner": "8.4.0"
|
|
69
72
|
},
|
|
70
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "5d003ce35250c9d9dcecc9fd13a97257d6b349fe"
|
|
71
74
|
}
|