playwright 1.54.1 → 1.56.1

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.
Files changed (116) hide show
  1. package/README.md +3 -3
  2. package/ThirdPartyNotices.txt +2727 -434
  3. package/lib/agents/generateAgents.js +263 -0
  4. package/lib/agents/generator.md +102 -0
  5. package/lib/agents/healer.md +78 -0
  6. package/lib/agents/planner.md +135 -0
  7. package/lib/common/config.js +3 -1
  8. package/lib/common/configLoader.js +2 -1
  9. package/lib/common/expectBundle.js +3 -0
  10. package/lib/common/expectBundleImpl.js +51 -51
  11. package/lib/common/fixtures.js +1 -1
  12. package/lib/common/suiteUtils.js +0 -9
  13. package/lib/index.js +127 -115
  14. package/lib/isomorphic/testTree.js +35 -8
  15. package/lib/matchers/expect.js +6 -7
  16. package/lib/matchers/matcherHint.js +43 -15
  17. package/lib/matchers/matchers.js +10 -4
  18. package/lib/matchers/toBeTruthy.js +16 -14
  19. package/lib/matchers/toEqual.js +18 -13
  20. package/lib/matchers/toHaveURL.js +12 -27
  21. package/lib/matchers/toMatchAriaSnapshot.js +26 -31
  22. package/lib/matchers/toMatchSnapshot.js +15 -12
  23. package/lib/matchers/toMatchText.js +29 -35
  24. package/lib/mcp/browser/actions.d.js +16 -0
  25. package/lib/mcp/browser/browserContextFactory.js +296 -0
  26. package/lib/mcp/browser/browserServerBackend.js +76 -0
  27. package/lib/mcp/browser/codegen.js +66 -0
  28. package/lib/mcp/browser/config.js +383 -0
  29. package/lib/mcp/browser/context.js +284 -0
  30. package/lib/mcp/browser/response.js +228 -0
  31. package/lib/mcp/browser/sessionLog.js +160 -0
  32. package/lib/mcp/browser/tab.js +277 -0
  33. package/lib/mcp/browser/tools/common.js +63 -0
  34. package/lib/mcp/browser/tools/console.js +44 -0
  35. package/lib/mcp/browser/tools/dialogs.js +60 -0
  36. package/lib/mcp/browser/tools/evaluate.js +70 -0
  37. package/lib/mcp/browser/tools/files.js +58 -0
  38. package/lib/mcp/browser/tools/form.js +74 -0
  39. package/lib/mcp/browser/tools/install.js +69 -0
  40. package/lib/mcp/browser/tools/keyboard.js +85 -0
  41. package/lib/mcp/browser/tools/mouse.js +107 -0
  42. package/lib/mcp/browser/tools/navigate.js +62 -0
  43. package/lib/mcp/browser/tools/network.js +54 -0
  44. package/lib/mcp/browser/tools/pdf.js +59 -0
  45. package/lib/mcp/browser/tools/screenshot.js +88 -0
  46. package/lib/mcp/browser/tools/snapshot.js +182 -0
  47. package/lib/mcp/browser/tools/tabs.js +67 -0
  48. package/lib/mcp/browser/tools/tool.js +49 -0
  49. package/lib/mcp/browser/tools/tracing.js +74 -0
  50. package/lib/mcp/browser/tools/utils.js +100 -0
  51. package/lib/mcp/browser/tools/verify.js +154 -0
  52. package/lib/mcp/browser/tools/wait.js +63 -0
  53. package/lib/mcp/browser/tools.js +80 -0
  54. package/lib/mcp/browser/watchdog.js +44 -0
  55. package/lib/mcp/config.d.js +16 -0
  56. package/lib/mcp/extension/cdpRelay.js +351 -0
  57. package/lib/mcp/extension/extensionContextFactory.js +75 -0
  58. package/lib/mcp/extension/protocol.js +28 -0
  59. package/lib/mcp/index.js +61 -0
  60. package/lib/mcp/log.js +35 -0
  61. package/lib/mcp/program.js +96 -0
  62. package/lib/mcp/sdk/bundle.js +81 -0
  63. package/lib/mcp/sdk/exports.js +32 -0
  64. package/lib/mcp/sdk/http.js +180 -0
  65. package/lib/mcp/sdk/inProcessTransport.js +71 -0
  66. package/lib/mcp/sdk/mdb.js +208 -0
  67. package/lib/mcp/sdk/proxyBackend.js +128 -0
  68. package/lib/mcp/sdk/server.js +190 -0
  69. package/lib/mcp/sdk/tool.js +51 -0
  70. package/lib/mcp/test/browserBackend.js +98 -0
  71. package/lib/mcp/test/generatorTools.js +122 -0
  72. package/lib/mcp/test/plannerTools.js +46 -0
  73. package/lib/mcp/test/seed.js +72 -0
  74. package/lib/mcp/test/streams.js +39 -0
  75. package/lib/mcp/test/testBackend.js +97 -0
  76. package/lib/mcp/test/testContext.js +176 -0
  77. package/lib/mcp/test/testTool.js +30 -0
  78. package/lib/mcp/test/testTools.js +115 -0
  79. package/lib/mcpBundleImpl.js +41 -0
  80. package/lib/plugins/webServerPlugin.js +2 -0
  81. package/lib/program.js +77 -57
  82. package/lib/reporters/base.js +34 -29
  83. package/lib/reporters/dot.js +11 -11
  84. package/lib/reporters/github.js +2 -1
  85. package/lib/reporters/html.js +58 -41
  86. package/lib/reporters/internalReporter.js +2 -1
  87. package/lib/reporters/line.js +15 -15
  88. package/lib/reporters/list.js +24 -19
  89. package/lib/reporters/listModeReporter.js +69 -0
  90. package/lib/reporters/markdown.js +3 -3
  91. package/lib/reporters/merge.js +3 -1
  92. package/lib/reporters/teleEmitter.js +3 -1
  93. package/lib/runner/dispatcher.js +9 -2
  94. package/lib/runner/failureTracker.js +12 -2
  95. package/lib/runner/lastRun.js +7 -4
  96. package/lib/runner/loadUtils.js +46 -12
  97. package/lib/runner/projectUtils.js +8 -2
  98. package/lib/runner/reporters.js +7 -32
  99. package/lib/runner/tasks.js +20 -10
  100. package/lib/runner/testRunner.js +390 -0
  101. package/lib/runner/testServer.js +57 -276
  102. package/lib/runner/watchMode.js +5 -1
  103. package/lib/runner/workerHost.js +8 -6
  104. package/lib/transform/babelBundleImpl.js +179 -195
  105. package/lib/transform/compilationCache.js +22 -5
  106. package/lib/transform/transform.js +1 -1
  107. package/lib/util.js +12 -35
  108. package/lib/utilsBundleImpl.js +1 -1
  109. package/lib/worker/fixtureRunner.js +7 -2
  110. package/lib/worker/testInfo.js +76 -45
  111. package/lib/worker/testTracing.js +8 -7
  112. package/lib/worker/workerMain.js +12 -3
  113. package/package.json +10 -2
  114. package/types/test.d.ts +63 -44
  115. package/types/testReporter.d.ts +1 -1
  116. package/lib/runner/runner.js +0 -110
