playwright 1.56.0-alpha-1758839353000 → 1.56.0-alpha-2025-09-27

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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # 🎭 Playwright
2
2
 
3
- [![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[![Chromium version](https://img.shields.io/badge/chromium-141.0.7390.16-blue.svg?logo=google-chrome)](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[![Firefox version](https://img.shields.io/badge/firefox-142.0.1-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[![WebKit version](https://img.shields.io/badge/webkit-26.0-blue.svg?logo=safari)](https://webkit.org/)<!-- GEN:stop --> [![Join Discord](https://img.shields.io/badge/join-discord-informational)](https://aka.ms/playwright/discord)
3
+ [![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) <!-- GEN:chromium-version-badge -->[![Chromium version](https://img.shields.io/badge/chromium-141.0.7390.37-blue.svg?logo=google-chrome)](https://www.chromium.org/Home)<!-- GEN:stop --> <!-- GEN:firefox-version-badge -->[![Firefox version](https://img.shields.io/badge/firefox-142.0.1-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/)<!-- GEN:stop --> <!-- GEN:webkit-version-badge -->[![WebKit version](https://img.shields.io/badge/webkit-26.0-blue.svg?logo=safari)](https://webkit.org/)<!-- GEN:stop --> [![Join Discord](https://img.shields.io/badge/join-discord-informational)](https://aka.ms/playwright/discord)
4
4
 
5
5
  ## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright)
6
6
 
@@ -8,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr
8
8
 
9
9
  | | Linux | macOS | Windows |
10
10
  | :--- | :---: | :---: | :---: |
11
- | Chromium <!-- GEN:chromium-version -->141.0.7390.16<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
11
+ | Chromium <!-- GEN:chromium-version -->141.0.7390.37<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
12
12
  | WebKit <!-- GEN:webkit-version -->26.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
13
13
  | Firefox <!-- GEN:firefox-version -->142.0.1<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
14
14
 
@@ -241,6 +241,7 @@ async function initVSCodeRepo() {
241
241
  type: "stdio",
242
242
  command: commonMcpServers.playwrightTest.command,
243
243
  args: commonMcpServers.playwrightTest.args,
244
+ cwd: "${workspaceFolder}",
244
245
  env: { "PLAYWRIGHT_MCP_TOOL_PREFIX": vscodeToolPrefix }
245
246
  };
246
247
  await writeFile(mcpJsonPath, JSON.stringify(mcpJson, null, 2));
@@ -9,8 +9,10 @@ tools:
9
9
  - read
10
10
  - write
11
11
  - edit
12
+ - playwright-test/browser_console_messages
12
13
  - playwright-test/browser_evaluate
13
14
  - playwright-test/browser_generate_locator
15
+ - playwright-test/browser_network_requests
14
16
  - playwright-test/browser_snapshot
15
17
  - playwright-test/test_debug
16
18
  - playwright-test/test_list
@@ -138,7 +138,7 @@ class Context {
138
138
  await promise.then(async ({ browserContext, close }) => {
139
139
  if (this.config.saveTrace)
140
140
  await browserContext.tracing.stop();
141
- const videos = browserContext.pages().map((page) => page.video()).filter((video) => !!video);
141
+ const videos = this.config.saveVideo ? browserContext.pages().map((page) => page.video()).filter((video) => !!video) : [];
142
142
  await close(async () => {
143
143
  for (const video of videos) {
144
144
  const name = await this.outputFile((0, import_utils.dateAsFileName)("webm"), { origin: "code", reason: "Saving video" });
@@ -38,7 +38,7 @@ class Tab extends import_events.EventEmitter {
38
38
  this._lastTitle = "about:blank";
39
39
  this._consoleMessages = [];
40
40
  this._recentConsoleMessages = [];
41
- this._requests = /* @__PURE__ */ new Map();
41
+ this._requests = /* @__PURE__ */ new Set();
42
42
  this._modalStates = [];
43
43
  this._downloads = [];
44
44
  this.context = context;
@@ -46,8 +46,7 @@ class Tab extends import_events.EventEmitter {
46
46
  this._onPageClose = onPageClose;
47
47
  page.on("console", (event) => this._handleConsoleMessage(messageToConsoleMessage(event)));
48
48
  page.on("pageerror", (error) => this._handleConsoleMessage(pageErrorToConsoleMessage(error)));
49
- page.on("request", (request) => this._requests.set(request, null));
50
- page.on("response", (response) => this._requests.set(response.request(), response));
49
+ page.on("request", (request) => this._requests.add(request));
51
50
  page.on("close", () => this._onClose());
52
51
  page.on("filechooser", (chooser) => {
53
52
  this.setModalState({
@@ -64,7 +63,7 @@ class Tab extends import_events.EventEmitter {
64
63
  page.setDefaultNavigationTimeout(this.context.config.timeouts.navigation);
65
64
  page.setDefaultTimeout(this.context.config.timeouts.action);
66
65
  page[tabSymbol] = this;
67
- void this._initialize();
66
+ this._initializedPromise = this._initialize();
68
67
  }
69
68
  static forPage(page) {
70
69
  return page[tabSymbol];
@@ -77,13 +76,8 @@ class Tab extends import_events.EventEmitter {
77
76
  for (const error of errors)
78
77
  this._handleConsoleMessage(pageErrorToConsoleMessage(error));
79
78
  const requests = await this.page.requests().catch(() => []);
80
- for (const request of requests) {
81
- this._requests.set(request, null);
82
- void request.response().catch(() => null).then((response) => {
83
- if (response)
84
- this._requests.set(request, response);
85
- });
86
- }
79
+ for (const request of requests)
80
+ this._requests.add(request);
87
81
  }
88
82
  modalStates() {
89
83
  return this._modalStates;
@@ -164,10 +158,12 @@ class Tab extends import_events.EventEmitter {
164
158
  }
165
159
  await this.waitForLoadState("load", { timeout: 5e3 });
166
160
  }
167
- consoleMessages() {
161
+ async consoleMessages() {
162
+ await this._initializedPromise;
168
163
  return this._consoleMessages;
169
164
  }
170
- requests() {
165
+ async requests() {
166
+ await this._initializedPromise;
171
167
  return this._requests;
172
168
  }
173
169
  async captureSnapshot() {
@@ -33,7 +33,8 @@ const console = (0, import_tool.defineTabTool)({
33
33
  type: "readOnly"
34
34
  },
35
35
  handle: async (tab, params, response) => {
36
- tab.consoleMessages().map((message) => response.addResult(message.toString()));
36
+ const messages = await tab.consoleMessages();
37
+ messages.map((message) => response.addResult(message.toString()));
37
38
  }
38
39
  });
39
40
  var console_default = [
@@ -33,15 +33,20 @@ const requests = (0, import_tool.defineTabTool)({
33
33
  type: "readOnly"
34
34
  },
35
35
  handle: async (tab, params, response) => {
36
- const requests2 = tab.requests();
37
- [...requests2.entries()].forEach(([req, res]) => response.addResult(renderRequest(req, res)));
36
+ const requests2 = await tab.requests();
37
+ for (const request of requests2)
38
+ response.addResult(await renderRequest(request));
38
39
  }
39
40
  });
40
- function renderRequest(request, response) {
41
+ async function renderRequest(request) {
41
42
  const result = [];
42
43
  result.push(`[${request.method().toUpperCase()}] ${request.url()}`);
43
- if (response)
44
- result.push(`=> [${response.status()}] ${response.statusText()}`);
44
+ const hasResponse = request._hasResponse;
45
+ if (hasResponse) {
46
+ const response = await request.response();
47
+ if (response)
48
+ result.push(`=> [${response.status()}] ${response.statusText()}`);
49
+ }
45
50
  return result.join(" ");
46
51
  }
47
52
  var network_default = [
@@ -150,7 +150,7 @@ test.describe('Test group', () => {
150
150
  const candidateFiles = [];
151
151
  candidateFiles.push(import_path.default.resolve(testDir, params.seedFile));
152
152
  candidateFiles.push(import_path.default.resolve(configDir, params.seedFile));
153
- candidateFiles.push(import_path.default.resolve(process.cwd(), params.seedFile));
153
+ candidateFiles.push(import_path.default.resolve(context.rootPath, params.seedFile));
154
154
  for (const candidateFile of candidateFiles) {
155
155
  if (await (0, import_util.fileExistsAsync)(candidateFile)) {
156
156
  seedFile = candidateFile;
@@ -169,7 +169,7 @@ ${seedFileContent}
169
169
  ` });
170
170
  const result = await testRunner.runTests(reporter, {
171
171
  headed: !context.options?.headless,
172
- locations: [seedFile],
172
+ locations: ["/" + (0, import_utils.escapeRegExp)(seedFile) + "/"],
173
173
  projects: params.project ? [params.project] : void 0,
174
174
  timeout: 0,
175
175
  workers: 1,
@@ -119,17 +119,10 @@ class HtmlReporter {
119
119
  else if (process.env.PLAYWRIGHT_HTML_NO_COPY_PROMPT)
120
120
  noCopyPrompt = true;
121
121
  noCopyPrompt = noCopyPrompt || this._options.noCopyPrompt;
122
- let noFiles;
123
- if (process.env.PLAYWRIGHT_HTML_NO_FILES === "false" || process.env.PLAYWRIGHT_HTML_NO_FILES === "0")
124
- noFiles = false;
125
- else if (process.env.PLAYWRIGHT_HTML_NO_FILES)
126
- noFiles = true;
127
- noFiles = noFiles || this._options.noFiles;
128
122
  const builder = new HtmlBuilder(this.config, this._outputFolder, this._attachmentsBaseURL, {
129
123
  title: process.env.PLAYWRIGHT_HTML_TITLE || this._options.title,
130
124
  noSnippets,
131
- noCopyPrompt,
132
- noFiles
125
+ noCopyPrompt
133
126
  });
134
127
  this._buildResult = await builder.build(this.config.metadata, projectSuites, result, this._topLevelErrors);
135
128
  }
@@ -229,20 +222,8 @@ class HtmlBuilder {
229
222
  for (const projectSuite of projectSuites) {
230
223
  const projectName = projectSuite.project().name;
231
224
  for (const fileSuite of projectSuite.suites) {
232
- if (this._options.noFiles) {
233
- for (const describeSuite of fileSuite.suites) {
234
- const groupName = describeSuite.title;
235
- this._createEntryForSuite(data, projectName, describeSuite, groupName, true);
236
- }
237
- const hasTestsOutsideGroups = fileSuite.tests.length > 0;
238
- if (hasTestsOutsideGroups) {
239
- const fileName = "<anonymous>";
240
- this._createEntryForSuite(data, projectName, fileSuite, fileName, false);
241
- }
242
- } else {
243
- const fileName = this._relativeLocation(fileSuite.location).file;
244
- this._createEntryForSuite(data, projectName, fileSuite, fileName, true);
245
- }
225
+ const fileName = this._relativeLocation(fileSuite.location).file;
226
+ this._createEntryForSuite(data, projectName, fileSuite, fileName, true);
246
227
  }
247
228
  }
248
229
  if (!this._options.noSnippets)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.56.0-alpha-1758839353000",
3
+ "version": "1.56.0-alpha-2025-09-27",
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.56.0-alpha-1758839353000"
67
+ "playwright-core": "1.56.0-alpha-2025-09-27"
68
68
  },
69
69
  "optionalDependencies": {
70
70
  "fsevents": "2.3.2"
package/types/test.d.ts CHANGED
@@ -31,7 +31,6 @@ export type HtmlReporterOptions = {
31
31
  title?: string;
32
32
  noSnippets?: boolean;
33
33
  noCopyPrompt?: boolean;
34
- noFiles?: boolean;
35
34
  };
36
35
 
37
36
  export type ReporterDescription = Readonly<