playwright 1.56.0-alpha-2025-09-10 → 1.56.0-alpha-2025-09-11

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.
@@ -30,7 +30,7 @@ const uploadFile = (0, import_tool.defineTabTool)({
30
30
  title: "Upload files",
31
31
  description: "Upload one or multiple files",
32
32
  inputSchema: import_bundle.z.object({
33
- paths: import_bundle.z.array(import_bundle.z.string()).describe("The absolute paths to the files to upload. Can be a single file or multiple files.")
33
+ paths: import_bundle.z.array(import_bundle.z.string()).optional().describe("The absolute paths to the files to upload. Can be single file or multiple files. If omitted, file chooser is cancelled.")
34
34
  }),
35
35
  type: "destructive"
36
36
  },
@@ -42,7 +42,8 @@ const uploadFile = (0, import_tool.defineTabTool)({
42
42
  response.addCode(`await fileChooser.setFiles(${JSON.stringify(params.paths)})`);
43
43
  tab.clearModalState(modalState);
44
44
  await tab.waitForCompletion(async () => {
45
- await modalState.fileChooser.setFiles(params.paths);
45
+ if (params.paths)
46
+ await modalState.fileChooser.setFiles(params.paths);
46
47
  });
47
48
  },
48
49
  clearsModalState: "fileChooser"
@@ -154,12 +154,27 @@ const selectOption = (0, import_tool.defineTabTool)({
154
154
  });
155
155
  }
156
156
  });
157
+ const pickLocator = (0, import_tool.defineTabTool)({
158
+ capability: "testing",
159
+ schema: {
160
+ name: "browser_generate_locator",
161
+ title: "Create locator for element",
162
+ description: "Generate locator for the given element to use in tests",
163
+ inputSchema: elementSchema,
164
+ type: "readOnly"
165
+ },
166
+ handle: async (tab, params, response) => {
167
+ const locator = await tab.refLocator(params);
168
+ response.addResult(await (0, import_utils.generateLocator)(locator));
169
+ }
170
+ });
157
171
  var snapshot_default = [
158
172
  snapshot,
159
173
  click,
160
174
  drag,
161
175
  hover,
162
- selectOption
176
+ selectOption,
177
+ pickLocator
163
178
  ];
164
179
  // Annotate the CommonJS export names for ESM import in node:
