@wdio/browser-runner 8.3.4 → 8.3.5

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.
@@ -1,3 +1,3 @@
1
1
  import type { Plugin } from 'vite';
2
- export declare function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin;
2
+ export declare function testrunner(options: WebdriverIO.BrowserRunnerOptions): Plugin[];
3
3
  //# sourceMappingURL=testrunner.d.ts.map
@@ -1 +1 @@
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,CAkH7E"}
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;AA2ClC,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,CAAC,oBAAoB,GAAG,MAAM,EAAE,CAgI9E"}
@@ -1,11 +1,13 @@
1
1
  import url from 'node:url';
2
2
  import path from 'node:path';
3
+ import { builtinModules } from 'node:module';
3
4
  import logger from '@wdio/logger';
5
+ import { polyfillPath } from 'modern-node-polyfills';
4
6
  import { deepmerge } from 'deepmerge-ts';
5
7
  import { resolve } from 'import-meta-resolve';
6
8
  import { WebDriverProtocol, MJsonWProtocol, JsonWProtocol, AppiumProtocol, ChromiumProtocol, SauceLabsProtocol, SeleniumProtocol, GeckoProtocol, WebDriverBidiProtocol } from '@wdio/protocols';
7
9
  import { SESSIONS } from '../../constants.js';
8
- import { getTemplate, getErrorTemplate } from '../utils.js';
10
+ import { getTemplate, getErrorTemplate, normalizeId } from '../utils.js';
9
11
  const log = logger('@wdio/browser-runner:plugin');
10
12
  const __dirname = url.fileURLToPath(new URL('.', import.meta.url));
11
13
  const commands = deepmerge(WebDriverProtocol, MJsonWProtocol, JsonWProtocol, AppiumProtocol, ChromiumProtocol, SauceLabsProtocol, SeleniumProtocol, GeckoProtocol, WebDriverBidiProtocol);
@@ -14,13 +16,16 @@ const WDIO_PACKAGES = ['webdriverio', 'expect-webdriverio'];
14
16
  const virtualModuleId = 'virtual:wdio';
15
17
  const resolvedVirtualModuleId = '\0' + virtualModuleId;
16
18
  const MODULES_TO_MOCK = [
17
- 'node:url', 'node:module', 'node:events', 'node:path', 'node:os',
18
19
  'import-meta-resolve', 'puppeteer-core', 'archiver', 'glob', 'devtools', 'ws'
19
20
  ];
21
+ const POLYFILLS = [
22
+ ...builtinModules,
23
+ ...builtinModules.map((m) => `node:${m}`)
24
+ ].map((m) => m.replace('/promises', ''));
20
25
  const FETCH_FROM_ESM = [
21
26
  'serialize-error', 'minimatch', 'css-shorthand-properties', 'lodash.merge', 'lodash.zip',
22
27
  'lodash.clonedeep', 'lodash.pickby', 'lodash.flattendeep', 'aria-query', 'grapheme-splitter',
23
- 'css-value', 'rgb2hex', 'p-iteration', 'fast-safe-stringify', 'deepmerge-ts', 'is-plain-obj',
28
+ 'css-value', 'rgb2hex', 'p-iteration', 'fast-safe-stringify', 'deepmerge-ts',
24
29
  'mocha'
25
30
  ];