@@ -29,30 +29,19 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var testServer_exports = {};
30
30
  __export(testServer_exports, {
31
31
  TestServerDispatcher: () => TestServerDispatcher,
32
- resolveCtDirs: () => resolveCtDirs,
33
32
  runTestServer: () => runTestServer,
34
33
  runUIMode: () => runUIMode
35
34
  });
36
35
  module.exports = __toCommonJS(testServer_exports);
37
- var import_fs = __toESM(require("fs"));
38
- var import_path = __toESM(require("path"));
39
36
  var import_util = __toESM(require("util"));
40
37
  var import_server = require("playwright-core/lib/server");
41
38
  var import_utils = require("playwright-core/lib/utils");
42
39
  var import_utilsBundle = require("playwright-core/lib/utilsBundle");
43
- var import_reporters = require("./reporters");
44
- var import_sigIntWatcher = require("./sigIntWatcher");
45
- var import_tasks = require("./tasks");
46
40
  var import_configLoader = require("../common/configLoader");
47
- var import_fsWatcher = require("../fsWatcher");
48
- var import_teleReceiver = require("../isomorphic/teleReceiver");
49
- var import_gitCommitInfoPlugin = require("../plugins/gitCommitInfoPlugin");
50
- var import_webServerPlugin = require("../plugins/webServerPlugin");
51
- var import_base = require("../reporters/base");
52
- var import_internalReporter = require("../reporters/internalReporter");
53
41
  var import_list = __toESM(require("../reporters/list"));
