playwright 1.56.0-alpha-2025-09-17 → 1.56.0-alpha-2025-09-18

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.
@@ -29,10 +29,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  var generateAgents_exports = {};
30
30
  __export(generateAgents_exports, {
31
31
  initClaudeCodeRepo: () => initClaudeCodeRepo,
32
- initOpencodeRepo: () => initOpencodeRepo
32
+ initOpencodeRepo: () => initOpencodeRepo,
33
+ initVSCodeRepo: () => initVSCodeRepo
33
34
  });
34
35
  module.exports = __toCommonJS(generateAgents_exports);
35
- var import_crypto = __toESM(require("crypto"));
36
36
  var import_fs = __toESM(require("fs"));
37
37
  var import_path = __toESM(require("path"));
38
38
  var import_utilsBundle = require("playwright-core/lib/utilsBundle");
@@ -88,22 +88,28 @@ const claudeToolMap = /* @__PURE__ */ new Map([
88
88
  ["ls", ["Glob"]],
89
89
  ["grep", ["Grep"]],
90
90
  ["read", ["Read"]],
91
- ["edit", ["Edit", "MultiEdit", "NotebookEdit"]],
91
+ ["edit", ["Edit", "MultiEdit"]],
92
92
  ["write", ["Write"]]
93
93
  ]);