26
31
  export function testrunner(options) {
@@ -28,95 +33,107 @@ export function testrunner(options) {
28
33
  const mockModulePath = path.resolve(__dirname, '..', '..', 'browser', 'mock.js');
29
34
  const setupModulePath = path.resolve(__dirname, '..', '..', 'browser', 'setup.js');
30
35
  const spyModulePath = path.resolve(__dirname, '..', '..', 'browser', 'spy.js');
31
- return {
32
- name: 'wdio:testrunner',
33
- enforce: 'pre',
34
- resolveId: async (id) => {
35
- if (id === virtualModuleId) {
36
- return resolvedVirtualModuleId;
37
- }
38
- if (id === '@wdio/browser-runner') {
39
- return spyModulePath;
40
- }
41
- if (id.endsWith('@wdio/browser-runner/setup')) {
42
- return setupModulePath;
43
- }
44
- /**
45
- * make sure WDIO imports are resolved properly as ESM module
46
- */
47
- if (id.startsWith('@wdio') || WDIO_PACKAGES.includes(id)) {
48
- return url.fileURLToPath(await resolve(id, import.meta.url));
49
- }
50
- /**
51
- * mock out imports that we can't transpile into browser land
52
- */
53
- if (MODULES_TO_MOCK.includes(id)) {
54
- return mockModulePath;
55
- }
56
- /**
57
- * some dependencies used by WebdriverIO packages are still using CJS
58
- * so we need to pull them from esm.sh to have them run in the browser
59
- */
60
- if (FETCH_FROM_ESM.includes(id)) {
61
- return `https://esm.sh/${id}`;
62
- }
63
- },
64
- load(id) {
65
- /**
66
- * provide a list of protocol commands to generate the prototype in the browser
67
- */
68
- if (id === resolvedVirtualModuleId) {
69
- return /*js*/ `
36
+ return [{
37
+ name: 'wdio:testrunner',
38
+ enforce: 'pre',
39
+ resolveId: async (id) => {
40
+ if (id === virtualModuleId) {
41
+ return resolvedVirtualModuleId;
42
+ }
43
+ if (POLYFILLS.includes(id)) {
44
+ return polyfillPath(normalizeId(id));
45
+ }
46
+ if (id === '@wdio/browser-runner') {
47
+ return spyModulePath;
48
+ }
49
+ if (id.endsWith('@wdio/browser-runner/setup')) {
50
+ return setupModulePath;
51
+ }
52
+ /**
53
+ * make sure WDIO imports are resolved properly as ESM module
54
+ */
55
+ if (id.startsWith('@wdio') || WDIO_PACKAGES.includes(id)) {
56
+ return url.fileURLToPath(await resolve(id, import.meta.url));
57
+ }
58
+ /**
59
+ * mock out imports that we can't transpile into browser land
60
+ */
61
+ if (MODULES_TO_MOCK.includes(id)) {
62
+ return mockModulePath;
63
+ }
64
+ /**
65
+ * some dependencies used by WebdriverIO packages are still using CJS
66
+ * so we need to pull them from esm.sh to have them run in the browser
67
+ */
68
+ if (FETCH_FROM_ESM.includes(id)) {
69
+ return `https://esm.sh/${id}`;
70
+ }
71
+ },
72
+ load(id) {
73
+ /**
74
+ * provide a list of protocol commands to generate the prototype in the browser
75
+ */
76
+ if (id === resolvedVirtualModuleId) {
77
+ return /*js*/ `
70
78
  export const commands = ${JSON.stringify(protocolCommandList)}
71
79
  export const automationProtocolPath = ${JSON.stringify(automationProtocolPath)}
72
80
  `;
73
- }
74
- },
75
- transform(code, id) {
76
- if (id.includes('.vite/deps/expect.js')) {
77
- return {
78
- code: code.replace('var fs = _interopRequireWildcard(require_graceful_fs());', 'var fs = {};').replace('var expect_default = require_build11();', 'var expect_default = require_build11();\nwindow.expect = expect_default.default;').replace('process.stdout.isTTY', 'false')
81
+ }
82
+ },
83
+ transform(code, id) {
84
+ if (id.includes('.vite/deps/expect.js')) {
85
+ return {
86
+ code: code.replace('var fs = _interopRequireWildcard(require_graceful_fs());', 'var fs = {};').replace('var expect_default = require_build11();', 'var expect_default = require_build11();\nwindow.expect = expect_default.default;').replace('process.stdout.isTTY', 'false')
87
+ };
88
+ }
89
+ return { code };
90
+ },
91
+ configureServer(server) {
92
+ return () => {
93
+ server.middlewares.use('/', async (req, res, next) => {
94
+ log.info(`Received request for: ${req.url}`);
95
+ if (!req.url) {
96
+ return next();
97
+ }
98
+ const urlParsed = url.parse(req.url);
99
+ // if request is not html , directly return next()
100
+ if (!urlParsed.pathname || !urlParsed.path || !urlParsed.pathname.endsWith('test.html')) {
101
+ return next();
102
+ }
103
+ const urlParamString = new URLSearchParams(urlParsed.query || '');
104
+ const [cid] = urlParsed.pathname.slice(1).split('/');
105
+ const spec = urlParamString.get('spec');
106
+ if (!cid || !SESSIONS.has(cid)) {
107
+ log.error(`No environment found for ${cid || 'non determined environment'}`);
108
+ return next();
109
+ }
110
+ if (!spec) {
111
+ log.error('No spec file was defined to run for this environment');
112
+ return next();
113
+ }
114
+ const env = SESSIONS.get(cid);
115
+ try {
116
+ const template = await getTemplate(options, env, spec);
117
+ log.debug(`Render template for ${req.url}`);
118
+ res.end(await server.transformIndexHtml(`${req.url}`, template));
119
+ }
120
+ catch (err) {
121
+ const template = getErrorTemplate(req.url, err);
122
+ log.error(`Failed to render template: ${err.message}`);
123
+ res.end(await server.transformIndexHtml(`${req.url}`, template));
124
+ }
125
+ return next();
126
+ });
79
127
  };
80
128
  }
81
- return { code };
82
- },
83
- configureServer(server) {
84
- return () => {
85
- server.middlewares.use('/', async (req, res, next) => {
86
- log.info(`Received request for: ${req.url}`);
87
- if (!req.url) {
88
- return next();
89
- }
90
- const urlParsed = url.parse(req.url);
91
- // if request is not html , directly return next()
92
- if (!urlParsed.pathname || !urlParsed.path || !urlParsed.pathname.endsWith('test.html')) {
93
- return next();
94
- }
95
- const urlParamString = new URLSearchParams(urlParsed.query || '');
96
- const [cid] = urlParsed.pathname.slice(1).split('/');
97
- const spec = urlParamString.get('spec');
98
- if (!cid || !SESSIONS.has(cid)) {
99
- log.error(`No environment found for ${cid || 'non determined environment'}`);
100
- return next();
101
- }
102
- if (!spec) {
103
- log.error('No spec file was defined to run for this environment');
104
- return next();
105
- }
106
- const env = SESSIONS.get(cid);
107
- try {
108
- const template = await getTemplate(options, env, spec);
109
- log.debug(`Render template for ${req.url}`);
110
- res.end(await server.transformIndexHtml(`${req.url}`, template));
111
- }
112
- catch (err) {
113
- const template = getErrorTemplate(req.url, err);
114
- log.error(`Failed to render template: ${err.message}`);
115
- res.end(await server.transformIndexHtml(`${req.url}`, template));
116
- }
117
- return next();
118
- });
119
- };
120
- }
121
- };
129
+ }, {
130
+ name: 'modern-node-polyfills',
131
+ async resolveId(id, _, ctx) {
132
+ if (ctx.ssr || !builtinModules.includes(id)) {
133
+ return;
134
+ }
135
+ id = normalizeId(id);
136
+ return { id: await polyfillPath(id), moduleSideEffects: false };
137
+ },
138
+ }];
122
139
  }
