@wdio/local-runner 9.32.0 → 10.0.0-alpha.150
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/AGENTS.md +31 -0
- package/build/index.d.ts +7 -7
- package/build/index.d.ts.map +1 -1
- package/build/index.js +157 -60
- package/build/worker.d.ts +9 -7
- package/build/worker.d.ts.map +1 -1
- package/package.json +12 -11
package/AGENTS.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# @wdio/local-runner
|
|
2
|
+
|
|
3
|
+
Forks one worker process per capability and owns its lifetime: ready/session
|
|
4
|
+
IPC, shutdown, the display daemon, and the in-worker REPL queue.
|
|
5
|
+
|
|
6
|
+
## Commands
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pnpm run dev @wdio/local-runner
|
|
10
|
+
pnpm run test:package wdio-local-runner
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Display-daemon changes also need `pnpm run test:e2e:display-server` on a Linux
|
|
14
|
+
host with no display. Elsewhere, leave that lane to CI.
|
|
15
|
+
|
|
16
|
+
## Test ownership
|
|
17
|
+
|
|
18
|
+
- `LocalRunner` fork, shutdown, watch-mode attach, and display lifetime:
|
|
19
|
+
`tests/localRunner.test.ts`. Force-kill after the real `SHUTDOWN_TIMEOUT`:
|
|
20
|
+
`tests/workerCleanupIssue.test.ts`.
|
|
21
|
+
- Worker IPC, exit codes, and `kill`: `tests/worker.test.ts`. Forked log-file
|
|
22
|
+
names: `tests/worker.env.test.ts`.
|
|
23
|
+
- Child-process entry (`src/run.ts`): `tests/run.test.ts`.
|
|
24
|
+
- REPL eval and result callbacks: `tests/repl.test.ts`. One-at-a-time debug
|
|
25
|
+
sessions: `tests/replQueue.test.ts` through `ReplQueue.next`.
|
|
26
|
+
- Log prefix and debugger-line filtering: `tests/transformStream.test.ts`.
|
|
27
|
+
Write the Node debugger prefixes in the test. Do not feed it
|
|
28
|
+
`DEBUGGER_MESSAGES`.
|
|
29
|
+
|
|
30
|
+
Do not add a second assertion of the same exit payload. Assert REPL errors
|
|
31
|
+
through `onResult`, not private helpers. A skipped queue test is not coverage.
|
package/build/index.d.ts
CHANGED
|
@@ -11,21 +11,16 @@ export default class LocalRunner {
|
|
|
11
11
|
private _options;
|
|
12
12
|
protected config: WebdriverIO.Config;
|
|
13
13
|
workerPool: Record<string, WorkerInstance>;
|
|
14
|
-
private
|
|
15
|
-
private xvfbManager;
|
|
14
|
+
private daemon;
|
|
16
15
|
stdout: WritableStreamBuffer;
|
|
17
16
|
stderr: WritableStreamBuffer;
|
|
18
17
|
constructor(_options: never, config: WebdriverIO.Config);
|
|
19
18
|
/**
|
|
20
|
-
*
|
|
19
|
+
* Runs before any service `onPrepare`, so drivers those services start inherit the display.
|
|
21
20
|
*/
|
|
22
21
|
initialize(): Promise<void>;
|
|
23
22
|
getWorkerCount(): number;
|
|
24
23
|
run({ command, args, ...workerOptions }: RunArgs): Promise<WorkerInstance>;
|
|
25
|
-
/**
|
|
26
|
-
* Initialize XVFB with capability-aware detection
|
|
27
|
-
*/
|
|
28
|
-
private initializeXvfb;
|
|
29
24
|
/**
|
|
30
25
|
* shutdown all worker processes
|
|
31
26
|
*
|
|
@@ -33,5 +28,10 @@ export default class LocalRunner {
|
|
|
33
28
|
* a timeout was reached
|
|
34
29
|
*/
|
|
35
30
|
shutdown(): Promise<boolean>;
|
|
31
|
+
/**
|
|
32
|
+
* Stop the display daemon. Runs after `onComplete`, so a driver or app a
|
|
33
|
+
* service started in `onPrepare` still has its display while it is torn down.
|
|
34
|
+
*/
|
|
35
|
+
dispose(): Promise<void>;
|
|
36
36
|
}
|
|
37
37
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,cAAc,MAAM,aAAa,CAAA;AAKxC,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,MAAM,WAAW,OAAQ,SAAQ,OAAO,CAAC,gBAAgB;IACrD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAA;IAC/B,GAAG,EAAE,MAAM,CAAA;CACd;AAED,MAAM,CAAC,OAAO,OAAO,WAAW;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAErD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAE1C,OAAO,cAAc,MAAM,aAAa,CAAA;AAKxC,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,MAAM,WAAW,OAAQ,SAAQ,OAAO,CAAC,gBAAgB;IACrD,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAA;IAC/B,GAAG,EAAE,MAAM,CAAA;CACd;AAED,MAAM,CAAC,OAAO,OAAO,WAAW;IAQxB,OAAO,CAAC,QAAQ;IAChB,SAAS,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM;IARxC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAK;IAC/C,OAAO,CAAC,MAAM,CAA6B;IAE3C,MAAM,uBAA2C;IACjD,MAAM,uBAA2C;gBAGrC,QAAQ,EAAE,KAAK,EACb,MAAM,EAAE,WAAW,CAAC,MAAM;IAGxC;;OAEG;IACG,UAAU;IAQhB,cAAc;IAIR,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,EAAE,OAAO;IAqBtD;;;;;OAKG;IACG,QAAQ;IAkFd;;;OAGG;IACG,OAAO;CAGhB"}
|
package/build/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import logger2 from "@wdio/logger";
|
|
3
3
|
import { WritableStreamBuffer } from "stream-buffers";
|
|
4
|
-
import {
|
|
4
|
+
import { startDisplayDaemonFromConfig } from "@wdio/display-server";
|
|
5
5
|
|
|
6
6
|
// src/worker.ts
|
|
7
7
|
import url from "node:url";
|
|
8
8
|
import path from "node:path";
|
|
9
|
+
import { fork } from "node:child_process";
|
|
9
10
|
import { constants } from "node:os";
|
|
10
11
|
import { EventEmitter } from "node:events";
|
|
11
|
-
import { ProcessFactory } from "@wdio/xvfb";
|
|
12
12
|
import logger from "@wdio/logger";
|
|
13
13
|
|
|
14
14
|
// src/transformStream.ts
|
|
@@ -194,6 +194,105 @@ function getExitCodeForSignal(signal) {
|
|
|
194
194
|
const signalNumber = signal ? constants.signals[signal] : void 0;
|
|
195
195
|
return signalNumber ? SIGNAL_EXIT_CODE_OFFSET + signalNumber : UNKNOWN_SIGNAL_EXIT_CODE;
|
|
196
196
|
}
|
|
197
|
+
var NODE_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set([
|
|
198
|
+
"-r",
|
|
199
|
+
"--require",
|
|
200
|
+
"--import",
|
|
201
|
+
"--experimental-loader",
|
|
202
|
+
"--loader",
|
|
203
|
+
"--conditions",
|
|
204
|
+
"-C",
|
|
205
|
+
"--max-old-space-size",
|
|
206
|
+
"--max-semi-space-size"
|
|
207
|
+
]);
|
|
208
|
+
var REPEATABLE_NODE_OPTIONS = /* @__PURE__ */ new Set([
|
|
209
|
+
"-r",
|
|
210
|
+
"--require",
|
|
211
|
+
"--import",
|
|
212
|
+
"--experimental-loader",
|
|
213
|
+
"--loader",
|
|
214
|
+
"--conditions",
|
|
215
|
+
"-C"
|
|
216
|
+
]);
|
|
217
|
+
function nodeOptionName(group) {
|
|
218
|
+
return group.split(" ")[0].split("=")[0];
|
|
219
|
+
}
|
|
220
|
+
function tokenizeNodeOptions(value) {
|
|
221
|
+
const tokens = [];
|
|
222
|
+
let current = "";
|
|
223
|
+
let quote;
|
|
224
|
+
const push = () => {
|
|
225
|
+
if (current) {
|
|
226
|
+
tokens.push(current);
|
|
227
|
+
current = "";
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
for (let i = 0; i < value.length; i++) {
|
|
231
|
+
const char = value[i];
|
|
232
|
+
if (quote) {
|
|
233
|
+
if (char === "\\" && i + 1 < value.length) {
|
|
234
|
+
current += char + value[i + 1];
|
|
235
|
+
i++;
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
current += char;
|
|
239
|
+
if (char === quote) {
|
|
240
|
+
quote = void 0;
|
|
241
|
+
}
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
if (char === '"' || char === "'") {
|
|
245
|
+
quote = char;
|
|
246
|
+
current += char;
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
if (/\s/.test(char)) {
|
|
250
|
+
push();
|
|
251
|
+
continue;
|
|
252
|
+
}
|
|
253
|
+
current += char;
|
|
254
|
+
}
|
|
255
|
+
push();
|
|
256
|
+
return tokens;
|
|
257
|
+
}
|
|
258
|
+
function parseNodeOptionGroups(value) {
|
|
259
|
+
const parts = tokenizeNodeOptions(value);
|
|
260
|
+
const groups = [];
|
|
261
|
+
for (let i = 0; i < parts.length; i++) {
|
|
262
|
+
const token = parts[i];
|
|
263
|
+
const name = token.split("=")[0];
|
|
264
|
+
const next = parts[i + 1];
|
|
265
|
+
if (!token.includes("=") && NODE_OPTIONS_WITH_VALUE.has(name) && next && !next.startsWith("-")) {
|
|
266
|
+
groups.push(`${token} ${next}`);
|
|
267
|
+
i++;
|
|
268
|
+
continue;
|
|
269
|
+
}
|
|
270
|
+
groups.push(token);
|
|
271
|
+
}
|
|
272
|
+
return groups;
|
|
273
|
+
}
|
|
274
|
+
function mergeWorkerNodeOptions(parent, runner) {
|
|
275
|
+
const merged = parseNodeOptionGroups(parent);
|
|
276
|
+
if (typeof runner !== "string") {
|
|
277
|
+
return merged.join(" ");
|
|
278
|
+
}
|
|
279
|
+
for (const group of parseNodeOptionGroups(runner)) {
|
|
280
|
+
const name = nodeOptionName(group);
|
|
281
|
+
if (REPEATABLE_NODE_OPTIONS.has(name)) {
|
|
282
|
+
if (!merged.includes(group)) {
|
|
283
|
+
merged.push(group);
|
|
284
|
+
}
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
const existing = merged.findIndex((item) => nodeOptionName(item) === name);
|
|
288
|
+
if (existing === -1) {
|
|
289
|
+
merged.push(group);
|
|
290
|
+
} else {
|
|
291
|
+
merged[existing] = group;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return merged.join(" ");
|
|
295
|
+
}
|
|
197
296
|
var WorkerInstance = class extends EventEmitter {
|
|
198
297
|
cid;
|
|
199
298
|
config;
|
|
@@ -211,9 +310,8 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
211
310
|
sessionId;
|
|
212
311
|
server;
|
|
213
312
|
logsAggregator = [];
|
|
214
|
-
#processFactory;
|
|
215
313
|
instances;
|
|
216
|
-
|
|
314
|
+
isMultiRemote;
|
|
217
315
|
isBusy = false;
|
|
218
316
|
isKilled = false;
|
|
219
317
|
isReady;
|
|
@@ -231,9 +329,8 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
231
329
|
* @param {string[]} specs list of paths to test files to run in this worker
|
|
232
330
|
* @param {number} retries number of retries remaining
|
|
233
331
|
* @param {object} execArgv execution arguments for the test run
|
|
234
|
-
* @param {XvfbManager} xvfbManager configured XvfbManager instance
|
|
235
332
|
*/
|
|
236
|
-
constructor(config, { cid, configFile, caps, specs, execArgv, retries }, stdout, stderr
|
|
333
|
+
constructor(config, { cid, configFile, caps, specs, execArgv, retries }, stdout, stderr) {
|
|
237
334
|
super();
|
|
238
335
|
this.cid = cid;
|
|
239
336
|
this.config = config;
|
|
@@ -245,7 +342,6 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
245
342
|
this.retries = retries;
|
|
246
343
|
this.stdout = stdout;
|
|
247
344
|
this.stderr = stderr;
|
|
248
|
-
this.#processFactory = new ProcessFactory(xvfbManager);
|
|
249
345
|
this.isReady = new Promise((resolve) => {
|
|
250
346
|
this.isReadyResolver = resolve;
|
|
251
347
|
});
|
|
@@ -259,9 +355,7 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
259
355
|
async startProcess() {
|
|
260
356
|
const { cid, execArgv } = this;
|
|
261
357
|
const argv = process.argv.slice(2);
|
|
262
|
-
const runnerEnv = Object.assign({
|
|
263
|
-
NODE_OPTIONS: "--enable-source-maps"
|
|
264
|
-
}, process.env, this.config.runnerEnv, {
|
|
358
|
+
const runnerEnv = Object.assign({}, process.env, this.config.runnerEnv, {
|
|
265
359
|
WDIO_WORKER_ID: cid,
|
|
266
360
|
NODE_ENV: process.env.NODE_ENV || "test"
|
|
267
361
|
});
|
|
@@ -273,9 +367,20 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
273
367
|
}
|
|
274
368
|
runnerEnv.WDIO_LOG_PATH = path.join(this.config.outputDir, logFileRunner);
|
|
275
369
|
}
|
|
276
|
-
|
|
370
|
+
const runnerOverride = this.config.runnerEnv?.NODE_OPTIONS;
|
|
371
|
+
const nodeOptions = mergeWorkerNodeOptions(
|
|
372
|
+
process.env.NODE_OPTIONS ?? "",
|
|
373
|
+
typeof runnerOverride === "string" ? runnerOverride : void 0
|
|
374
|
+
);
|
|
375
|
+
const hasSourceMaps = nodeOptions.split(" ").includes("--enable-source-maps");
|
|
376
|
+
const merged = this.shouldEnableSourceMaps() && !hasSourceMaps ? `${nodeOptions} --enable-source-maps`.trim() : nodeOptions;
|
|
377
|
+
if (merged) {
|
|
378
|
+
runnerEnv.NODE_OPTIONS = merged;
|
|
379
|
+
} else {
|
|
380
|
+
delete runnerEnv.NODE_OPTIONS;
|
|
381
|
+
}
|
|
277
382
|
log.info(`Start worker ${cid} with arg: ${argv.join(" ")}`);
|
|
278
|
-
const childProcess = this.childProcess =
|
|
383
|
+
const childProcess = this.childProcess = fork(
|
|
279
384
|
path.join(__dirname, "run.js"),
|
|
280
385
|
argv,
|
|
281
386
|
{
|
|
@@ -302,6 +407,17 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
302
407
|
}
|
|
303
408
|
return childProcess;
|
|
304
409
|
}
|
|
410
|
+
/**
|
|
411
|
+
* Source maps help debug stack traces but cost worker boot time.
|
|
412
|
+
* Enable for verbose log levels, or when WDIO_SOURCE_MAPS=1.
|
|
413
|
+
*/
|
|
414
|
+
shouldEnableSourceMaps() {
|
|
415
|
+
if (process.env.WDIO_SOURCE_MAPS === "1" || process.env.WDIO_SOURCE_MAPS === "true") {
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
const level = this.config.logLevel;
|
|
419
|
+
return level === "trace" || level === "debug";
|
|
420
|
+
}
|
|
305
421
|
_handleMessage(payload) {
|
|
306
422
|
const { cid, childProcess } = this;
|
|
307
423
|
if (payload.name === "finishedCommand") {
|
|
@@ -318,12 +434,13 @@ var WorkerInstance = class extends EventEmitter {
|
|
|
318
434
|
if (this.retries === -1 && payload.specFileRetries) {
|
|
319
435
|
this.retries = payload.specFileRetries - 1;
|
|
320
436
|
}
|
|
321
|
-
if (payload.content.
|
|
437
|
+
if (payload.content.isMultiRemote) {
|
|
322
438
|
Object.assign(this, payload.content);
|
|
323
439
|
} else {
|
|
440
|
+
const { capabilities, ...connection } = payload.content;
|
|
324
441
|
this.sessionId = payload.content.sessionId;
|
|
325
|
-
this.capabilities =
|
|
326
|
-
|
|
442
|
+
this.capabilities = capabilities;
|
|
443
|
+
this.config = { ...this.config, ...connection };
|
|
327
444
|
}
|
|
328
445
|
}
|
|
329
446
|
if (childProcess && payload.origin === "debugger" && payload.name === "start") {
|
|
@@ -424,35 +541,27 @@ var LocalRunner = class {
|
|
|
424
541
|
constructor(_options, config) {
|
|
425
542
|
this._options = _options;
|
|
426
543
|
this.config = config;
|
|
427
|
-
this.xvfbManager = new XvfbManager({
|
|
428
|
-
enabled: this.config.autoXvfb !== false,
|
|
429
|
-
autoInstall: this.config.xvfbAutoInstall,
|
|
430
|
-
autoInstallMode: this.config.xvfbAutoInstallMode,
|
|
431
|
-
autoInstallCommand: this.config.xvfbAutoInstallCommand,
|
|
432
|
-
xvfbMaxRetries: this.config.xvfbMaxRetries,
|
|
433
|
-
xvfbRetryDelay: this.config.xvfbRetryDelay
|
|
434
|
-
});
|
|
435
544
|
}
|
|
436
545
|
_options;
|
|
437
546
|
config;
|
|
438
547
|
workerPool = {};
|
|
439
|
-
|
|
440
|
-
xvfbManager;
|
|
548
|
+
daemon = null;
|
|
441
549
|
stdout = new WritableStreamBuffer(BUFFER_OPTIONS);
|
|
442
550
|
stderr = new WritableStreamBuffer(BUFFER_OPTIONS);
|
|
443
551
|
/**
|
|
444
|
-
*
|
|
552
|
+
* Runs before any service `onPrepare`, so drivers those services start inherit the display.
|
|
445
553
|
*/
|
|
446
554
|
async initialize() {
|
|
555
|
+
try {
|
|
556
|
+
this.daemon = await startDisplayDaemonFromConfig(this.config);
|
|
557
|
+
} catch (error) {
|
|
558
|
+
log2.warn("Failed to start a display server; continuing without a virtual display:", error);
|
|
559
|
+
}
|
|
447
560
|
}
|
|
448
561
|
getWorkerCount() {
|
|
449
562
|
return Object.keys(this.workerPool).length;
|
|
450
563
|
}
|
|
451
564
|
async run({ command, args, ...workerOptions }) {
|
|
452
|
-
if (!this.xvfbInitialized) {
|
|
453
|
-
await this.initializeXvfb(workerOptions);
|
|
454
|
-
this.xvfbInitialized = true;
|
|
455
|
-
}
|
|
456
565
|
const workerCnt = this.getWorkerCount();
|
|
457
566
|
if (workerCnt >= process.stdout.getMaxListeners() - 2) {
|
|
458
567
|
process.stdout.setMaxListeners(workerCnt + 2);
|
|
@@ -462,34 +571,12 @@ var LocalRunner = class {
|
|
|
462
571
|
this.config,
|
|
463
572
|
workerOptions,
|
|
464
573
|
this.stdout,
|
|
465
|
-
this.stderr
|
|
466
|
-
this.xvfbManager
|
|
574
|
+
this.stderr
|
|
467
575
|
);
|
|
468
576
|
this.workerPool[workerOptions.cid] = worker;
|
|
469
577
|
await worker.postMessage(command, args);
|
|
470
578
|
return worker;
|
|
471
579
|
}
|
|
472
|
-
/**
|
|
473
|
-
* Initialize XVFB with capability-aware detection
|
|
474
|
-
*/
|
|
475
|
-
async initializeXvfb(workerOptions) {
|
|
476
|
-
if (this.config.autoXvfb === false) {
|
|
477
|
-
log2.info("Skipping automatic Xvfb initialization (disabled by config)");
|
|
478
|
-
return;
|
|
479
|
-
}
|
|
480
|
-
try {
|
|
481
|
-
const capabilities = workerOptions.caps;
|
|
482
|
-
const xvfbInitialized = await this.xvfbManager.init(capabilities);
|
|
483
|
-
if (xvfbInitialized) {
|
|
484
|
-
log2.info("Xvfb is ready for use");
|
|
485
|
-
}
|
|
486
|
-
} catch (error) {
|
|
487
|
-
log2.warn(
|
|
488
|
-
"Failed to initialize Xvfb, continuing without virtual display:",
|
|
489
|
-
error
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
580
|
/**
|
|
494
581
|
* shutdown all worker processes
|
|
495
582
|
*
|
|
@@ -505,16 +592,22 @@ var LocalRunner = class {
|
|
|
505
592
|
server,
|
|
506
593
|
sessionId,
|
|
507
594
|
config,
|
|
508
|
-
|
|
595
|
+
isMultiRemote,
|
|
509
596
|
instances
|
|
510
597
|
} = worker;
|
|
511
598
|
let payload = {};
|
|
512
|
-
if (config && config.watch && (sessionId ||
|
|
599
|
+
if (config && config.watch && (sessionId || isMultiRemote)) {
|
|
513
600
|
payload = {
|
|
514
|
-
|
|
601
|
+
/**
|
|
602
|
+
* The worker's own session id wins over any id stored on
|
|
603
|
+
* config. Workers used to share one config object, so the
|
|
604
|
+
* last session started would otherwise be deleted twice
|
|
605
|
+
* and the others left open.
|
|
606
|
+
*/
|
|
607
|
+
config: { ...server, ...config, ...sessionId ? { sessionId } : {} },
|
|
515
608
|
capabilities,
|
|
516
609
|
watch: true,
|
|
517
|
-
|
|
610
|
+
isMultiRemote,
|
|
518
611
|
instances
|
|
519
612
|
};
|
|
520
613
|
} else if (!worker.isBusy) {
|
|
@@ -549,11 +642,15 @@ var LocalRunner = class {
|
|
|
549
642
|
}
|
|
550
643
|
}, 250);
|
|
551
644
|
});
|
|
552
|
-
if (this.xvfbManager.shouldRun()) {
|
|
553
|
-
log2.info("Xvfb cleanup handled automatically by xvfb-run");
|
|
554
|
-
}
|
|
555
645
|
return shutdownResult;
|
|
556
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Stop the display daemon. Runs after `onComplete`, so a driver or app a
|
|
649
|
+
* service started in `onPrepare` still has its display while it is torn down.
|
|
650
|
+
*/
|
|
651
|
+
async dispose() {
|
|
652
|
+
await this.daemon?.stop();
|
|
653
|
+
}
|
|
557
654
|
};
|
|
558
655
|
export {
|
|
559
656
|
LocalRunner as default
|
package/build/worker.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
+
import { type ChildProcess } from 'node:child_process';
|
|
1
2
|
import { EventEmitter } from 'node:events';
|
|
2
|
-
import type { ChildProcess } from 'node:child_process';
|
|
3
3
|
import type { WritableStreamBuffer } from 'stream-buffers';
|
|
4
|
-
import { type XvfbManager } from '@wdio/xvfb';
|
|
5
4
|
import type { Workers } from '@wdio/types';
|
|
6
5
|
/**
|
|
7
6
|
* WorkerInstance
|
|
@@ -9,7 +8,6 @@ import type { Workers } from '@wdio/types';
|
|
|
9
8
|
* session lifetime.
|
|
10
9
|
*/
|
|
11
10
|
export default class WorkerInstance extends EventEmitter implements Workers.Worker {
|
|
12
|
-
#private;
|
|
13
11
|
cid: string;
|
|
14
12
|
config: WebdriverIO.Config;
|
|
15
13
|
configFile: string;
|
|
@@ -27,7 +25,7 @@ export default class WorkerInstance extends EventEmitter implements Workers.Work
|
|
|
27
25
|
instances?: Record<string, {
|
|
28
26
|
sessionId: string;
|
|
29
27
|
}>;
|
|
30
|
-
|
|
28
|
+
isMultiRemote?: boolean;
|
|
31
29
|
isBusy: boolean;
|
|
32
30
|
isKilled: boolean;
|
|
33
31
|
isReady: Promise<boolean>;
|
|
@@ -43,13 +41,17 @@ export default class WorkerInstance extends EventEmitter implements Workers.Work
|
|
|
43
41
|
* @param {string[]} specs list of paths to test files to run in this worker
|
|
44
42
|
* @param {number} retries number of retries remaining
|
|
45
43
|
* @param {object} execArgv execution arguments for the test run
|
|
46
|
-
* @param {XvfbManager} xvfbManager configured XvfbManager instance
|
|
47
44
|
*/
|
|
48
|
-
constructor(config: WebdriverIO.Config, { cid, configFile, caps, specs, execArgv, retries }: Workers.WorkerRunPayload, stdout: WritableStreamBuffer, stderr: WritableStreamBuffer
|
|
45
|
+
constructor(config: WebdriverIO.Config, { cid, configFile, caps, specs, execArgv, retries }: Workers.WorkerRunPayload, stdout: WritableStreamBuffer, stderr: WritableStreamBuffer);
|
|
49
46
|
/**
|
|
50
47
|
* spawns process to kick of wdio-runner
|
|
51
48
|
*/
|
|
52
49
|
startProcess(): Promise<ChildProcess>;
|
|
50
|
+
/**
|
|
51
|
+
* Source maps help debug stack traces but cost worker boot time.
|
|
52
|
+
* Enable for verbose log levels, or when WDIO_SOURCE_MAPS=1.
|
|
53
|
+
*/
|
|
54
|
+
private shouldEnableSourceMaps;
|
|
53
55
|
private _handleMessage;
|
|
54
56
|
private _handleError;
|
|
55
57
|
/**
|
|
@@ -71,6 +73,6 @@ export default class WorkerInstance extends EventEmitter implements Workers.Work
|
|
|
71
73
|
* @param command method to run in wdio-runner
|
|
72
74
|
* @param args arguments for functions to call
|
|
73
75
|
*/
|
|
74
|
-
postMessage(command: string, args: Workers.WorkerMessageArgs, requiresSetup?: boolean): Promise<void>;
|
|
76
|
+
postMessage(command: string, args: Workers.WorkerMessageArgs | Workers.WorkerRequest['args'], requiresSetup?: boolean): Promise<void>;
|
|
75
77
|
}
|
|
76
78
|
//# sourceMappingURL=worker.d.ts.map
|
package/build/worker.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAwK1C;;;;GAIG;AACH,MAAM,CAAC,OAAO,OAAO,cAAe,SAAQ,YAAa,YAAW,OAAO,CAAC,MAAM;IAC9E,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,WAAW,CAAC,MAAM,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAElB,IAAI,EAAE,WAAW,CAAC,YAAY,CAAA;IAE9B,YAAY,EAAE,WAAW,CAAC,YAAY,CAAA;IACtC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,oBAAoB,CAAA;IAC5B,MAAM,EAAE,oBAAoB,CAAA;IAC5B,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,cAAc,EAAE,MAAM,EAAE,CAAK;IAE7B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACjD,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB,MAAM,UAAQ;IACd,QAAQ,UAAQ;IAChB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACzB,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;IACzB,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,CAAW;IAC3E,eAAe,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,IAAI,CAAW;IAE3E;;;;;;;;;OASG;gBAEC,MAAM,EAAE,WAAW,CAAC,MAAM,EAC1B,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,gBAAgB,EAC7E,MAAM,EAAE,oBAAoB,EAC5B,MAAM,EAAE,oBAAoB;IAkBhC;;OAEG;IACG,YAAY;IAgFlB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAQ9B,OAAO,CAAC,cAAc;IA+EtB,OAAO,CAAC,YAAY;IAKpB;;;;OAIG;IACH,OAAO,CAAC,WAAW;IAmCnB;;;;;;OAMG;IACH,IAAI,CAAC,MAAM,GAAE,MAAM,CAAC,OAAmB,GAAG,IAAI;IAiB9C;;;;OAIG;IACG,WAAW,CAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,aAAa,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CA4B7I"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wdio/local-runner",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "10.0.0-alpha.150+75574d3dd",
|
|
4
4
|
"description": "A WebdriverIO runner to run tests locally",
|
|
5
5
|
"author": "Christian Bromann <mail@bromann.dev>",
|
|
6
6
|
"homepage": "https://github.com/webdriverio/webdriverio/tree/main/packages/wdio-local-runner",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"engines": {
|
|
9
|
-
"node": ">=
|
|
9
|
+
"node": ">=22.19.0"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
|
@@ -34,16 +34,17 @@
|
|
|
34
34
|
"import": "./build/run.js"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
-
"typeScriptVersion": "
|
|
37
|
+
"typeScriptVersion": "6.0.3",
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@types/node": "^20.
|
|
40
|
-
"@
|
|
41
|
-
"@wdio/
|
|
42
|
-
"@wdio/
|
|
43
|
-
"@wdio/
|
|
44
|
-
"@wdio/
|
|
39
|
+
"@types/node": "^22.20.4",
|
|
40
|
+
"@types/split2": "^4.2.3",
|
|
41
|
+
"@wdio/display-server": "10.0.0-alpha.150+75574d3dd",
|
|
42
|
+
"@wdio/logger": "10.0.0-alpha.150+75574d3dd",
|
|
43
|
+
"@wdio/repl": "10.0.0-alpha.150+75574d3dd",
|
|
44
|
+
"@wdio/runner": "10.0.0-alpha.150+75574d3dd",
|
|
45
|
+
"@wdio/types": "10.0.0-alpha.150+75574d3dd",
|
|
45
46
|
"exit-hook": "^4.0.0",
|
|
46
|
-
"expect-webdriverio": "^
|
|
47
|
+
"expect-webdriverio": "^8.0.0-alpha.2",
|
|
47
48
|
"split2": "^4.1.0",
|
|
48
49
|
"stream-buffers": "^3.0.2"
|
|
49
50
|
},
|
|
@@ -53,5 +54,5 @@
|
|
|
53
54
|
"publishConfig": {
|
|
54
55
|
"access": "public"
|
|
55
56
|
},
|
|
56
|
-
"gitHead": "
|
|
57
|
+
"gitHead": "75574d3dd2cd697b0e552444a8a71c5ff38e69eb"
|
|
57
58
|
}
|