165
180
  0 && (module.exports = {
@@ -29,7 +29,7 @@ function defineTabTool(tool) {
29
29
  return {
30
30
  ...tool,
31
31
  handle: async (context, params, response) => {
32
- const tab = context.currentTabOrDie();
32
+ const tab = await context.ensureTab();
33
33
  const modalStates = tab.modalStates().map((state) => state.type);
34
34
  if (tool.clearsModalState && !modalStates.includes(tool.clearsModalState))
35
35
  response.addError(`Error: The tool "${tool.schema.name}" can only be used when there is related modal state present.
@@ -36,7 +36,7 @@ var import_tool = require("./tool");
36
36
  var javascript = __toESM(require("../codegen"));
37
37
  var import_utils = require("./utils");
38
38
  const verifyElement = (0, import_tool.defineTabTool)({
39
- capability: "verify",
39
+ capability: "testing",
40
40
  schema: {
41
41
  name: "browser_verify_element_visible",
42
42
  title: "Verify element visible",
@@ -58,7 +58,7 @@ const verifyElement = (0, import_tool.defineTabTool)({
58
58
  }
59
59
  });
60
60
  const verifyText = (0, import_tool.defineTabTool)({
61
- capability: "verify",
61
+ capability: "testing",
62
62
  schema: {
63
63
  name: "browser_verify_text_visible",
64
64
  title: "Verify text visible",
@@ -79,7 +79,7 @@ const verifyText = (0, import_tool.defineTabTool)({
79
79
  }
80
80
  });
81
81
  const verifyList = (0, import_tool.defineTabTool)({
82
- capability: "verify",
82
+ capability: "testing",
83
83
  schema: {
84
84
  name: "browser_verify_list_visible",
85
85
  title: "Verify list visible",
@@ -111,7 +111,7 @@ ${itemTexts.map((t) => ` - listitem: ${javascript.escapeWithQuotes(t, '"')}`).j
111
111
  }
112
112
  });
113
113
  const verifyValue = (0, import_tool.defineTabTool)({
114
- capability: "verify",
114
+ capability: "testing",
115
115
  schema: {
116
116
  name: "browser_verify_value",
117
117
  title: "Verify value",
@@ -28,7 +28,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var tools_exports = {};
30
30
  __export(tools_exports, {
31
- allTools: () => allTools,
31
+ browserTools: () => browserTools,
32
32
  filteredTools: () => filteredTools
33
33
  });
34
34
  module.exports = __toCommonJS(tools_exports);
@@ -50,7 +50,7 @@ var import_tabs = __toESM(require("./tools/tabs"));
50
50
  var import_tracing = __toESM(require("./tools/tracing"));
51
51
  var import_wait = __toESM(require("./tools/wait"));
52
52
  var import_verify = __toESM(require("./tools/verify"));
53
- const allTools = [
53
+ const browserTools = [
54
54
  ...import_common.default,
55
55
  ...import_console.default,
56
56
  ...import_dialogs.default,
@@ -71,10 +71,10 @@ const allTools = [
71
71
  ...import_verify.default
72
72
  ];
73
73
  function filteredTools(config) {
74
- return allTools.filter((tool) => tool.capability.startsWith("core") || config.capabilities?.includes(tool.capability));
74
+ return browserTools.filter((tool) => tool.capability.startsWith("core") || config.capabilities?.includes(tool.capability));
75
75
  }
76
76
  // Annotate the CommonJS export names for ESM import in node:
77
77
  0 && (module.exports = {
78
- allTools,
78
+ browserTools,
79
79
  filteredTools
80
80
  });
@@ -28,66 +28,43 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
  var browserBackend_exports = {};
30
30
  __export(browserBackend_exports, {
31
- BrowserBackend: () => BrowserBackend,
32
31
  runBrowserBackendOnError: () => runBrowserBackendOnError
33
32
  });
34
33
  module.exports = __toCommonJS(browserBackend_exports);
35
34
  var mcp = __toESM(require("../sdk/exports"));
36
- var mcpBundle = __toESM(require("../sdk/bundle"));
37
35
  var import_globals = require("../../common/globals");
38
- var import_browserTools = require("./browserTools");
39
36
  var import_util = require("../../util");
40
- const tools = [import_browserTools.snapshot, import_browserTools.pickLocator, import_browserTools.evaluate];
41
- class BrowserBackend {
42
- constructor(page) {
43
- this.name = "Playwright";
44
- this.version = "0.0.1";
45
- this._tools = tools;
46
- this._page = page;
47
- }
48
- async initialize() {
49
- }
50
- async listTools() {
51
- return [...this._tools.map((tool) => mcp.toMcpTool(tool.schema)), mcp.toMcpTool(doneToolSchema)];
52
- }
53
- async callTool(name, args) {
54
- if (name === "done") {
55
- this.requestSelfDestruct?.();
56
- return {
57
- content: [{ type: "text", text: "Done" }]
58
- };
59
- }
60
- const tool = this._tools.find((tool2) => tool2.schema.name === name);
61
- if (!tool)
62
- throw new Error(`Tool not found: ${name}. Available tools: ${this._tools.map((tool2) => tool2.schema.name).join(", ")}`);
63
- const parsedArguments = tool.schema.inputSchema.parse(args || {});
64
- return await tool.handle(this._page, parsedArguments);
65
- }
66
- }
67
- const doneToolSchema = mcp.defineToolSchema({
68
- name: "done",
69
- title: "Done",
70
- description: "Done",
71
- inputSchema: mcpBundle.z.object({}),
72
- type: "destructive"
73
- });
37
+ var import_config = require("../browser/config");
38
+ var import_browserServerBackend = require("../browser/browserServerBackend");
74
39
  async function runBrowserBackendOnError(page, message) {
75
40
  const testInfo = (0, import_globals.currentTestInfo)();
76
41
  if (!testInfo || !testInfo._pauseOnError())
77
42
  return;
78
- const snapshot2 = await page._snapshotForAI();
43
+ const browserContextFactory = {
44
+ createContext: async (clientInfo, abortSignal, toolName) => {
45
+ return {
46
+ browserContext: page.context(),
47
+ close: async () => {
48
+ }
49
+ };
50
+ }
51
+ };
52
+ const config = {
53
+ ...import_config.defaultConfig,
54
+ capabilities: ["testing"]
55
+ };
56
+ const snapshot = await page._snapshotForAI();
79
57
  const introMessage = `### Paused on error:
80
58
  ${(0, import_util.stripAnsiEscapes)(message())}
81
59
 
82
60
  ### Current page snapshot:
83
- ${snapshot2}
61
+ ${snapshot}
84
62
 
85
63
  ### Task
86
- Try recovering from the error prior to continuing, use following tools to recover: ${tools.map((tool) => tool.schema.name).join(", ")}`;
87
- await mcp.runOnPauseBackendLoop(new BrowserBackend(page), introMessage);
64
+ Try recovering from the error prior to continuing`;
65
+ await mcp.runOnPauseBackendLoop(new import_browserServerBackend.BrowserServerBackend(config, browserContextFactory), introMessage);
88
66
  }
89
67
  // Annotate the CommonJS export names for ESM import in node:
90
68
  0 && (module.exports = {
91
- BrowserBackend,
92
69
  runBrowserBackendOnError
93
70
  });
@@ -34,7 +34,7 @@ module.exports = __toCommonJS(testBackend_exports);
34
34
  var mcp = __toESM(require("../sdk/exports"));
35
35
  var import_testContext = require("./testContext");
36
36
  var import_testTools = require("./testTools.js");
37
- var import_browserTools = require("./browserTools");
37
+ var import_tools = require("../browser/tools");
38
38
  class TestServerBackend {
39
39
  constructor(resolvedLocation, options) {
40
40
  this.name = "Playwright";
@@ -45,9 +45,7 @@ class TestServerBackend {
45
45
  async listTools() {
46
46
  return [
47
47
  ...this._tools.map((tool) => mcp.toMcpTool(tool.schema)),
48
- mcp.toMcpTool(import_browserTools.snapshot.schema),
49
- mcp.toMcpTool(import_browserTools.pickLocator.schema),
50
- mcp.toMcpTool(import_browserTools.evaluate.schema)
48
+ ...import_tools.browserTools.map((tool) => mcp.toMcpTool(tool.schema))
51
49
  ];
52
50
  }
53
51
  async callTool(name, args) {
package/lib/util.js CHANGED
@@ -30,7 +30,6 @@ var util_exports = {};
30
30
  __export(util_exports, {
31
31
  addSuffixToFilePath: () => addSuffixToFilePath,
32
32
  ansiRegex: () => ansiRegex,
33
- callLogText: () => callLogText,
34
33
  createFileFiltersFromArguments: () => createFileFiltersFromArguments,
35
34
  createFileMatcher: () => createFileMatcher,
36
35
  createFileMatcherFromArguments: () => createFileMatcherFromArguments,
@@ -227,14 +226,6 @@ function getContainedPath(parentPath, subPath = "") {
227
226
  return null;
228
227
  }
229
228
  const debugTest = (0, import_utilsBundle.debug)("pw:test");
230
- const callLogText = (log) => {
231
- if (!log || !log.some((l) => !!l))
232
- return "";
233
- return `
234
- Call log:
235
- ${import_utilsBundle.colors.dim(log.join("\n"))}
236
- `;
237
- };
238
229
  const folderToPackageJsonPath = /* @__PURE__ */ new Map();
239
230
  function getPackageJsonPath(folderPath) {
240
231
  const cached = folderToPackageJsonPath.get(folderPath);
@@ -376,7 +367,6 @@ function stripAnsiEscapes(str) {
376
367
  0 && (module.exports = {
377
368
  addSuffixToFilePath,
378
369
  ansiRegex,
379
- callLogText,
380
370
  createFileFiltersFromArguments,
381
371
  createFileMatcher,
382
372
  createFileMatcherFromArguments,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "playwright",
3
- "version": "1.56.0-alpha-2025-09-10",
3
+ "version": "1.56.0-alpha-2025-09-11",
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-10"
67
+ "playwright-core": "1.56.0-alpha-2025-09-11"
68
68
  },
69
69
  "optionalDependencies": {
70
70
  "fsevents": "2.3.2"
@@ -1,30 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var browserTool_exports = {};
20
- __export(browserTool_exports, {
21
- defineBrowserTool: () => defineBrowserTool
22
- });
23
- module.exports = __toCommonJS(browserTool_exports);
24
- function defineBrowserTool(tool) {
25
- return tool;
26
- }
27
- // Annotate the CommonJS export names for ESM import in node:
28
- 0 && (module.exports = {
29
- defineBrowserTool
30
- });
@@ -1,120 +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 browserTools_exports = {};
30
- __export(browserTools_exports, {
31
- elementSchema: () => elementSchema,
32
- evaluate: () => evaluate,
33
- pickLocator: () => pickLocator,
34
- snapshot: () => snapshot
35
- });
36
- module.exports = __toCommonJS(browserTools_exports);
37
- var import_utils = require("playwright-core/lib/utils");
38
- var import_browserTool = require("./browserTool.js");
39
- var mcpBundle = __toESM(require("../sdk/bundle"));
40
- const { z } = mcpBundle;
41
- const snapshot = (0, import_browserTool.defineBrowserTool)({
42
- schema: {
43
- name: "playwright_test_browser_snapshot",
44
- title: "Capture page snapshot",
45
- description: "Capture page snapshot for debugging",
46
- inputSchema: z.object({}),
47
- type: "readOnly"
48
- },
49
- handle: async (page, params) => {
50
- const snapshot2 = await page._snapshotForAI();
51
- return {
52
- content: [
53
- {
54
- type: "text",
55
- text: snapshot2
56
- }
57
- ]
58
- };
59
- }
60
- });
61
- const elementSchema = z.object({
62
- element: z.string().describe("Human-readable element description used to obtain permission to interact with the element"),
63
- ref: z.string().describe("Exact target element reference from the page snapshot")
64
- });
65
- const pickLocator = (0, import_browserTool.defineBrowserTool)({
66
- schema: {
67
- name: "playwright_test_generate_locator",
68
- title: "Create locator for element",
69
- description: "Generate locator for the given element to use in tests",
70
- inputSchema: elementSchema,
71
- type: "readOnly"
72
- },
73
- handle: async (page, params) => {
74
- const locator = await refLocator(page, params);
75
- try {
76
- const { resolvedSelector } = await locator._resolveSelector();
77
- const locatorString = (0, import_utils.asLocator)("javascript", resolvedSelector);
78
- return { content: [{ type: "text", text: locatorString }] };
79
- } catch (e) {
80
- throw new Error(`Ref not found, likely because element was removed. Use ${snapshot.schema.name} to see what elements are currently on the page.`);
81
- }
82
- }
83
- });
84
- const evaluateSchema = z.object({
85
- function: z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
86
- element: z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
87
- ref: z.string().optional().describe("Exact target element reference from the page snapshot")
88
- });
89
- const evaluate = (0, import_browserTool.defineBrowserTool)({
90
- schema: {
91
- name: "playwright_test_evaluate_on_pause",
92
- title: "Evaluate in page",
93
- description: "Evaluate JavaScript expression on page or element",
94
- inputSchema: evaluateSchema,
95
- type: "destructive"
96
- },
97
- handle: async (page, params) => {
98
- let locator;
99
- if (params.ref && params.element)
100
- locator = await refLocator(page, { ref: params.ref, element: params.element });
101
- const receiver = locator ?? page;
102
- const result = await receiver._evaluateFunction(params.function);
103
- return {
104
- content: [{ type: "text", text: JSON.stringify(result, null, 2) || "undefined" }]
105
- };
106
- }
107
- });
108
- async function refLocator(page, elementRef) {
109
- const snapshot2 = await page._snapshotForAI();
110
- if (!snapshot2.includes(`[ref=${elementRef.ref}]`))
111
- throw new Error(`Ref ${elementRef.ref} not found in the current page snapshot. Try capturing new snapshot.`);
112
- return page.locator(`aria-ref=${elementRef.ref}`).describe(elementRef.element);
113
- }
114
- // Annotate the CommonJS export names for ESM import in node:
115
- 0 && (module.exports = {
116
- elementSchema,
117
- evaluate,
118
- pickLocator,
119
- snapshot
120
- });