@@ -1,5 +1,6 @@
1
1
  import type { Environment, FrameworkPreset } from '../types.js';
2
2
  export declare function getTemplate(options: WebdriverIO.BrowserRunnerOptions, env: Environment, spec: string): Promise<string>;
3
3
  export declare function userfriendlyImport(preset: FrameworkPreset, pkg?: string): Promise<any>;
4
+ export declare function normalizeId(id: string, base?: string): string;
4
5
  export declare function getErrorTemplate(filename: string, error: Error): string;
5
6
  //# 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,CAAE,OAAO,EAAE,WAAW,CAAC,oBAAoB,EAAE,GAAG,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,mBAoE3G;AAED,wBAAsB,kBAAkB,CAAE,MAAM,EAAE,eAAe,EAAE,GAAG,CAAC,EAAE,MAAM,gBAa9E;AAED,wBAAgB,gBAAgB,CAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,UAU/D"}
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,mBAyE1G;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,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,UAU9D"}
@@ -4,10 +4,10 @@ import path from 'node:path';
4
4
  import { resolve } from 'import-meta-resolve';
5
5
  export async function getTemplate(options, env, spec) {
6
6
  const root = options.rootDir || process.cwd();
7
+ const rootFileUrl = url.pathToFileURL(root).href;
7
8
  let vueDeps = '';
8
9
  if (options.preset === 'vue') {
9
10
  try {
10
- const rootFileUrl = url.pathToFileURL(root).href;
11
11
  const vueDir = path.dirname(url.fileURLToPath(await resolve('vue', `${rootFileUrl}/node_modules`)));
12
12
  const vueScript = (await fs.readFile(path.join(vueDir, 'dist', 'vue.global.prod.js'), 'utf-8')).toString();
13
13
  vueDeps += /*html*/ `
@@ -29,13 +29,14 @@ export async function getTemplate(options, env, spec) {
29
29
  `Error: ${err.stack}`);
30
30
  }
31
31
  }
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');
32
33
  return /* html */ `
33
34
  <!doctype html>
34
35
  <html>
35
36
  <head>
36
37
  <title>WebdriverIO Browser Test</title>
37
38
  <link rel="icon" type="image/x-icon" href="https://webdriver.io/img/favicon.png">
38
- <link rel="stylesheet" href="https://unpkg.com/mocha@10.0.0/mocha.css">
39
+ <link rel="stylesheet" href="${mochaCSSHref}">
39
40
  <script type="module">
40
41
  /**
41
42
  * Inject environment variables
@@ -79,6 +80,18 @@ export async function userfriendlyImport(preset, pkg) {
79
80
  `Please run:\n\n\tnpm install ${pkg}\n\tor\n\tyarn add --dev ${pkg}`);
80
81
  }
81
82
  }
83
+ export function normalizeId(id, base) {
84
+ if (base && id.startsWith(base)) {
85
+ id = `/${id.slice(base.length)}`;
86
+ }
87
+ return id
88
+ .replace(/^\/@id\/__x00__/, '\0') // virtual modules start with `\0`
89
+ .replace(/^\/@id\//, '')
90
+ .replace(/^__vite-browser-external:/, '')
91
+ .replace(/^node:/, '')
92
+ .replace(/[?&]v=\w+/, '?') // remove ?v= query
93
+ .replace(/\?$/, ''); // remove end query mark
94
+ }
82
95
  export function getErrorTemplate(filename, error) {
83
96
  return /*html*/ `
84
97
  <pre>${error.stack}</pre>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/browser-runner",
3
- "version": "8.3.4",
3
+ "version": "8.3.5",
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",
@@ -32,11 +32,11 @@
32
32
  "@types/istanbul-lib-source-maps": "^4.0.1",
33
33
  "@types/node": "^18.11.18",
34
34
  "@vitest/spy": "^0.28.4",
35
- "@wdio/globals": "8.3.3",
36
- "@wdio/local-runner": "8.3.3",
35
+ "@wdio/globals": "8.3.5",
36
+ "@wdio/local-runner": "8.3.5",
37
37
  "@wdio/logger": "8.1.0",
38
38
  "@wdio/mocha-framework": "8.3.0",
39
- "@wdio/protocols": "8.2.0",
39
+ "@wdio/protocols": "8.3.5",
40
40
  "@wdio/types": "8.3.0",
41
41
  "@wdio/utils": "8.3.0",
42
42
  "deepmerge-ts": "^4.2.2",
@@ -48,12 +48,13 @@
48
48
  "istanbul-lib-report": "^3.0.0",
49
49
  "istanbul-lib-source-maps": "^4.0.1",
50
50
  "istanbul-reports": "^3.1.5",
51
+ "modern-node-polyfills": "^0.0.9",
51
52
  "serialize-error": "^11.0.0",
52
53
  "vite": "^4.0.4",
53
54
  "vite-plugin-istanbul": "^4.0.0",
54
55
  "vite-plugin-top-level-await": "^1.2.2",
55
- "webdriver": "8.3.2",
56
- "webdriverio": "8.3.3",
56
+ "webdriver": "8.3.5",
57
+ "webdriverio": "8.3.5",
57
58
  "ws": "^8.12.0"
58
59
  },
59
60
  "scripts": {
@@ -64,7 +65,7 @@
64
65
  },
65
66
  "devDependencies": {
66
67
  "@types/ws": "^8.5.4",
67
- "@wdio/runner": "8.3.3"
68
+ "@wdio/runner": "8.3.5"
68
69
  },
69
- "gitHead": "efefec970ff7ec657e6284ef8f5402363579284b"
70
+ "gitHead": "cc6deb72e7c4f064074ca8a2e101da7c08db8b4b"
70
71
  }