@wdio/browser-runner 8.0.4 → 8.0.6

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 +1 @@
1
- {"version":3,"file":"mocha.d.ts","sourceRoot":"","sources":["../../../src/browser/frameworks/mocha.ts"],"names":[],"mappings":"AAUA,qBAAa,cAAc;;gBAKV,MAAM,EAAE,SAAS;IAqB9B,GAAG;CA0EN"}
1
+ {"version":3,"file":"mocha.d.ts","sourceRoot":"","sources":["../../../src/browser/frameworks/mocha.ts"],"names":[],"mappings":"AAUA,qBAAa,cAAc;;gBAKV,MAAM,EAAE,SAAS;IA+B9B,GAAG;CA+DN"}
@@ -10,6 +10,15 @@ export class MochaFramework {
10
10
  constructor(socket) {
11
11
  this.#socket = socket;
12
12
  socket.addEventListener('message', this.#handleSocketMessage.bind(this));
13
+ const [cid] = window.location.pathname.slice(1).split('/');
14
+ if (!cid) {
15
+ throw new Error('"cid" query parameter is missing');
16
+ }
17
+ const beforeHook = this.#getHook('beforeHook');
18
+ const beforeTest = this.#getHook('beforeTest');
19
+ const afterHook = this.#getHook('afterHook');
20
+ const afterTest = this.#getHook('afterTest');
21
+ setupEnv(cid, window.__wdioEnv__.args, beforeTest, beforeHook, afterTest, afterHook);
13
22
  const self = this;
14
23
  before(function () {
15
24
  self.#getHook('beforeSuite')({
@@ -27,15 +36,6 @@ export class MochaFramework {
27
36
  }
28
37
  run() {
29
38
  const runner = mocha.run(this.#onFinish.bind(this));
30
- const [cid] = window.location.pathname.slice(1).split('/');
31
- if (!cid) {
32
- throw new Error('"cid" query parameter is missing');
33
- }
34
- const beforeHook = this.#getHook('beforeHook');
35
- const beforeTest = this.#getHook('beforeTest');
36
- const afterHook = this.#getHook('afterHook');
37
- const afterTest = this.#getHook('afterTest');
38
- setupEnv(cid, window.__wdioEnv__.args, beforeTest, beforeHook, afterTest, afterHook);
39
39
  Object.entries(EVENTS).map(([mochaEvent, wdioEvent]) => runner.on(mochaEvent, (payload) => {
40
40
  this.#runnerEvents.push(formatMessage({ type: wdioEvent, payload, err: payload.err }));
41
41
  }));
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAIzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAK1C,OAAO,KAAK,EAAE,oBAAoB,IAAI,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAIjF,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;;IAK9C,OAAO,CAAC,OAAO;IACf,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU;gBAD7B,OAAO,EAAE,0BAA0B,EACjC,OAAO,EAAE,OAAO,CAAC,UAAU;IAYzC;;OAEG;IACG,UAAU;IAYhB,GAAG,CAAE,OAAO,EAAE,OAAO;IAyCrB;;;;OAIG;IACG,QAAQ;CAIjB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,oBAAqB,SAAQ,0BAA0B;SAAG;KACvE;CACJ"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAIzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAM1C,OAAO,KAAK,EAAE,oBAAoB,IAAI,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAIjF,MAAM,CAAC,OAAO,OAAO,aAAc,SAAQ,WAAW;;IAK9C,OAAO,CAAC,OAAO;IACf,SAAS,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU;gBAD7B,OAAO,EAAE,0BAA0B,EACjC,OAAO,EAAE,OAAO,CAAC,UAAU;IAYzC;;OAEG;IACG,UAAU;IAYhB,GAAG,CAAE,OAAO,EAAE,OAAO;IAmDrB;;;;OAIG;IACG,QAAQ;CAIjB;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,oBAAqB,SAAQ,0BAA0B;SAAG;KACvE;CACJ"}
package/build/index.js CHANGED
@@ -40,6 +40,13 @@ export default class BrowserRunner extends LocalRunner {
40
40
  runArgs.args.baseUrl = this._config.baseUrl;
41
41
  }
42
42
  const worker = super.run(runArgs);
43
+ this.#server.on('debugState', (state) => worker.postMessage('switchDebugState', state));
44
+ this.#server.on('workerHookExecution', (payload) => {
45
+ if (worker.cid !== payload.cid) {
46
+ return;
47
+ }
48
+ return worker.postMessage('workerHookExecution', payload);
49
+ });
43
50
  worker.on('message', async (payload) => {
44
51
  if (payload.name === 'sessionStarted' && !SESSIONS.has(payload.cid)) {
45
52
  SESSIONS.set(payload.cid, {
@@ -60,13 +67,15 @@ export default class BrowserRunner extends LocalRunner {
60
67
  /**
61
68
  * propagate debug state to the worker
62
69
  */
63
- browser.on('debugState', (state) => worker.postMessage('switchDebugState', state));
64
70
  BROWSER_POOL.set(payload.cid, browser);
65
71
  }
66
72
  if (payload.name === 'sessionEnded') {
67
73
  SESSIONS.delete(payload.cid);
68
74
  BROWSER_POOL.delete(payload.cid);
69
75
  }
76
+ if (payload.name === 'workerHookResult') {
77
+ this.#server.resolveHook(payload.args);
78
+ }
70
79
  });
71
80
  return worker;
72
81
  }
@@ -1,11 +1,16 @@
1
+ /// <reference types="node" />
2
+ import { EventEmitter } from 'node:events';
1
3
  import { WebSocketServer } from 'ws';
2
4
  import { InlineConfig } from 'vite';
3
- export declare class ViteServer {
5
+ import type { HookTriggerEvent } from './types';
6
+ export declare class ViteServer extends EventEmitter {
4
7
  #private;
5
8
  get socketServer(): WebSocketServer | undefined;
6
9
  get config(): Partial<InlineConfig>;
7
10
  constructor(options: WebdriverIO.BrowserRunnerOptions);
8
11
  start(): Promise<void>;
9
12
  close(): Promise<void>;
13
+ private runWorkerHooks;
14
+ resolveHook(result: HookTriggerEvent): void;
10
15
  }
11
16
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/vite/server.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAA;AAG/C,OAAO,EAA+B,YAAY,EAAE,MAAM,MAAM,CAAA;AAchE,qBAAa,UAAU;;IAOnB,IAAI,YAAY,gCAEf;IAED,IAAI,MAAM,0BAET;gBAEY,OAAO,EAAE,WAAW,CAAC,oBAAoB;IAiBhD,KAAK;IAuCL,KAAK;CA8Gd"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/vite/server.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1C,OAAO,EAAE,eAAe,EAAa,MAAM,IAAI,CAAA;AAG/C,OAAO,EAA+B,YAAY,EAAE,MAAM,MAAM,CAAA;AAQhE,OAAO,KAAK,EAAgB,gBAAgB,EAA6E,MAAM,SAAS,CAAA;AAYxI,qBAAa,UAAW,SAAQ,YAAY;;IAQxC,IAAI,YAAY,gCAEf;IAED,IAAI,MAAM,0BAET;gBAEY,OAAO,EAAE,WAAW,CAAC,oBAAoB;IAkBhD,KAAK;IAwCL,KAAK;IAmIX,OAAO,CAAC,cAAc;IAetB,WAAW,CAAE,MAAM,EAAE,gBAAgB;CAUxC"}
@@ -1,3 +1,4 @@
1
+ import { EventEmitter } from 'node:events';
1
2
  import getPort from 'get-port';
2
3
  import logger from '@wdio/logger';
3
4
  import { deepmerge } from 'deepmerge-ts';
@@ -11,7 +12,9 @@ import { PRESET_DEPENDENCIES, DEFAULT_VITE_CONFIG } from './constants.js';
11
12
  import { MESSAGE_TYPES } from '../constants.js';
12
13
  import { BROWSER_POOL, SESSIONS } from '../constants.js';
13
14
  const log = logger('@wdio/browser-runner:ViteServer');
14
- export class ViteServer {
15
+ const HOOK_TIMEOUT = 15 * 1000;
16
+ export class ViteServer extends EventEmitter {
17
+ #pendingHooks = new Map();
15
18
  #connections = new Set();
16
19
  #options;
17
20
  #viteConfig;
@@ -24,6 +27,7 @@ export class ViteServer {
24
27
  return this.#viteConfig;
25
28
  }
26
29
  constructor(options) {
30
+ super();
27
31
  this.#options = options;
28
32
  if (options.preset && options.viteConfig) {
29
33
  throw new Error('Invalid runner configuration: "preset" and "viteConfig" options are defined but only one of each can be used at the same time');
@@ -55,6 +59,7 @@ export class ViteServer {
55
59
  this.#wss.on('connection', this.#onConnect.bind(this));
56
60
  this.#viteConfig = deepmerge(this.#viteConfig, {
57
61
  server: {
62
+ host: '0.0.0.0',
58
63
  port: vitePort,
59
64
  proxy: {
60
65
  '/ws': {
@@ -116,7 +121,21 @@ export class ViteServer {
116
121
  const error = serializeError(new Error(`No session for cid ${payload.cid} found!`));
117
122
  return ws.send(JSON.stringify(this.#hookResponse({ ...payload, error })));
118
123
  }
119
- const result = await executeHooksWithArgs(payload.name, session.config[payload.name], payload.args).then(() => payload, (error) => ({ ...payload, error: serializeError(error) }));
124
+ const result = await Promise.all([
125
+ /**
126
+ * run config file hooks
127
+ */
128
+ executeHooksWithArgs(payload.name, session.config[payload.name], payload.args).then(() => payload, (error) => ({ ...payload, error: serializeError(error) })),
129
+ /**
130
+ * run service hooks in worker process
131
+ */
132
+ this.runWorkerHooks(payload).catch((error) => ({ ...payload, error: serializeError(error) }))
133
+ ]).then(
134
+ /**
135
+ * we don't propagate hook results from worker executions back
136
+ * as it doesn't seem to be necessary or relevant
137
+ */
138
+ ([result]) => result);
120
139
  return ws.send(JSON.stringify(this.#hookResponse(result)));
121
140
  }
122
141
  async #handleCommand(ws, payload) {
@@ -136,7 +155,7 @@ export class ViteServer {
136
155
  * emit debug state to be enabled to runner so it can be propagated to the worker
137
156
  */
138
157
  if (payload.commandName === 'debug') {
139
- browser.emit('debugState', true);
158
+ this.emit('debugState', true);
140
159
  }
141
160
  const result = await browser[payload.commandName](...payload.args);
142
161
  const resultMsg = JSON.stringify(this.#commandResponse({ id: payload.id, result }));
@@ -144,7 +163,7 @@ export class ViteServer {
144
163
  * emit debug state to be disabled to runner so it can be propagated to the worker
145
164
  */
146
165
  if (payload.commandName === 'debug') {
147
- browser.emit('debugState', false);
166
+ this.emit('debugState', false);
148
167
  }
149
168
  log.info(`Return command result: ${resultMsg}`);
150
169
  return ws.send(resultMsg);
@@ -168,4 +187,27 @@ export class ViteServer {
168
187
  value
169
188
  };
170
189
  }
190
+ #getPendingHookId(payload) {
191
+ return `${payload.cid}-${payload.id}`;
192
+ }
193
+ runWorkerHooks(payload) {
194
+ const hookId = this.#getPendingHookId(payload);
195
+ if (this.#pendingHooks.has(hookId)) {
196
+ throw new Error(`There is still a hook running for runner with id ${hookId}`);
197
+ }
198
+ this.emit('workerHookExecution', payload);
199
+ return new Promise((resolve, reject) => {
200
+ const hookExecutionTimeout = setTimeout(() => reject(new Error(`hook execution for runner with id ${hookId} timed out`)), HOOK_TIMEOUT);
201
+ this.#pendingHooks.set(hookId, { hookExecutionTimeout, resolveFn: resolve });
202
+ });
203
+ }
204
+ resolveHook(result) {
205
+ const hookId = this.#getPendingHookId(result);
206
+ const pendingHook = this.#pendingHooks.get(hookId);
207
+ if (!pendingHook) {
208
+ return log.warn(`Tried to resolve hook for cid ${result.cid} with id ${result.id} that didn't exist`);
209
+ }
210
+ pendingHook.resolveFn();
211
+ this.#pendingHooks.delete(hookId);
212
+ }
171
213
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wdio/browser-runner",
3
- "version": "8.0.4",
3
+ "version": "8.0.6",
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,14 @@
31
31
  "@esbuild-plugins/node-globals-polyfill": "^0.1.1",
32
32
  "@originjs/vite-plugin-commonjs": "^1.0.3",
33
33
  "@types/mocha": "^10.0.0",
34
- "@wdio/globals": "8.0.4",
35
- "@wdio/local-runner": "8.0.4",
34
+ "@wdio/globals": "8.0.6",
35
+ "@wdio/local-runner": "8.0.6",
36
36
  "@wdio/logger": "8.0.0",
37
- "@wdio/mocha-framework": "8.0.2",
37
+ "@wdio/mocha-framework": "8.0.6",
38
38
  "@wdio/protocols": "8.0.0",
39
- "@wdio/runner": "8.0.4",
40
- "@wdio/types": "8.0.0",
41
- "@wdio/utils": "8.0.2",
39
+ "@wdio/runner": "8.0.6",
40
+ "@wdio/types": "8.0.6",
41
+ "@wdio/utils": "8.0.6",
42
42
  "deepmerge-ts": "^4.2.2",
43
43
  "expect-webdriverio": "^4.0.1",
44
44
  "fast-safe-stringify": "^2.1.1",
@@ -47,8 +47,8 @@
47
47
  "serialize-error": "^11.0.0",
48
48
  "vite": "^3.1.7",
49
49
  "vite-plugin-top-level-await": "^1.2.1",
50
- "webdriver": "8.0.2",
51
- "webdriverio": "8.0.4",
50
+ "webdriver": "8.0.6",
51
+ "webdriverio": "8.0.6",
52
52
  "ws": "^8.10.0"
53
53
  },
54
54
  "scripts": {
@@ -60,5 +60,5 @@
60
60
  "devDependencies": {
61
61
  "@types/ws": "^8.5.3"
62
62
  },
63
- "gitHead": "3e59b46e07fe878dd9ff57d746f698edcb13d94f"
63
+ "gitHead": "4f63a94a3af029401d652ff1d0fa36e9057f553c"
64
64
  }