54
- var import_compilationCache = require("../transform/compilationCache");
55
- var import_util2 = require("../util");
42
+ var import_reporters = require("./reporters");
43
+ var import_sigIntWatcher = require("./sigIntWatcher");
44
+ var import_testRunner = require("./testRunner");
56
45
  const originalDebugLog = import_utilsBundle.debug.log;
57
46
  const originalStdoutWrite = process.stdout.write;
58
47
  const originalStderrWrite = process.stderr.write;
@@ -66,22 +55,14 @@ class TestServer {
66
55
  return await (0, import_server.startTraceViewerServer)({ ...options, transport: this._dispatcher.transport });
67
56
  }
68
57
  async stop() {
69
- await this._dispatcher?._setInterceptStdio(false);
70
- await this._dispatcher?.runGlobalTeardown();
58
+ await this._dispatcher?.stop();
71
59
  }
72
60
  }
73
61
  class TestServerDispatcher {
74
62
  constructor(configLocation, configCLIOverrides) {
75
- this._watchedProjectDirs = /* @__PURE__ */ new Set();
76
- this._ignoredProjectOutputs = /* @__PURE__ */ new Set();
77
- this._watchedTestDependencies = /* @__PURE__ */ new Set();
78
- this._queue = Promise.resolve();
79
63
  this._serializer = require.resolve("./uiModeReporter");
80
- this._watchTestDirs = false;
81
64
  this._closeOnDisconnect = false;
82
- this._populateDependenciesOnList = false;
83
- this._configLocation = configLocation;
84
- this._configCLIOverrides = configCLIOverrides;
65
+ this._testRunner = new import_testRunner.TestRunner(configLocation, configCLIOverrides);
85
66
  this.transport = {
86
67
  onconnect: () => {
87
68
  },
@@ -91,27 +72,26 @@ class TestServerDispatcher {
91
72
  (0, import_utils.gracefullyProcessExitDoNotHang)(0);
92
73
  }
93
74
  };
94
- this._watcher = new import_fsWatcher.Watcher((events) => {
95
- const collector = /* @__PURE__ */ new Set();
96
- events.forEach((f) => (0, import_compilationCache.collectAffectedTestFiles)(f.file, collector));
97
- this._dispatchEvent("testFilesChanged", { testFiles: [...collector] });
98
- });
99
75
  this._dispatchEvent = (method, params) => this.transport.sendEvent?.(method, params);
76
+ this._testRunner.on(import_testRunner.TestRunnerEvent.TestFilesChanged, (testFiles) => this._dispatchEvent("testFilesChanged", { testFiles }));
100
77
  }
101
78
  async _wireReporter(messageSink) {
102
79
  return await (0, import_reporters.createReporterForTestServer)(this._serializer, messageSink);
103
80
  }
104
- async _collectingInternalReporter(...extraReporters) {
81
+ async _collectingReporter() {
105
82
  const report = [];
106
- const collectingReporter = await (0, import_reporters.createReporterForTestServer)(this._serializer, (e) => report.push(e));
107
- return { reporter: new import_internalReporter.InternalReporter([collectingReporter, ...extraReporters]), report };
83
+ return {
84
+ reporter: await (0, import_reporters.createReporterForTestServer)(this._serializer, (e) => report.push(e)),
85
+ report
86
+ };
108
87
  }
109
88
  async initialize(params) {
110
89
  this._serializer = params.serializer || require.resolve("./uiModeReporter");
111
90
  this._closeOnDisconnect = !!params.closeOnDisconnect;
112
- await this._setInterceptStdio(!!params.interceptStdio);
113
- this._watchTestDirs = !!params.watchTestDirs;
114
- this._populateDependenciesOnList = !!params.populateDependenciesOnList;
91
+ await this._testRunner.initialize({
92
+ ...params
93
+ });
94
+ this._setInterceptStdio(!!params.interceptStdio);
115
95
  }
116
96
  async ping() {
117
97
  }
@@ -121,271 +101,102 @@ class TestServerDispatcher {
121
101
  (0, import_utilsBundle.open)("vscode://file/" + params.location.file + ":" + params.location.line).catch((e) => console.error(e));
122
102
  }
123
103
  async resizeTerminal(params) {
124
- process.stdout.columns = params.cols;
125
- process.stdout.rows = params.rows;
126
- process.stderr.columns = params.cols;
127
- process.stderr.rows = params.rows;
104
+ this._testRunner.resizeTerminal(params);
128
105
  }
129
106
  async checkBrowsers() {
130
- return { hasBrowsers: hasSomeBrowsers() };
107
+ return { hasBrowsers: this._testRunner.hasSomeBrowsers() };
131
108
  }
132
109
  async installBrowsers() {
133
- await installBrowsers();
110
+ await this._testRunner.installBrowsers();
134
111
  }
135
112
  async runGlobalSetup(params) {
136
113
  await this.runGlobalTeardown();
137
- const { reporter, report } = await this._collectingInternalReporter(new import_list.default());
138
- const config = await this._loadConfigOrReportError(reporter, this._configCLIOverrides);
139
- if (!config)
140
- return { status: "failed", report };
141
- const { status, cleanup } = await (0, import_tasks.runTasksDeferCleanup)(new import_tasks.TestRun(config, reporter), [
142
- ...(0, import_tasks.createGlobalSetupTasks)(config)
143
- ]);
144
- if (status !== "passed")
145
- await cleanup();
146
- else
147
- this._globalSetup = { cleanup, report };
114
+ const { reporter, report } = await this._collectingReporter();
115
+ this._globalSetupReport = report;
116
+ const { status } = await this._testRunner.runGlobalSetup([reporter, new import_list.default()]);
148
117
  return { report, status };
149
118
  }
150
119
  async runGlobalTeardown() {
151
- const globalSetup = this._globalSetup;
152
- const status = await globalSetup?.cleanup();
153
- this._globalSetup = void 0;
154
- return { status, report: globalSetup?.report || [] };
120
+ const { status } = await this._testRunner.runGlobalTeardown();
121
+ const report = this._globalSetupReport || [];
122
+ this._globalSetupReport = void 0;
123
+ return { status, report };
155
124
  }
156
125
  async startDevServer(params) {
157
126
  await this.stopDevServer({});
158
- const { reporter, report } = await this._collectingInternalReporter();
159
- const config = await this._loadConfigOrReportError(reporter);
160
- if (!config)
161
- return { report, status: "failed" };
162
- const { status, cleanup } = await (0, import_tasks.runTasksDeferCleanup)(new import_tasks.TestRun(config, reporter), [
163
- (0, import_tasks.createLoadTask)("out-of-process", { failOnLoadErrors: true, filterOnly: false }),
164
- (0, import_tasks.createStartDevServerTask)()
165
- ]);
166
- if (status !== "passed")
167
- await cleanup();
168
- else
169
- this._devServer = { cleanup, report };
127
+ const { reporter, report } = await this._collectingReporter();
128
+ const { status } = await this._testRunner.startDevServer(reporter, "out-of-process");
170
129
  return { report, status };
171
130
  }
172
131
  async stopDevServer(params) {
173
- const devServer = this._devServer;
174
- const status = await devServer?.cleanup();
175
- this._devServer = void 0;
176
- return { status, report: devServer?.report || [] };
132
+ const { status } = await this._testRunner.stopDevServer();
133
+ const report = this._devServerReport || [];
134
+ this._devServerReport = void 0;
135
+ return { status, report };
177
136
  }
178
137
  async clearCache(params) {
179
- const reporter = new import_internalReporter.InternalReporter([]);
180
- const config = await this._loadConfigOrReportError(reporter);
181
- if (!config)
182
- return;
183
- await (0, import_tasks.runTasks)(new import_tasks.TestRun(config, reporter), [
184
- (0, import_tasks.createClearCacheTask)(config)
185
- ]);
138
+ await this._testRunner.clearCache();
186
139
  }
187
140
  async listFiles(params) {
188
- const { reporter, report } = await this._collectingInternalReporter();
189
- const config = await this._loadConfigOrReportError(reporter);
190
- if (!config)
191
- return { status: "failed", report };
192
- config.cliProjectFilter = params.projects?.length ? params.projects : void 0;
193
- const status = await (0, import_tasks.runTasks)(new import_tasks.TestRun(config, reporter), [
194
- (0, import_tasks.createListFilesTask)(),
195
- (0, import_tasks.createReportBeginTask)()
196
- ]);
141
+ const { reporter, report } = await this._collectingReporter();
142
+ const { status } = await this._testRunner.listFiles(reporter, params.projects);
197
143
  return { report, status };
198
144
  }
199
145
  async listTests(params) {
200
- let result;
201
- this._queue = this._queue.then(async () => {
202
- const { config, report, status } = await this._innerListTests(params);
203
- if (config)
204
- await this._updateWatchedDirs(config);
205
- result = { report, status };
206
- }).catch(printInternalError);
207
- await this._queue;
208
- return result;
209
- }
210
- async _innerListTests(params) {
211
- const overrides = {
212
- ...this._configCLIOverrides,
213
- repeatEach: 1,
214
- retries: 0
215
- };
216
- const { reporter, report } = await this._collectingInternalReporter();
217
- const config = await this._loadConfigOrReportError(reporter, overrides);
218
- if (!config)
219
- return { report, reporter, status: "failed" };
220
- config.cliArgs = params.locations || [];
221
- config.cliGrep = params.grep;
222
- config.cliGrepInvert = params.grepInvert;
223
- config.cliProjectFilter = params.projects?.length ? params.projects : void 0;
224
- config.cliListOnly = true;
225
- const status = await (0, import_tasks.runTasks)(new import_tasks.TestRun(config, reporter), [
226
- (0, import_tasks.createLoadTask)("out-of-process", { failOnLoadErrors: false, filterOnly: false, populateDependencies: this._populateDependenciesOnList }),
227
- (0, import_tasks.createReportBeginTask)()
228
- ]);
229
- return { config, report, reporter, status };
230
- }
231
- async _updateWatchedDirs(config) {
232
- this._watchedProjectDirs = /* @__PURE__ */ new Set();
233
- this._ignoredProjectOutputs = /* @__PURE__ */ new Set();
234
- for (const p of config.projects) {
235
- this._watchedProjectDirs.add(p.project.testDir);
236
- this._ignoredProjectOutputs.add(p.project.outputDir);
237
- }
238
- const result = await resolveCtDirs(config);
239
- if (result) {
240
- this._watchedProjectDirs.add(result.templateDir);
241
- this._ignoredProjectOutputs.add(result.outDir);
242
- }
243
- if (this._watchTestDirs)
244
- await this._updateWatcher(false);
245
- }
246
- async _updateWatcher(reportPending) {
247
- await this._watcher.update([...this._watchedProjectDirs, ...this._watchedTestDependencies], [...this._ignoredProjectOutputs], reportPending);
146
+ const { reporter, report } = await this._collectingReporter();
147
+ const { status } = await this._testRunner.listTests(reporter, params);
148
+ return { report, status };
248
149
  }
249
150
  async runTests(params) {
250
- let result = { status: "passed" };
251
- this._queue = this._queue.then(async () => {
252
- result = await this._innerRunTests(params).catch((e) => {
253
- printInternalError(e);
254
- return { status: "failed" };
255
- });
256
- });
257
- await this._queue;
258
- return result;
259
- }
260
- async _innerRunTests(params) {
261
- await this.stopTests();
262
- const overrides = {
263
- ...this._configCLIOverrides,
264
- repeatEach: 1,
265
- retries: 0,
266
- preserveOutputDir: true,
267
- reporter: params.reporters ? params.reporters.map((r) => [r]) : void 0,
268
- use: {
269
- ...this._configCLIOverrides.use,
270
- ...params.trace === "on" ? { trace: { mode: "on", sources: false, _live: true } } : {},
271
- ...params.trace === "off" ? { trace: "off" } : {},
272
- ...params.video === "on" || params.video === "off" ? { video: params.video } : {},
273
- ...params.headed !== void 0 ? { headless: !params.headed } : {},
274
- _optionContextReuseMode: params.reuseContext ? "when-possible" : void 0,
275
- _optionConnectOptions: params.connectWsEndpoint ? { wsEndpoint: params.connectWsEndpoint } : void 0
276
- },
277
- ...params.updateSnapshots ? { updateSnapshots: params.updateSnapshots } : {},
278
- ...params.updateSourceMethod ? { updateSourceMethod: params.updateSourceMethod } : {},
279
- ...params.workers ? { workers: params.workers } : {}
280
- };
281
- if (params.trace === "on")
282
- process.env.PW_LIVE_TRACE_STACKS = "1";
283
- else
284
- process.env.PW_LIVE_TRACE_STACKS = void 0;
285
151
  const wireReporter = await this._wireReporter((e) => this._dispatchEvent("report", e));
286
- const config = await this._loadConfigOrReportError(new import_internalReporter.InternalReporter([wireReporter]), overrides);
287
- if (!config)
288
- return { status: "failed" };
289
- const testIdSet = params.testIds ? new Set(params.testIds) : null;
290
- config.cliListOnly = false;
291
- config.cliPassWithNoTests = true;
292
- config.cliArgs = params.locations || [];
293
- config.cliGrep = params.grep;
294
- config.cliGrepInvert = params.grepInvert;
295
- config.cliProjectFilter = params.projects?.length ? params.projects : void 0;
296
- config.testIdMatcher = testIdSet ? (id) => testIdSet.has(id) : void 0;
297
- const configReporters = await (0, import_reporters.createReporters)(config, "test", true);
298
- const reporter = new import_internalReporter.InternalReporter([...configReporters, wireReporter]);
299
- const stop = new import_utils.ManualPromise();
300
- const tasks = [
301
- (0, import_tasks.createApplyRebaselinesTask)(),
302
- (0, import_tasks.createLoadTask)("out-of-process", { filterOnly: true, failOnLoadErrors: false, doNotRunDepsOutsideProjectFilter: true }),
303
- ...(0, import_tasks.createRunTestsTasks)(config)
304
- ];
305
- const run = (0, import_tasks.runTasks)(new import_tasks.TestRun(config, reporter), tasks, 0, stop).then(async (status) => {
306
- this._testRun = void 0;
307
- return status;
152
+ const { status } = await this._testRunner.runTests(wireReporter, {
153
+ ...params,
154
+ doNotRunDepsOutsideProjectFilter: true
308
155
  });
309
- this._testRun = { run, stop };
310
- return { status: await run };
156
+ return { status };
311
157
  }
312
158
  async watch(params) {
313
- this._watchedTestDependencies = /* @__PURE__ */ new Set();
314
- for (const fileName of params.fileNames) {
315
- this._watchedTestDependencies.add(fileName);
316
- (0, import_compilationCache.dependenciesForTestFile)(fileName).forEach((file) => this._watchedTestDependencies.add(file));
317
- }
318
- await this._updateWatcher(true);
159
+ await this._testRunner.watch(params.fileNames);
319
160
  }
320
161
  async findRelatedTestFiles(params) {
321
- const errorReporter = (0, import_reporters.createErrorCollectingReporter)(import_base.internalScreen);
322
- const reporter = new import_internalReporter.InternalReporter([errorReporter]);
323
- const config = await this._loadConfigOrReportError(reporter);
324
- if (!config)
325
- return { errors: errorReporter.errors(), testFiles: [] };
326
- const status = await (0, import_tasks.runTasks)(new import_tasks.TestRun(config, reporter), [
327
- (0, import_tasks.createLoadTask)("out-of-process", { failOnLoadErrors: true, filterOnly: false, populateDependencies: true })
328
- ]);
329
- if (status !== "passed")
330
- return { errors: errorReporter.errors(), testFiles: [] };
331
- return { testFiles: (0, import_compilationCache.affectedTestFiles)(params.files) };
162
+ return this._testRunner.findRelatedTestFiles(params.files);
332
163
  }
333
164
  async stopTests() {
334
- this._testRun?.stop?.resolve();
335
- await this._testRun?.run;
165
+ await this._testRunner.stopTests();
166
+ }
167
+ async stop() {
168
+ this._setInterceptStdio(false);
169
+ await this._testRunner.stop();
336
170
  }
337
- async _setInterceptStdio(intercept) {
171
+ async closeGracefully() {
172
+ await this._testRunner.closeGracefully();
173
+ }
174
+ _setInterceptStdio(interceptStdio) {
338
175
  if (process.env.PWTEST_DEBUG)
339
176
  return;
340
- if (intercept) {
177
+ if (interceptStdio) {
341
178
  if (import_utilsBundle.debug.log === originalDebugLog) {
342
179
  import_utilsBundle.debug.log = (...args) => {
343
180
  const string = import_util.default.format(...args) + "\n";
344
181
  return originalStderrWrite.apply(process.stderr, [string]);
345
182
  };
346
183
  }
347
- process.stdout.write = (chunk) => {
184
+ const stdoutWrite = (chunk) => {
348
185
  this._dispatchEvent("stdio", chunkToPayload("stdout", chunk));
349
186
  return true;
350
187
  };
351
- process.stderr.write = (chunk) => {
188
+ const stderrWrite = (chunk) => {
352
189
  this._dispatchEvent("stdio", chunkToPayload("stderr", chunk));
353
190
  return true;
354
191
  };
192
+ process.stdout.write = stdoutWrite;
193
+ process.stderr.write = stderrWrite;
355
194
  } else {
356
195
  import_utilsBundle.debug.log = originalDebugLog;
357
196
  process.stdout.write = originalStdoutWrite;
358
197
  process.stderr.write = originalStderrWrite;
359
198
  }
360
199
  }
361
- async closeGracefully() {
362
- (0, import_utils.gracefullyProcessExitDoNotHang)(0);
363
- }
364
- async _loadConfig(overrides) {
365
- try {
366
- const config = await (0, import_configLoader.loadConfig)(this._configLocation, overrides);
367
- if (!this._plugins) {
368
- (0, import_webServerPlugin.webServerPluginsForConfig)(config).forEach((p) => config.plugins.push({ factory: p }));
369
- (0, import_gitCommitInfoPlugin.addGitCommitInfoPlugin)(config);
370
- this._plugins = config.plugins || [];
371
- } else {
372
- config.plugins.splice(0, config.plugins.length, ...this._plugins);
373
- }
374
- return { config };
375
- } catch (e) {
376
- return { config: null, error: (0, import_util2.serializeError)(e) };
377
- }
378
- }
379
- async _loadConfigOrReportError(reporter, overrides) {
380
- const { config, error } = await this._loadConfig(overrides);
381
- if (config)
382
- return config;
383
- reporter.onConfigure(import_teleReceiver.baseFullConfig);
384
- reporter.onError(error);
385
- await reporter.onEnd({ status: "failed" });
386
- await reporter.onExit();
387
- return null;
388
- }
389
200
  }
390
201
  async function runUIMode(configFile, configCLIOverrides, options) {
391
202
  const configLocation = (0, import_configLoader.resolveConfigLocation)(configFile);
@@ -445,39 +256,9 @@ function chunkToPayload(type, chunk) {
445
256
  return { type, buffer: chunk.toString("base64") };
446
257
  return { type, text: chunk };
447
258
  }
448
- function hasSomeBrowsers() {
449
- for (const browserName of ["chromium", "webkit", "firefox"]) {
450
- try {
451
- import_server.registry.findExecutable(browserName).executablePathOrDie("javascript");
452
- return true;
453
- } catch {
454
- }
455
- }
456
- return false;
457
- }
458
- async function installBrowsers() {
459
- const executables = import_server.registry.defaultExecutables();
460
- await import_server.registry.install(executables, false);
461
- }
462
- function printInternalError(e) {
463
- console.error("Internal error:", e);
464
- }
465
- async function resolveCtDirs(config) {
466
- const use = config.config.projects[0].use;
467
- const relativeTemplateDir = use.ctTemplateDir || "playwright";
468
- const templateDir = await import_fs.default.promises.realpath(import_path.default.normalize(import_path.default.join(config.configDir, relativeTemplateDir))).catch(() => void 0);
469
- if (!templateDir)
470
- return null;
471
- const outDir = use.ctCacheDir ? import_path.default.resolve(config.configDir, use.ctCacheDir) : import_path.default.resolve(templateDir, ".cache");
472
- return {
473
- outDir,
474
- templateDir
475
- };
476
- }
477
259
  // Annotate the CommonJS export names for ESM import in node:
478
260
  0 && (module.exports = {
479
261
  TestServerDispatcher,
480
- resolveCtDirs,
481
262
  runTestServer,
482
263
  runUIMode
483
264
  });
@@ -113,7 +113,11 @@ async function runWatchModeLoop(configLocation, initialOptions) {
113
113
  });
114
114
  });
115
115
  testServerConnection.onReport((report2) => teleSuiteUpdater.processTestReportEvent(report2));
116
- await testServerConnection.initialize({ interceptStdio: false, watchTestDirs: true, populateDependenciesOnList: true });
116
+ await testServerConnection.initialize({
117
+ interceptStdio: false,
118
+ watchTestDirs: true,
119
+ populateDependenciesOnList: true
120
+ });
117
121
  await testServerConnection.runGlobalSetup({});
118
122
  const { report } = await testServerConnection.listTests({});
119
123
  teleSuiteUpdater.processListReport(report);
@@ -39,24 +39,26 @@ var import_ipc = require("../common/ipc");
39
39
  var import_folders = require("../isomorphic/folders");
40
40
  let lastWorkerIndex = 0;
41
41
  class WorkerHost extends import_processHost.ProcessHost {
42
- constructor(testGroup, parallelIndex, config, extraEnv, outputDir) {
42
+ constructor(testGroup, options) {
43
43
  const workerIndex = lastWorkerIndex++;
44
44
  super(require.resolve("../worker/workerMain.js"), `worker-${workerIndex}`, {
45
- ...extraEnv,
45
+ ...options.extraEnv,
46
46
  FORCE_COLOR: "1",
47
47
  DEBUG_COLORS: process.env.DEBUG_COLORS === void 0 ? "1" : process.env.DEBUG_COLORS
48
48
  });
49
49
  this._didFail = false;
50
50
  this.workerIndex = workerIndex;
51
- this.parallelIndex = parallelIndex;
51
+ this.parallelIndex = options.parallelIndex;
52
52
  this._hash = testGroup.workerHash;
53
53
  this._params = {
54
54
  workerIndex: this.workerIndex,
55
- parallelIndex,
55
+ parallelIndex: options.parallelIndex,
56
56
  repeatEachIndex: testGroup.repeatEachIndex,
57
57
  projectId: testGroup.projectId,
58
- config,
59
- artifactsDir: import_path.default.join(outputDir, (0, import_folders.artifactsFolderName)(workerIndex))
58
+ config: options.config,
59
+ artifactsDir: import_path.default.join(options.outputDir, (0, import_folders.artifactsFolderName)(workerIndex)),
60
+ pauseOnError: options.pauseOnError,
61
+ pauseAtEnd: options.pauseAtEnd
60
62
  };
61
63
  }
62
64
  async start() {