playwright 1.57.0-alpha-2025-11-13 → 1.57.0-alpha-2025-11-15

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.
@@ -23,16 +23,12 @@ __export(tool_exports, {
23
23
  });
24
24
  module.exports = __toCommonJS(tool_exports);
25
25
  var import_bundle = require("../sdk/bundle");
26
- const typesWithIntent = ["action", "assertion", "input"];
27
- function toMcpTool(tool, options) {
28
- const inputSchema = options?.addIntent && typesWithIntent.includes(tool.type) ? tool.inputSchema.extend({
29
- intent: import_bundle.z.string().describe("The intent of the call, for example the test step description plan idea")
30
- }) : tool.inputSchema;
26
+ function toMcpTool(tool) {
31
27
  const readOnly = tool.type === "readOnly" || tool.type === "assertion";
32
28
  return {
33
29
  name: tool.name,
34
30
  description: tool.description,
35
- inputSchema: (0, import_bundle.zodToJsonSchema)(inputSchema, { strictUnions: true }),
31
+ inputSchema: (0, import_bundle.zodToJsonSchema)(tool.inputSchema, { strictUnions: true }),
36
32
  annotations: {
37
33
  title: tool.title,
38
34
  readOnlyHint: readOnly,
@@ -50,11 +50,11 @@ const setupPage = (0, import_testTool.defineTestTool)({
50
50
  }),
51
51
  type: "readOnly"
52
52
  },
53
- handle: async (context, params, progress) => {
53
+ handle: async (context, params) => {
54
54
  const seed = await context.getOrCreateSeedFile(params.seedFile, params.project);
55
55
  context.generatorJournal = new import_testContext.GeneratorJournal(context.rootPath, params.plan, seed);
56
- await context.runSeedTest(seed.file, seed.projectName, progress);
57
- return { content: [] };
56
+ const { output, status } = await context.runSeedTest(seed.file, seed.projectName);
57
+ return { content: [{ type: "text", text: output }], isError: status !== "paused" };
58
58
  }
59
59
  });
60
60
  const generatorReadLog = (0, import_testTool.defineTestTool)({
@@ -48,10 +48,10 @@ const setupPage = (0, import_testTool.defineTestTool)({
48
48
  }),
49
49
  type: "readOnly"
50
50
  },
51
- handle: async (context, params, progress) => {
51
+ handle: async (context, params) => {
52
52
  const seed = await context.getOrCreateSeedFile(params.seedFile, params.project);
53
- await context.runSeedTest(seed.file, seed.projectName, progress);
54
- return { content: [] };
53
+ const { output, status } = await context.runSeedTest(seed.file, seed.projectName);
54
+ return { content: [{ type: "text", text: output }], isError: status !== "paused" };
55
55
  }
56
56
  });
57
57
  const planSchema = import_bundle.z.object({
@@ -24,14 +24,17 @@ module.exports = __toCommonJS(streams_exports);
24
24
  var import_stream = require("stream");
25
25
  var import_util = require("../../util");
26
26
  class StringWriteStream extends import_stream.Writable {
27
- constructor(progress, stdio) {
27
+ constructor(output, stdio) {
28
28
  super();
29
- this._progress = progress;
29
+ this._output = output;
30
30
  this._prefix = stdio === "stdout" ? "" : "[err] ";
31
31
  }
32
32
  _write(chunk, encoding, callback) {
33
- const text = (0, import_util.stripAnsiEscapes)(chunk.toString());
34
- this._progress({ message: `${this._prefix}${text.endsWith("\n") ? text.slice(0, -1) : text}` });
33
+ let text = (0, import_util.stripAnsiEscapes)(chunk.toString());
34
+ if (text.endsWith("\n"))
35
+ text = text.slice(0, -1);
36
+ if (text)
37
+ this._output.push(this._prefix + text);
35
38
  callback();
36
39
  }
37
40
  }
@@ -31,17 +31,13 @@ __export(testBackend_exports, {
31
31
  TestServerBackend: () => TestServerBackend
32
32
  });
33
33
  module.exports = __toCommonJS(testBackend_exports);
34
- var import_utilsBundle = require("playwright-core/lib/utilsBundle");
35
- var import_utils = require("playwright-core/lib/utils");
36
34
  var mcp = __toESM(require("../sdk/exports"));
37
35
  var import_testContext = require("./testContext");
38
36
  var testTools = __toESM(require("./testTools.js"));
39
37
  var generatorTools = __toESM(require("./generatorTools.js"));
40
38
  var plannerTools = __toESM(require("./plannerTools.js"));
41
39
  var import_tools = require("../browser/tools");
42
- var import_configLoader = require("../../common/configLoader");
43
- var import_response = require("../browser/response");
44
- const errorsDebug = (0, import_utilsBundle.debug)("pw:mcp:errors");
40
+ var import_bundle = require("../sdk/bundle");
45
41
  class TestServerBackend {
46
42
  constructor(configOption, options) {
47
43
  this.name = "Playwright";
@@ -55,86 +51,48 @@ class TestServerBackend {
55
51
  generatorTools.generatorWriteTest,
56
52
  testTools.listTests,
57
53
  testTools.runTests,
58
- testTools.debugTest
54
+ testTools.debugTest,
55
+ ...import_tools.browserTools.map((tool) => wrapBrowserTool(tool))
59
56
  ];
60
- this._progress = [];
61
- this._context = new import_testContext.TestContext(this._pushClient.bind(this), options);
57
+ this._options = options || {};
62
58
  this._configOption = configOption;
63
- this._progressCallback = (params) => {
64
- if (params.message)
65
- this._progress.push({ type: "text", text: params.message });
66
- };
67
- }
68
- async _pushClient(sendMessage) {
69
- try {
70
- const initializeResponse = await sendMessage({ initialize: { clientInfo: this._clientInfo } });
71
- const listToolsResponse = await sendMessage({ listTools: {} });
72
- const tools = listToolsResponse.listTools;
73
- this._onPauseClient = { sendMessage, tools };
74
- this._interruptPromise?.resolve({
75
- content: [{
76
- type: "text",
77
- text: initializeResponse.initialize.pausedMessage
78
- }]
79
- });
80
- this._interruptPromise = void 0;
81
- } catch {
82
- }
83
59
  }
84
60
  async initialize(clientInfo) {
85
- this._clientInfo = clientInfo;
86
- const rootPath = mcp.firstRootPath(clientInfo);
87
- if (this._configOption) {
88
- this._context.initialize(rootPath, (0, import_configLoader.resolveConfigLocation)(this._configOption));
89
- return;
90
- }
91
- if (rootPath) {
92
- this._context.initialize(rootPath, (0, import_configLoader.resolveConfigLocation)(rootPath));
93
- return;
94
- }
95
- this._context.initialize(rootPath, (0, import_configLoader.resolveConfigLocation)(void 0));
61
+ this._context = new import_testContext.TestContext(clientInfo, this._configOption, this._options);
96
62
  }
97
63
  async listTools() {
98
- return [
99
- ...this._tools.map((tool) => mcp.toMcpTool(tool.schema)),
100
- ...import_tools.browserTools.map((tool) => mcp.toMcpTool(tool.schema, { addIntent: true }))
101
- ];
64
+ return this._tools.map((tool) => mcp.toMcpTool(tool.schema));
102
65
  }
103
66
  async callTool(name, args) {
104
- if (this._onPauseClient?.tools.find((tool) => tool.name === name)) {
105
- const callToolRespone = await this._onPauseClient.sendMessage({ callTool: { name, arguments: args } });
106
- const result2 = callToolRespone.callTool;
107
- const response = (0, import_response.parseResponse)(result2);
108
- if (response && !response.isError && response.code && typeof args?.["intent"] === "string")
109
- this._context.generatorJournal?.logStep(args["intent"], response.code);
110
- return result2;
111
- }
112
- await this._onPauseClient?.sendMessage({ close: {} }).catch(errorsDebug);
113
- this._onPauseClient = void 0;
114
- const resultPromise = new import_utils.ManualPromise();
115
- const interruptPromise = new import_utils.ManualPromise();
116
- this._interruptPromise = interruptPromise;
117
- this._callTestTool(name, args).then((result2) => {
118
- resultPromise.resolve(result2);
119
- }).catch((e) => {
120
- resultPromise.resolve({ content: [{ type: "text", text: String(e) }], isError: true });
121
- });
122
- const result = await Promise.race([interruptPromise, resultPromise]);
123
- result.content.unshift(...this._progress);
124
- this._progress.length = 0;
125
- return result;
126
- }
127
- async _callTestTool(name, args) {
128
67
  const tool = this._tools.find((tool2) => tool2.schema.name === name);
129
68
  if (!tool)
130
69
  throw new Error(`Tool not found: ${name}. Available tools: ${this._tools.map((tool2) => tool2.schema.name).join(", ")}`);
131
- const parsedArguments = tool.schema.inputSchema.parse(args || {});
132
- return await tool.handle(this._context, parsedArguments, this._progressCallback);
70
+ try {
71
+ return await tool.handle(this._context, tool.schema.inputSchema.parse(args || {}));
72
+ } catch (e) {
73
+ return { content: [{ type: "text", text: String(e) }], isError: true };
74
+ }
133
75
  }
134
76
  serverClosed() {
135
77
  void this._context.close();
136
78
  }
137
79
  }
80
+ const typesWithIntent = ["action", "assertion", "input"];
81
+ function wrapBrowserTool(tool) {
82
+ const inputSchema = typesWithIntent.includes(tool.schema.type) ? tool.schema.inputSchema.extend({
83
+ intent: import_bundle.z.string().describe("The intent of the call, for example the test step description plan idea")
84
+ }) : tool.schema.inputSchema;
85
+ return {
86
+ schema: {
87
+ ...tool.schema,
88
+ inputSchema
89
+ },
90
+ handle: async (context, params) => {
91
+ const response = await context.sendMessageToPausedTest({ callTool: { name: tool.schema.name, arguments: params } });
92
+ return response.callTool;
93
+ }
94
+ };
95
+ }
138
96
  // Annotate the CommonJS export names for ESM import in node:
139
97
  0 && (module.exports = {
140
98
  TestServerBackend
@@ -43,6 +43,10 @@ var import_streams = require("./streams");
43
43
  var import_util = require("../../util");
44
44
  var import_testRunner = require("../../runner/testRunner");
45
45
  var import_seed = require("./seed");
46
+ var import_exports = require("../sdk/exports");
47
+ var import_configLoader = require("../../common/configLoader");
48
+ var import_response = require("../browser/response");
49
+ var import_log = require("../log");
46
50
  class GeneratorJournal {
47
51
  constructor(rootPath, plan, seed) {
48
52
  this._rootPath = rootPath;
@@ -72,40 +76,51 @@ ${step.code}
72
76
  }
73
77
  }
74
78
  class TestContext {
75
- constructor(pushClient, options) {
76
- this._pushClient = pushClient;
77
- this.options = options;
79
+ constructor(clientInfo, configPath, options) {
80
+ this._clientInfo = clientInfo;
81
+ const rootPath = (0, import_exports.firstRootPath)(clientInfo);
82
+ this._configLocation = (0, import_configLoader.resolveConfigLocation)(configPath || rootPath);
83
+ this.rootPath = rootPath || this._configLocation.configDir;
78
84
  if (options?.headless !== void 0)
79
85
  this.computedHeaded = !options.headless;
80
86
  else
81
87
  this.computedHeaded = !process.env.CI && !(import_os.default.platform() === "linux" && !process.env.DISPLAY);
82
88
  }
83
- initialize(rootPath, configLocation) {
84
- this.configLocation = configLocation;
85
- this.rootPath = rootPath || configLocation.configDir;
86
- }
87
89
  existingTestRunner() {
88
- return this._testRunner;
90
+ return this._testRunnerAndScreen?.testRunner;
91
+ }
92
+ async _cleanupTestRunner() {
93
+ if (!this._testRunnerAndScreen)
94
+ return;
95
+ await this._testRunnerAndScreen.testRunner.stopTests();
96
+ this._testRunnerAndScreen.claimStdio();
97
+ try {
98
+ await this._testRunnerAndScreen.testRunner.runGlobalTeardown();
99
+ } finally {
100
+ this._testRunnerAndScreen.releaseStdio();
101
+ this._testRunnerAndScreen = void 0;
102
+ }
89
103
  }
90
104
  async createTestRunner() {
91
- if (this._testRunner)
92
- await this._testRunner.stopTests();
93
- const testRunner = new import_testRunner.TestRunner(this.configLocation, {});
105
+ await this._cleanupTestRunner();
106
+ const testRunner = new import_testRunner.TestRunner(this._configLocation, {});
94
107
  await testRunner.initialize({});
108
+ const testPaused = new import_utils.ManualPromise();
109
+ const testRunnerAndScreen = {
110
+ ...createScreen(),
111
+ testRunner,
112
+ waitForTestPaused: () => testPaused
113
+ };
114
+ this._testRunnerAndScreen = testRunnerAndScreen;
95
115
  testRunner.on(import_testRunner.TestRunnerEvent.TestPaused, (params) => {
96
- void this._pushClient(async (request) => {
97
- const response = await params.sendMessage({ request });
98
- if (response.error)
99
- throw new Error(response.error.message);
100
- return response.response;
101
- });
116
+ testRunnerAndScreen.sendMessageToPausedTest = params.sendMessage;
117
+ testPaused.resolve();
102
118
  });
103
- this._testRunner = testRunner;
104
- return testRunner;
119
+ return testRunnerAndScreen;
105
120
  }
106
121
  async getOrCreateSeedFile(seedFile, projectName) {
107
- const configDir = this.configLocation.configDir;
108
- const testRunner = await this.createTestRunner();
122
+ const configDir = this._configLocation.configDir;
123
+ const { testRunner } = await this.createTestRunner();
109
124
  const config = await testRunner.loadConfig();
110
125
  const project = (0, import_seed.seedProject)(config, projectName);
111
126
  if (!seedFile) {
@@ -134,53 +149,91 @@ class TestContext {
134
149
  projectName: project.project.name
135
150
  };
136
151
  }
137
- async runSeedTest(seedFile, projectName, progress) {
138
- await this.runWithGlobalSetup(async (testRunner, reporter) => {
139
- const result = await testRunner.runTests(reporter, {
140
- headed: this.computedHeaded,
141
- locations: ["/" + (0, import_utils.escapeRegExp)(seedFile) + "/"],
142
- projects: [projectName],
143
- timeout: 0,
144
- workers: 1,
145
- pauseAtEnd: true,
146
- disableConfigReporters: true,
147
- failOnLoadErrors: true
148
- });
149
- if (result.status === "passed" && !reporter.suite?.allTests().length)
150
- throw new Error("seed test not found.");
151
- if (result.status !== "passed")
152
- throw new Error("Errors while running the seed test.");
153
- }, progress);
152
+ async runSeedTest(seedFile, projectName) {
153
+ const result = await this.runTestsWithGlobalSetupAndPossiblePause({
154
+ headed: this.computedHeaded,
155
+ locations: ["/" + (0, import_utils.escapeRegExp)(seedFile) + "/"],
156
+ projects: [projectName],
157
+ timeout: 0,
158
+ workers: 1,
159
+ pauseAtEnd: true,
160
+ disableConfigReporters: true,
161
+ failOnLoadErrors: true
162
+ });
163
+ if (result.status === "passed")
164
+ result.output += "\nError: seed test not found.";
165
+ else if (result.status !== "paused")
166
+ result.output += "\nError while running the seed test.";
167
+ return result;
154
168
  }
155
- async runWithGlobalSetup(callback, progress) {
156
- const { screen, claimStdio, releaseStdio } = createScreen(progress);
157
- const configDir = this.configLocation.configDir;
158
- const testRunner = await this.createTestRunner();
169
+ async runTestsWithGlobalSetupAndPossiblePause(params) {
170
+ const configDir = this._configLocation.configDir;
171
+ const testRunnerAndScreen = await this.createTestRunner();
172
+ const { testRunner, screen, claimStdio, releaseStdio } = testRunnerAndScreen;
159
173
  claimStdio();
160
174
  try {
161
175
  const setupReporter = new import_list.default({ configDir, screen, includeTestId: true });
162
- const { status } = await testRunner.runGlobalSetup([setupReporter]);
163
- if (status !== "passed")
164
- throw new Error("Failed to run global setup");
176
+ const { status: status2 } = await testRunner.runGlobalSetup([setupReporter]);
177
+ if (status2 !== "passed")
178
+ return { output: testRunnerAndScreen.output.join("\n"), status: status2 };
165
179
  } finally {
166
180
  releaseStdio();
167
181
  }
168
- try {
169
- const reporter = new import_list.default({ configDir, screen, includeTestId: true });
170
- return await callback(testRunner, reporter);
171
- } finally {
182
+ let status = "passed";
183
+ const cleanup = async () => {
172
184
  claimStdio();
173
- await testRunner.runGlobalTeardown().finally(() => {
185
+ try {
186
+ const result = await testRunner.runGlobalTeardown();
187
+ if (status === "passed")
188
+ status = result.status;
189
+ } finally {
174
190
  releaseStdio();
175
- });
191
+ }
192
+ };
193
+ try {
194
+ const reporter = new import_list.default({ configDir, screen, includeTestId: true });
195
+ status = await Promise.race([
196
+ testRunner.runTests(reporter, params).then((result) => result.status),
197
+ testRunnerAndScreen.waitForTestPaused().then(() => "paused")
198
+ ]);
199
+ if (status === "paused") {
200
+ const response = await testRunnerAndScreen.sendMessageToPausedTest({ request: { initialize: { clientInfo: this._clientInfo } } });
201
+ if (response.error)
202
+ throw new Error(response.error.message);
203
+ testRunnerAndScreen.output.push(response.response.initialize.pausedMessage);
204
+ return { output: testRunnerAndScreen.output.join("\n"), status };
205
+ }
206
+ } catch (e) {
207
+ status = "failed";
208
+ testRunnerAndScreen.output.push(String(e));
209
+ await cleanup();
210
+ return { output: testRunnerAndScreen.output.join("\n"), status };
176
211
  }
212
+ await cleanup();
213
+ return { output: testRunnerAndScreen.output.join("\n"), status };
177
214
  }
178
215
  async close() {
216
+ await this._cleanupTestRunner().catch(import_log.logUnhandledError);
217
+ }
218
+ async sendMessageToPausedTest(request) {
219
+ const sendMessage = this._testRunnerAndScreen?.sendMessageToPausedTest;
220
+ if (!sendMessage)
221
+ throw new Error("Must setup test before interacting with the page");
222
+ const result = await sendMessage({ request });
223
+ if (result.error)
224
+ throw new Error(result.error.message);
225
+ if (typeof request?.callTool?.arguments?.["intent"] === "string") {
226
+ const response = (0, import_response.parseResponse)(result.response.callTool);
227
+ if (response && !response.isError && response.code)
228
+ this.generatorJournal?.logStep(request.callTool.arguments["intent"], response.code);
229
+ }
230
+ return result.response;
179
231
  }
180
232
  }
181
- function createScreen(progress) {
182
- const stdout = new import_streams.StringWriteStream(progress, "stdout");
183
- const stderr = new import_streams.StringWriteStream(progress, "stderr");
233
+ function createScreen() {
234
+ const output = [];
235
+ const stdout = new import_streams.StringWriteStream(output, "stdout");
236
+ const stderr = new import_streams.StringWriteStream(output, "stderr");
184
237
  const screen = {
185
238
  ...import_base.terminalScreen,
186
239
  isTTY: false,
@@ -204,7 +257,7 @@ function createScreen(progress) {
204
257
  process.stdout.write = originalStdoutWrite;
205
258
  process.stderr.write = originalStderrWrite;
206
259
  };
207
- return { screen, claimStdio, releaseStdio };
260
+ return { screen, claimStdio, releaseStdio, output };
208
261
  }
209
262
  const bestPracticesMarkdown = `
210
263
  # Best practices
@@ -36,7 +36,6 @@ module.exports = __toCommonJS(testTools_exports);
36
36
  var import_bundle = require("../sdk/bundle");
37
37
  var import_listModeReporter = __toESM(require("../../reporters/listModeReporter"));
38
38
  var import_testTool = require("./testTool");
39
- var import_testContext = require("./testContext");
40
39
  const listTests = (0, import_testTool.defineTestTool)({
41
40
  schema: {
42
41
  name: "test_list",
@@ -45,12 +44,11 @@ const listTests = (0, import_testTool.defineTestTool)({
45
44
  inputSchema: import_bundle.z.object({}),
46
45
  type: "readOnly"
47
46
  },
48
- handle: async (context, _, progress) => {
49
- const { screen } = (0, import_testContext.createScreen)(progress);
47
+ handle: async (context) => {
48
+ const { testRunner, screen, output } = await context.createTestRunner();
50
49
  const reporter = new import_listModeReporter.default({ screen, includeTestId: true });
51
- const testRunner = await context.createTestRunner();
52
50
  await testRunner.listTests(reporter, {});
53
- return { content: [] };
51
+ return { content: output.map((text) => ({ type: "text", text })) };
54
52
  }
55
53
  });
56
54
  const runTests = (0, import_testTool.defineTestTool)({
@@ -64,15 +62,13 @@ const runTests = (0, import_testTool.defineTestTool)({
64
62
  }),
65
63
  type: "readOnly"
66
64
  },
67
- handle: async (context, params, progress) => {
68
- await context.runWithGlobalSetup(async (testRunner, reporter) => {
69
- await testRunner.runTests(reporter, {
70
- locations: params.locations,
71
- projects: params.projects,
72
- disableConfigReporters: true
73
- });
74
- }, progress);
75
- return { content: [] };
65
+ handle: async (context, params) => {
66
+ const { output } = await context.runTestsWithGlobalSetupAndPossiblePause({
67
+ locations: params.locations,
68
+ projects: params.projects,
69
+ disableConfigReporters: true
70
+ });
71
+ return { content: [{ type: "text", text: output }] };
76
72
  }
77
73
  });
78
74
  const debugTest = (0, import_testTool.defineTestTool)({
@@ -88,20 +84,18 @@ const debugTest = (0, import_testTool.defineTestTool)({
88
84
  }),
89
85
  type: "readOnly"
90
86
  },
91
- handle: async (context, params, progress) => {
92
- await context.runWithGlobalSetup(async (testRunner, reporter) => {
93
- await testRunner.runTests(reporter, {
94
- headed: context.computedHeaded,
95
- testIds: [params.test.id],
96
- // For automatic recovery
97
- timeout: 0,
98
- workers: 1,
99
- pauseOnError: true,
100
- disableConfigReporters: true,
101
- actionTimeout: 5e3
102
- });
103
- }, progress);
104
- return { content: [] };
87
+ handle: async (context, params) => {
88
+ const { output, status } = await context.runTestsWithGlobalSetupAndPossiblePause({
89
+ headed: context.computedHeaded,
90
+ testIds: [params.test.id],
91
+ // For automatic recovery
92
+ timeout: 0,
93
+ workers: 1,
94
+ pauseOnError: true,
95
+ disableConfigReporters: true,
96
+ actionTimeout: 5e3
97
+ });
98
+ return { content: [{ type: "text", text: output }], isError: status !== "paused" && status !== "passed" };
105
99
  }
106
100
  });
107
101
  // Annotate the CommonJS export names for ESM import in node:
@@ -483,6 +483,7 @@ class JobDispatcher {
483
483
  const result = test._appendTestResult();
484
484
  this._reporter.onTestBegin?.(test, result);
485
485
  result.status = "skipped";
486
+ result.annotations = [...test.annotations];
486
487
  this._reportTestEnd(test, result);
487
488
  }
488
489
  return true;
@@ -253,10 +253,6 @@ class TestRunner extends import_events.default {
253
253
  ...params.updateSourceMethod ? { updateSourceMethod: params.updateSourceMethod } : {},
254
254
  ...params.workers ? { workers: params.workers } : {}
255
255
  };
256
- if (params.trace === "on")
257
- process.env.PW_LIVE_TRACE_STACKS = "1";
258
- else
259
- process.env.PW_LIVE_TRACE_STACKS = void 0;
260
256
  const config = await this._loadConfigOrReportError(new import_internalReporter.InternalReporter([userReporter]), overrides);
261
257
  if (!config)
262
258
  return { status: "failed" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.57.0-alpha-2025-11-13",
3
+ "version": "1.57.0-alpha-2025-11-15",
4
4
  "description": "A high-level API to automate web browsers",
5
5
  "repository": {
6
6
  "type": "git",
@@ -64,7 +64,7 @@
64
64
  },
65
65
  "license": "Apache-2.0",
66
66
  "dependencies": {
67
- "playwright-core": "1.57.0-alpha-2025-11-13"
67
+ "playwright-core": "1.57.0-alpha-2025-11-15"
68
68
  },
69
69
  "optionalDependencies": {
70
70
  "fsevents": "2.3.2"
package/types/test.d.ts CHANGED
@@ -10198,14 +10198,14 @@ interface TestConfigWebServer {
10198
10198
  wait?: {
10199
10199
  /**
10200
10200
  * Regular expression to wait for in the `stdout` of the command output. Named capture groups are stored in the
10201
- * environment, for example /Listening on port (?<my_server_port>\\d+)/ will store the port number in
10201
+ * environment, for example `/Listening on port (?<my_server_port>\\d+)/` will store the port number in
10202
10202
  * `process.env['MY_SERVER_PORT']`.
10203
10203
  */
10204
10204
  stdout?: RegExp;
10205
10205
 
10206
10206
  /**
10207
10207
  * Regular expression to wait for in the `stderr` of the command output. Named capture groups are stored in the
10208
- * environment, for example /Listening on port (?<my_server_port>\\d+)/ will store the port number in
10208
+ * environment, for example `/Listening on port (?<my_server_port>\\d+)/` will store the port number in
10209
10209
  * `process.env['MY_SERVER_PORT']`.
10210
10210
  */
10211
10211
  stderr?: RegExp;