94
+ const commonMcpServers = {
95
+ playwrightTest: {
96
+ type: "local",
97
+ command: "npx",
98
+ args: ["playwright", "run-test-mcp-server"]
99
+ }
100
+ };
94
101
  function saveAsClaudeCode(agent) {
95
- function asClaudeTool(hash2, tool) {
102
+ function asClaudeTool(tool) {
96
103
  const [first, second] = tool.split("/");
97
104
  if (!second)
98
105
  return (claudeToolMap.get(first) || [first]).join(", ");
99
- return `mcp__${first}-${hash2}__${second}`;
106
+ return `mcp__${first}__${second}`;
100
107
  }
101
- const hash = shortHash(agent.header.name);
102
108
  const lines = [];
103
109
  lines.push(`---`);
104
110
  lines.push(`name: ${agent.header.name}`);
105
111
  lines.push(`description: ${agent.header.description}. Examples: ${agent.examples.map((example) => `<example>${example}</example>`).join("")}`);
106
- lines.push(`tools: ${agent.header.tools.map((tool) => asClaudeTool(hash, tool)).join(", ")}`);
112
+ lines.push(`tools: ${agent.header.tools.map((tool) => asClaudeTool(tool)).join(", ")}`);
107
113
  lines.push(`model: ${agent.header.model}`);
108
114
  lines.push(`color: ${agent.header.color}`);
109
115
  lines.push(`---`);
@@ -119,13 +125,13 @@ const opencodeToolMap = /* @__PURE__ */ new Map([
119
125
  ["write", ["write"]]
120
126
  ]);
121
127
  function saveAsOpencodeJson(agents) {
122
- function asOpencodeTool(tools, hash, tool) {
128
+ function asOpencodeTool(tools, tool) {
123
129
  const [first, second] = tool.split("/");
124
130
  if (!second) {
125
131
  for (const tool2 of opencodeToolMap.get(first) || [first])
126
132
  tools[tool2] = true;
127
133
  } else {
128
- tools[`${first}-${hash}*${second}`] = true;
134
+ tools[`${first}*${second}`] = true;
129
135
  }
130
136
  }
131
137
  const result = {};
@@ -136,7 +142,6 @@ function saveAsOpencodeJson(agents) {
136
142
  };
137
143
  result["agent"] = {};
138
144
  for (const agent of agents) {
139
- const hash = shortHash(agent.header.name);
140
145
  const tools = {};
141
146
  result["agent"][agent.header.name] = {
142
147
  description: agent.header.description,
@@ -145,20 +150,16 @@ function saveAsOpencodeJson(agents) {
145
150
  tools
146
151
  };
147
152
  for (const tool of agent.header.tools)
148
- asOpencodeTool(tools, hash, tool);
149
- for (const [name, mcp] of Object.entries(agent.header["mcp-servers"])) {
150
- result["mcp"][name + "-" + hash] = {
151
- type: mcp.type,
152
- command: [mcp.command, ...mcp.args],
153
- enabled: true
154
- };
155
- }
153
+ asOpencodeTool(tools, tool);
156
154
  }
155
+ const server = commonMcpServers.playwrightTest;
156
+ result["mcp"]["playwright-test"] = {
157
+ type: server.type,
158
+ command: [server.command, ...server.args],
159
+ enabled: true
160
+ };
157
161
  return JSON.stringify(result, null, 2);
158
162
  }
159
- function shortHash(str) {
160
- return import_crypto.default.createHash("sha256").update(str).digest("hex").slice(0, 4);
161
- }
162
163
  async function loadAgents() {
163
164
  const files = await import_fs.default.promises.readdir(__dirname);
164
165
  return Promise.all(files.filter((file) => file.endsWith(".md")).map((file) => AgentParser.parseFile(import_path.default.join(__dirname, file))));
@@ -172,18 +173,62 @@ async function initClaudeCodeRepo() {
172
173
  await import_fs.default.promises.mkdir(".claude/agents", { recursive: true });
173
174
  for (const agent of agents)
174
175
  await writeFile(`.claude/agents/${agent.header.name}.md`, saveAsClaudeCode(agent));
175
- const mcpServers = {};
176
- for (const agent of agents) {
177
- const hash = shortHash(agent.header.name);
178
- for (const [name, mcp] of Object.entries(agent.header["mcp-servers"])) {
179
- const entry = {
180
- command: mcp.command,
181
- args: mcp.args
182
- };
183
- mcpServers[name + "-" + hash] = entry;
176
+ await writeFile(".mcp.json", JSON.stringify({
177
+ mcpServers: {
178
+ "playwright-test": {
179
+ command: commonMcpServers.playwrightTest.command,
180
+ args: commonMcpServers.playwrightTest.args
181
+ }
184
182
  }
183
+ }, null, 2));
184
+ }
185
+ const vscodeToolMap = /* @__PURE__ */ new Map([
186
+ ["ls", ["listDirectory", "fileSearch"]],
187
+ ["grep", ["textSearch"]],
188
+ ["read", ["readFile"]],
189
+ ["edit", ["editFiles"]],
190
+ ["write", ["createFile", "createDirectory"]]
191
+ ]);
192
+ function saveAsVSCodeChatmode(agent) {
193
+ function asVscodeTool(tool) {
194
+ const [first, second] = tool.split("/");
195
+ if (second)
196
+ return second;
197
+ return vscodeToolMap.get(first) || first;
185
198
  }
186
- await writeFile(".mcp.json", JSON.stringify({ mcpServers }, null, 2));
199
+ const tools = agent.header.tools.map(asVscodeTool).flat().map((tool) => `'${tool}'`).join(", ");
200
+ const lines = [];
201
+ lines.push(`---`);
202
+ lines.push(`description: ${agent.header.description}. Examples: ${agent.examples.map((example) => `<example>${example}</example>`).join("")}`);
203
+ lines.push(`tools: [${tools}]`);
204
+ lines.push(`---`);
205
+ lines.push("");
206
+ lines.push(agent.instructions);
207
+ return lines.join("\n");
208
+ }
209
+ async function initVSCodeRepo() {
210
+ const agents = await loadAgents();
211
+ await import_fs.default.promises.mkdir(".github/chatmodes", { recursive: true });
212
+ for (const agent of agents)
213
+ await writeFile(`.github/chatmodes/${agent.header.name}.chatmode.md`, saveAsVSCodeChatmode(agent));
214
+ await import_fs.default.promises.mkdir(".vscode", { recursive: true });
215
+ const mcpJsonPath = ".vscode/mcp.json";
216
+ let mcpJson = {
217
+ servers: {},
218
+ inputs: []
219
+ };
220
+ try {
221
+ mcpJson = JSON.parse(import_fs.default.readFileSync(mcpJsonPath, "utf8"));
222
+ } catch {
223
+ }
224
+ if (!mcpJson.servers)
225
+ mcpJson.servers = {};
226
+ mcpJson.servers["playwright-test"] = {
227
+ type: "stdio",
228
+ command: commonMcpServers.playwrightTest.command,
229
+ args: commonMcpServers.playwrightTest.args
230
+ };
231
+ await writeFile(mcpJsonPath, JSON.stringify(mcpJson, null, 2));
187
232
  }
188
233
  async function initOpencodeRepo() {
189
234
  const agents = await loadAgents();
@@ -199,5 +244,6 @@ async function initOpencodeRepo() {
199
244
  // Annotate the CommonJS export names for ESM import in node:
200
245
  0 && (module.exports = {
201
246
  initClaudeCodeRepo,
202
- initOpencodeRepo
247
+ initOpencodeRepo,
248
+ initVSCodeRepo
203
249
  });
@@ -8,28 +8,23 @@ tools:
8
8
  - grep
9
9
  - read
10
10
  - write
11
- - playwright/browser_click
12
- - playwright/browser_drag
13
- - playwright/browser_evaluate
14
- - playwright/browser_file_upload
15
- - playwright/browser_handle_dialog
16
- - playwright/browser_hover
17
- - playwright/browser_navigate
18
- - playwright/browser_press_key
19
- - playwright/browser_select_option
20
- - playwright/browser_snapshot
21
- - playwright/browser_type
22
- - playwright/browser_verify_element_visible
23
- - playwright/browser_verify_list_visible
24
- - playwright/browser_verify_text_visible
25
- - playwright/browser_verify_value
26
- - playwright/browser_wait_for
27
- - playwright/test_setup_page
28
- mcp-servers:
29
- playwright:
30
- type: 'local'
31
- command: 'npx'
32
- args: ['playwright', 'run-test-mcp-server']
11
+ - playwright-test/browser_click
12
+ - playwright-test/browser_drag
13
+ - playwright-test/browser_evaluate
14
+ - playwright-test/browser_file_upload
15
+ - playwright-test/browser_handle_dialog
16
+ - playwright-test/browser_hover
17
+ - playwright-test/browser_navigate
18
+ - playwright-test/browser_press_key
19
+ - playwright-test/browser_select_option
20
+ - playwright-test/browser_snapshot
21
+ - playwright-test/browser_type
22
+ - playwright-test/browser_verify_element_visible
23
+ - playwright-test/browser_verify_list_visible
24
+ - playwright-test/browser_verify_text_visible
25
+ - playwright-test/browser_verify_value
26
+ - playwright-test/browser_wait_for
27
+ - playwright-test/test_setup_page
33
28
  ---
34
29
 
35
30
  You are a Playwright Test Generator, an expert in browser automation and end-to-end testing. Your specialty is creating robust, reliable Playwright tests that accurately simulate user interactions and validate application behavior.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: playwright-test-fixer
2
+ name: playwright-test-healer
3
3
  description: Use this agent when you need to debug and fix failing Playwright tests
4
4
  color: red
5
5
  model: sonnet
@@ -9,21 +9,15 @@ tools:
9
9
  - read
10
10
  - write
11
11
  - edit
12
- - playwright/browser_evaluate
13
- - playwright/browser_generate_locator
14
- - playwright/browser_snapshot
15
- - playwright/test_debug
16
- - playwright/test_list
17
- - playwright/test_run
18
- - playwright/test_setup_page
19
- mcp-servers:
20
- playwright:
21
- type: 'local'
22
- command: 'npx'
23
- args: ['playwright', 'run-test-mcp-server']
12
+ - playwright-test/browser_evaluate
13
+ - playwright-test/browser_generate_locator
14
+ - playwright-test/browser_snapshot
15
+ - playwright-test/test_debug
16
+ - playwright-test/test_list
17
+ - playwright-test/test_run
24
18
  ---
25
19
 
26
- You are the Playwright Test Fixer, an expert test automation engineer specializing in debugging and
20
+ You are the Playwright Test Healer, an expert test automation engineer specializing in debugging and
27
21
  resolving Playwright test failures. Your mission is to systematically identify, diagnose, and fix
28
22
  broken Playwright tests using a methodical approach.
29
23
 
@@ -43,7 +37,7 @@ Your workflow:
43
37
  - Updating selectors to match current application state
44
38
  - Fixing assertions and expected values
45
39
  - Improving test reliability and maintainability
46
- - For inherently dynamic data, utilize regular expressions to produce resilient locators
40
+ - For inherently dynamic data, utilize regular expressions to produce resilient locators
47
41
  6. **Verification**: Restart the test after each fix to validate the changes
48
42
  7. **Iteration**: Repeat the investigation and fixing process until the test passes cleanly
49
43
 
@@ -62,19 +56,19 @@ Key principles:
62
56
  <example>
63
57
  Context: A developer has a failing Playwright test that needs to be debugged and fixed.
64
58
  user: 'The login test is failing, can you fix it?'
65
- assistant: 'I'll use the playwright-test-fixer agent to debug and fix the failing login test.'
59
+ assistant: 'I'll use the playwright-test-healer agent to debug and fix the failing login test.'
66
60
  <commentary>
67
61
  The user has identified a specific failing test that needs debugging and fixing, which is exactly what the
68
- playwright-test-fixer agent is designed for.
62
+ playwright-test-healer agent is designed for.
69
63
  </commentary>
70
64
  </example>
71
65
 
72
66
  <example>
73
67
  Context: After running a test suite, several tests are reported as failing.
74
68
  user: 'Test user-registration.spec.ts is broken after the recent changes'
75
- assistant: 'Let me use the playwright-test-fixer agent to investigate and fix the user-registration test.'
69
+ assistant: 'Let me use the playwright-test-healer agent to investigate and fix the user-registration test.'
76
70
  <commentary>
77
71
  A specific test file is failing and needs debugging, which requires the systematic approach of the
78
- playwright-test-fixer agent.
72
+ playwright-test-healer agent.
79
73
  </commentary>
80
74
  </example>
@@ -8,36 +8,31 @@ tools:
8
8
  - grep
9
9
  - read
10
10
  - write
11
- - playwright/browser_click
12
- - playwright/browser_close
13
- - playwright/browser_console_messages
14
- - playwright/browser_drag
15
- - playwright/browser_evaluate
16
- - playwright/browser_file_upload
17
- - playwright/browser_handle_dialog
18
- - playwright/browser_hover
19
- - playwright/browser_navigate
20
- - playwright/browser_navigate_back
21
- - playwright/browser_network_requests
22
- - playwright/browser_press_key
23
- - playwright/browser_select_option
24
- - playwright/browser_snapshot
25
- - playwright/browser_take_screenshot
26
- - playwright/browser_type
27
- - playwright/browser_wait_for
28
- - playwright/test_setup_page
29
- mcp-servers:
30
- playwright:
31
- type: 'local'
32
- command: 'npx'
33
- args: ['playwright', 'run-test-mcp-server']
11
+ - playwright-test/browser_click
12
+ - playwright-test/browser_close
13
+ - playwright-test/browser_console_messages
14
+ - playwright-test/browser_drag
15
+ - playwright-test/browser_evaluate
16
+ - playwright-test/browser_file_upload
17
+ - playwright-test/browser_handle_dialog
18
+ - playwright-test/browser_hover
19
+ - playwright-test/browser_navigate
20
+ - playwright-test/browser_navigate_back
21
+ - playwright-test/browser_network_requests
22
+ - playwright-test/browser_press_key
23
+ - playwright-test/browser_select_option
24
+ - playwright-test/browser_snapshot
25
+ - playwright-test/browser_take_screenshot
26
+ - playwright-test/browser_type
27
+ - playwright-test/browser_wait_for
28
+ - playwright-test/test_setup_page
34
29
  ---
35
30
 
36
31
  You are an expert web test planner with extensive experience in quality assurance, user experience testing, and test scenario design. Your expertise includes functional testing, usability testing, edge case identification, and comprehensive test coverage planning.
37
32
 
38
33
  When given a target web page or application, you will:
39
34
 
40
- 1. **Navigate and Explore**:
35
+ 1. **Navigate and Explore**:
41
36
  - Invoke the `test_setup_page` tool once to set up page before using any other tools
42
37
  - Explore the aria snapshot, use browser_* tools to navigate and discover interface.
43
38
  - Thoroughly explore the interface, identifying all interactive elements, forms, navigation paths, and functionality
@@ -38,7 +38,6 @@ var import_path = __toESM(require("path"));
38
38
  var playwright = __toESM(require("playwright-core"));
39
39
  var import_registry = require("playwright-core/lib/server/registry/index");
40
40
  var import_server = require("playwright-core/lib/server");
41
- var import_processUtils = require("./processUtils");
42
41
  var import_log = require("../log");
43
42
  var import_config = require("./config");
44
43
  var import_server2 = require("../sdk/server");
@@ -162,32 +161,32 @@ class PersistentContextFactory {
162
161
  (0, import_log.testDebug)("lock user data dir", userDataDir);
163
162
  const browserType = playwright[this.config.browser.browserName];
164
163
  for (let i = 0; i < 5; i++) {
165
- if (!await alreadyRunning(this.config, browserType, userDataDir))
166
- break;
167
- await new Promise((resolve) => setTimeout(resolve, 1e3));
168
- }
169
- const launchOptions = {
170
- tracesDir,
171
- ...this.config.browser.launchOptions,
172
- ...this.config.browser.contextOptions,
173
- handleSIGINT: false,
174
- handleSIGTERM: false,
175
- ignoreDefaultArgs: [
176
- "--disable-extensions"
177
- ],
178
- assistantMode: true
179
- };
180
- try {
181
- const browserContext = await browserType.launchPersistentContext(userDataDir, launchOptions);
182
- const close = () => this._closeBrowserContext(browserContext, userDataDir);
183
- return { browserContext, close };
184
- } catch (error) {
185
- if (error.message.includes("Executable doesn't exist"))
186
- throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
187
- if (error.message.includes("ProcessSingleton") || error.message.includes("Invalid URL"))
188
- throw new Error(`Browser is already in use for ${userDataDir}, use --isolated to run multiple instances of the same browser`);
189
- throw error;
164
+ const launchOptions = {
165
+ tracesDir,
166
+ ...this.config.browser.launchOptions,
167
+ ...this.config.browser.contextOptions,
168
+ handleSIGINT: false,
169
+ handleSIGTERM: false,
170
+ ignoreDefaultArgs: [
171
+ "--disable-extensions"
172
+ ],
173
+ assistantMode: true
174
+ };
175
+ try {
176
+ const browserContext = await browserType.launchPersistentContext(userDataDir, launchOptions);
177
+ const close = () => this._closeBrowserContext(browserContext, userDataDir);
178
+ return { browserContext, close };
179
+ } catch (error) {
180
+ if (error.message.includes("Executable doesn't exist"))
181
+ throw new Error(`Browser specified in your config is not installed. Either install it (likely) or change the config.`);
182
+ if (error.message.includes("ProcessSingleton") || error.message.includes("Invalid URL")) {
183
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
184
+ continue;
185
+ }
186
+ throw error;
187
+ }
190
188
  }
189
+ throw new Error(`Browser is already in use for ${userDataDir}, use --isolated to run multiple instances of the same browser`);
191
190
  }
192
191
  async _closeBrowserContext(browserContext, userDataDir) {
193
192
  (0, import_log.testDebug)("close browser context (persistent)");
@@ -207,12 +206,6 @@ class PersistentContextFactory {
207
206
  return result;
208
207
  }
209
208
  }
210
- async function alreadyRunning(config, browserType, userDataDir) {
211
- const execPath = config.browser.launchOptions.executablePath ?? (0, import_processUtils.getBrowserExecPath)(config.browser.launchOptions.channel ?? browserType.name());
212
- if (!execPath)
213
- return false;
214
- return !!(0, import_processUtils.findBrowserProcess)(execPath, userDataDir);
215
- }
216
209
  async function injectCdpPort(browserConfig) {
217
210
  if (browserConfig.browserName === "chromium")
218
211
  browserConfig.launchOptions.cdpPort = await findFreePort();
package/lib/program.js CHANGED
@@ -175,9 +175,12 @@ function addInitAgentsCommand(program3) {
175
175
  command.description("Initialize repository agents for the Claude Code");
176
176
  command.option("--claude", "Initialize repository agents for the Claude Code");
177
177
  command.option("--opencode", "Initialize repository agents for the Opencode");
178
+ command.option("--vscode", "Initialize repository agents for the VS Code Copilot");
178
179
  command.action(async (opts) => {
179
180
  if (opts.opencode)
180
181
  await (0, import_generateAgents.initOpencodeRepo)();
182
+ else if (opts.vscode)
183
+ await (0, import_generateAgents.initVSCodeRepo)();
181
184
  else
182
185
  await (0, import_generateAgents.initClaudeCodeRepo)();
183
186
  });
@@ -113,7 +113,17 @@ class HtmlReporter {
113
113
  else if (process.env.PLAYWRIGHT_HTML_NO_SNIPPETS)
114
114
  noSnippets = true;
115
115
  noSnippets = noSnippets || this._options.noSnippets;
116
- const builder = new HtmlBuilder(this.config, this._outputFolder, this._attachmentsBaseURL, process.env.PLAYWRIGHT_HTML_TITLE || this._options.title, noSnippets);
116
+ let noCopyPrompt;
117
+ if (process.env.PLAYWRIGHT_HTML_NO_COPY_PROMPT === "false" || process.env.PLAYWRIGHT_HTML_NO_COPY_PROMPT === "0")
118
+ noCopyPrompt = false;
119
+ else if (process.env.PLAYWRIGHT_HTML_NO_COPY_PROMPT)
120
+ noCopyPrompt = true;
121
+ noCopyPrompt = noCopyPrompt || this._options.noCopyPrompt;
122
+ const builder = new HtmlBuilder(this.config, this._outputFolder, this._attachmentsBaseURL, {
123
+ title: process.env.PLAYWRIGHT_HTML_TITLE || this._options.title,
124
+ noSnippets,
125
+ noCopyPrompt
126
+ });
117
127
  this._buildResult = await builder.build(this.config.metadata, projectSuites, result, this._topLevelErrors);
118
128
  }
119
129
  async onExit() {
@@ -197,16 +207,15 @@ function startHtmlReportServer(folder) {
197
207
  return server;
198
208
  }
199
209
  class HtmlBuilder {
200
- constructor(config, outputDir, attachmentsBaseURL, title, noSnippets = false) {
210
+ constructor(config, outputDir, attachmentsBaseURL, options) {
201
211
  this._stepsInFile = new import_utils.MultiMap();
202
212
  this._hasTraces = false;
203
213
  this._config = config;
204
214
  this._reportFolder = outputDir;
205
- this._noSnippets = noSnippets;
215
+ this._options = options;
206
216
  import_fs.default.mkdirSync(this._reportFolder, { recursive: true });
207
217
  this._dataZipFile = new import_zipBundle.yazl.ZipFile();
208
218
  this._attachmentsBaseURL = attachmentsBaseURL;
209
- this._title = title;
210
219
  }
211
220
  async build(metadata, projectSuites, result, topLevelErrors) {
212
221
  const data = /* @__PURE__ */ new Map();
@@ -231,7 +240,7 @@ class HtmlBuilder {
231
240
  }
232
241
  }
233
242
  }
234
- if (!this._noSnippets)
243
+ if (!this._options.noSnippets)
235
244
  createSnippets(this._stepsInFile);
236
245
  let ok = true;
237
246
  for (const [fileId, { testFile, testFileSummary }] of data) {
@@ -260,13 +269,13 @@ class HtmlBuilder {
260
269
  }
261
270
  const htmlReport = {
262
271
  metadata,
263
- title: this._title,
264
272
  startTime: result.startTime.getTime(),
265
273
  duration: result.duration,
266
274
  files: [...data.values()].map((e) => e.testFileSummary),
267
275
  projectNames: projectSuites.map((r) => r.project().name),
268
276
  stats: { ...[...data.values()].reduce((a, e) => addStats(a, e.testFileSummary.stats), emptyStats()) },
269
- errors: topLevelErrors.map((error) => (0, import_base.formatError)(import_base.internalScreen, error).message)
277
+ errors: topLevelErrors.map((error) => (0, import_base.formatError)(import_base.internalScreen, error).message),
278
+ options: this._options
270
279
  };
271
280
  htmlReport.files.sort((f1, f2) => {
272
281
  const w1 = f1.stats.unexpected * 1e3 + f1.stats.flaky;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.56.0-alpha-2025-09-17",
3
+ "version": "1.56.0-alpha-2025-09-18",
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-2025-09-17"
67
+ "playwright-core": "1.56.0-alpha-2025-09-18"
68
68
  },
69
69
  "optionalDependencies": {
70
70
  "fsevents": "2.3.2"
package/types/test.d.ts CHANGED
@@ -22,7 +22,16 @@ export type BlobReporterOptions = { outputDir?: string, fileName?: string };
22
22
  export type ListReporterOptions = { printSteps?: boolean };
23
23
  export type JUnitReporterOptions = { outputFile?: string, stripANSIControlSequences?: boolean, includeProjectInTestName?: boolean };
24
24
  export type JsonReporterOptions = { outputFile?: string };
25
- export type HtmlReporterOptions = { outputFolder?: string, open?: 'always' | 'never' | 'on-failure', host?: string, port?: number, attachmentsBaseURL?: string, title?: string, noSnippets?: boolean };
25
+ export type HtmlReporterOptions = {
26
+ outputFolder?: string;
27
+ open?: 'always' | 'never' | 'on-failure';
28
+ host?: string;
29
+ port?: number;
30
+ attachmentsBaseURL?: string;
31
+ title?: string;
32
+ noSnippets?: boolean;
33
+ noCopyPrompt?: boolean;
34
+ };
26
35
 
27
36
  export type ReporterDescription = Readonly<
28
37
  ['blob'] | ['blob', BlobReporterOptions] |
@@ -1,102 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
- }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var processUtils_exports = {};
30
- __export(processUtils_exports, {
31
- findBrowserProcess: () => findBrowserProcess,
32
- getBrowserExecPath: () => getBrowserExecPath
33
- });
34
- module.exports = __toCommonJS(processUtils_exports);
35
- var import_child_process = __toESM(require("child_process"));
36
- var import_fs = __toESM(require("fs"));
37
- var import_registry = require("playwright-core/lib/server/registry/index");
38
- function getBrowserExecPath(channelOrName) {
39
- return import_registry.registry.findExecutable(channelOrName)?.executablePath("javascript");
40
- }
41
- function findBrowserProcess(execPath, arg) {
42
- const predicate = (line) => line.includes(execPath) && line.includes(arg) && !line.includes("--type");
43
- try {
44
- switch (process.platform) {
45
- case "darwin":
46
- return findProcessMacos(predicate);
47
- case "linux":
48
- return findProcessLinux(predicate);
49
- case "win32":
50
- return findProcessWindows(execPath, arg, predicate);
51
- default:
52
- return void 0;
53
- }
54
- } catch {
55
- return void 0;
56
- }
57
- }
58
- function findProcessLinux(predicate) {
59
- const procDirs = import_fs.default.readdirSync("/proc").filter((name) => /^\d+$/.test(name));
60
- for (const pid of procDirs) {
61
- try {
62
- const cmdlineBuffer = import_fs.default.readFileSync(`/proc/${pid}/cmdline`);
63
- const cmdline = cmdlineBuffer.toString().replace(/\0/g, " ").trim();
64
- if (predicate(cmdline))
65
- return `${pid} ${cmdline}`;
66
- } catch {
67
- continue;
68
- }
69
- }
70
- return void 0;
71
- }
72
- function findProcessMacos(predicate) {
73
- const result = import_child_process.default.spawnSync("/bin/ps", ["-axo", "pid=,command="]);
74
- if (result.status !== 0 || !result.stdout)
75
- return void 0;
76
- return findMatchingLine(result.stdout.toString(), predicate);
77
- }
78
- function findProcessWindows(execPath, arg, predicate) {
79
- const psEscape = (path) => `'${path.replaceAll("'", "''")}'`;
80
- const filter = `$_.ExecutablePath -eq ${psEscape(execPath)} -and $_.CommandLine.Contains(${psEscape(arg)}) -and $_.CommandLine -notmatch '--type'`;
81
- const ps = import_child_process.default.spawnSync(
82
- "powershell.exe",
83
- [
84
- "-NoProfile",
85
- "-Command",
86
- `Get-CimInstance Win32_Process | Where-Object { ${filter} } | Select-Object -Property ProcessId,CommandLine | ForEach-Object { "$($_.ProcessId) $($_.CommandLine)" }`
87
- ],
88
- { encoding: "utf8" }
89
- );
90
- if (ps.status !== 0 || !ps.stdout)
91
- return void 0;
92
- return findMatchingLine(ps.stdout.toString(), predicate);
93
- }
94
- function findMatchingLine(psOutput, predicate) {
95
- const lines = psOutput.split("\n").map((l) => l.trim()).filter(Boolean);
96
- return lines.find(predicate);
97
- }
98
- // Annotate the CommonJS export names for ESM import in node:
99
- 0 && (module.exports = {
100
- findBrowserProcess,
101
- getBrowserExecPath
102
- });