playwright 1.57.0-alpha-2025-10-09 → 1.57.0-alpha-2025-10-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.
- package/lib/mcp/browser/tab.js +8 -5
- package/lib/mcp/browser/tools/evaluate.js +2 -3
- package/lib/mcp/browser/tools/form.js +2 -3
- package/lib/mcp/browser/tools/keyboard.js +4 -5
- package/lib/mcp/browser/tools/screenshot.js +4 -4
- package/lib/mcp/browser/tools/snapshot.js +12 -13
- package/lib/mcp/browser/tools/utils.js +0 -11
- package/lib/mcp/browser/tools/verify.js +3 -4
- package/lib/reporters/html.js +0 -21
- package/package.json +2 -2
package/lib/mcp/browser/tab.js
CHANGED
|
@@ -222,12 +222,15 @@ class Tab extends import_events.EventEmitter {
|
|
|
222
222
|
return (await this.refLocators([params]))[0];
|
|
223
223
|
}
|
|
224
224
|
async refLocators(params) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
return Promise.all(params.map(async (param) => {
|
|
226
|
+
try {
|
|
227
|
+
const locator = this.page.locator(`aria-ref=${param.ref}`).describe(param.element);
|
|
228
|
+
const { resolvedSelector } = await locator._resolveSelector();
|
|
229
|
+
return { locator, resolved: (0, import_utils.asLocator)("javascript", resolvedSelector) };
|
|
230
|
+
} catch (e) {
|
|
228
231
|
throw new Error(`Ref ${param.ref} not found in the current page snapshot. Try capturing new snapshot.`);
|
|
229
|
-
|
|
230
|
-
});
|
|
232
|
+
}
|
|
233
|
+
}));
|
|
231
234
|
}
|
|
232
235
|
async waitForTimeout(time) {
|
|
233
236
|
if (this._javaScriptBlocked()) {
|
|
@@ -34,7 +34,6 @@ module.exports = __toCommonJS(evaluate_exports);
|
|
|
34
34
|
var import_bundle = require("../../sdk/bundle");
|
|
35
35
|
var import_tool = require("./tool");
|
|
36
36
|
var javascript = __toESM(require("../codegen"));
|
|
37
|
-
var import_utils = require("./utils");
|
|
38
37
|
const evaluateSchema = import_bundle.z.object({
|
|
39
38
|
function: import_bundle.z.string().describe("() => { /* code */ } or (element) => { /* code */ } when element is provided"),
|
|
40
39
|
element: import_bundle.z.string().optional().describe("Human-readable element description used to obtain permission to interact with the element"),
|
|
@@ -54,12 +53,12 @@ const evaluate = (0, import_tool.defineTabTool)({
|
|
|
54
53
|
let locator;
|
|
55
54
|
if (params.ref && params.element) {
|
|
56
55
|
locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
|
57
|
-
response.addCode(`await page.${
|
|
56
|
+
response.addCode(`await page.${locator.resolved}.evaluate(${javascript.quote(params.function)});`);
|
|
58
57
|
} else {
|
|
59
58
|
response.addCode(`await page.evaluate(${javascript.quote(params.function)});`);
|
|
60
59
|
}
|
|
61
60
|
await tab.waitForCompletion(async () => {
|
|
62
|
-
const receiver = locator ?? tab.page;
|
|
61
|
+
const receiver = locator?.locator ?? tab.page;
|
|
63
62
|
const result = await receiver._evaluateFunction(params.function);
|
|
64
63
|
response.addResult(JSON.stringify(result, null, 2) || "undefined");
|
|
65
64
|
});
|
|
@@ -33,7 +33,6 @@ __export(form_exports, {
|
|
|
33
33
|
module.exports = __toCommonJS(form_exports);
|
|
34
34
|
var import_bundle = require("../../sdk/bundle");
|
|
35
35
|
var import_tool = require("./tool");
|
|
36
|
-
var import_utils = require("./utils");
|
|
37
36
|
var codegen = __toESM(require("../codegen"));
|
|
38
37
|
const fillForm = (0, import_tool.defineTabTool)({
|
|
39
38
|
capability: "core",
|
|
@@ -53,8 +52,8 @@ const fillForm = (0, import_tool.defineTabTool)({
|
|
|
53
52
|
},
|
|
54
53
|
handle: async (tab, params, response) => {
|
|
55
54
|
for (const field of params.fields) {
|
|
56
|
-
const locator = await tab.refLocator({ element: field.name, ref: field.ref });
|
|
57
|
-
const locatorSource = `await page.${
|
|
55
|
+
const { locator, resolved } = await tab.refLocator({ element: field.name, ref: field.ref });
|
|
56
|
+
const locatorSource = `await page.${resolved}`;
|
|
58
57
|
if (field.type === "textbox" || field.type === "slider") {
|
|
59
58
|
const secret = tab.context.lookupSecret(field.value);
|
|
60
59
|
await locator.fill(secret.value);
|
|
@@ -24,7 +24,6 @@ module.exports = __toCommonJS(keyboard_exports);
|
|
|
24
24
|
var import_bundle = require("../../sdk/bundle");
|
|
25
25
|
var import_tool = require("./tool");
|
|
26
26
|
var import_snapshot = require("./snapshot");
|
|
27
|
-
var import_utils = require("./utils");
|
|
28
27
|
const pressKey = (0, import_tool.defineTabTool)({
|
|
29
28
|
capability: "core",
|
|
30
29
|
schema: {
|
|
@@ -60,20 +59,20 @@ const type = (0, import_tool.defineTabTool)({
|
|
|
60
59
|
type: "input"
|
|
61
60
|
},
|
|
62
61
|
handle: async (tab, params, response) => {
|
|
63
|
-
const locator = await tab.refLocator(params);
|
|
62
|
+
const { locator, resolved } = await tab.refLocator(params);
|
|
64
63
|
const secret = tab.context.lookupSecret(params.text);
|
|
65
64
|
await tab.waitForCompletion(async () => {
|
|
66
65
|
if (params.slowly) {
|
|
67
66
|
response.setIncludeSnapshot();
|
|
68
|
-
response.addCode(`await page.${
|
|
67
|
+
response.addCode(`await page.${resolved}.pressSequentially(${secret.code});`);
|
|
69
68
|
await locator.pressSequentially(secret.value);
|
|
70
69
|
} else {
|
|
71
|
-
response.addCode(`await page.${
|
|
70
|
+
response.addCode(`await page.${resolved}.fill(${secret.code});`);
|
|
72
71
|
await locator.fill(secret.value);
|
|
73
72
|
}
|
|
74
73
|
if (params.submit) {
|
|
75
74
|
response.setIncludeSnapshot();
|
|
76
|
-
response.addCode(`await page.${
|
|
75
|
+
response.addCode(`await page.${resolved}.press('Enter');`);
|
|
77
76
|
await locator.press("Enter");
|
|
78
77
|
}
|
|
79
78
|
});
|
|
@@ -68,12 +68,12 @@ const screenshot = (0, import_tool.defineTabTool)({
|
|
|
68
68
|
const isElementScreenshot = params.element && params.ref;
|
|
69
69
|
const screenshotTarget = isElementScreenshot ? params.element : params.fullPage ? "full page" : "viewport";
|
|
70
70
|
response.addCode(`// Screenshot ${screenshotTarget} and save it as ${fileName}`);
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
response.addCode(`await page.${
|
|
71
|
+
const ref = params.ref ? await tab.refLocator({ element: params.element || "", ref: params.ref }) : null;
|
|
72
|
+
if (ref)
|
|
73
|
+
response.addCode(`await page.${ref.resolved}.screenshot(${javascript.formatObject(options)});`);
|
|
74
74
|
else
|
|
75
75
|
response.addCode(`await page.screenshot(${javascript.formatObject(options)});`);
|
|
76
|
-
const buffer =
|
|
76
|
+
const buffer = ref ? await ref.locator.screenshot(options) : await tab.page.screenshot(options);
|
|
77
77
|
response.addResult(`Took the ${screenshotTarget} screenshot and saved it as ${fileName}`);
|
|
78
78
|
if (!params.fullPage) {
|
|
79
79
|
response.addImage({
|
|
@@ -35,7 +35,6 @@ module.exports = __toCommonJS(snapshot_exports);
|
|
|
35
35
|
var import_bundle = require("../../sdk/bundle");
|
|
36
36
|
var import_tool = require("./tool");
|
|
37
37
|
var javascript = __toESM(require("../codegen"));
|
|
38
|
-
var import_utils = require("./utils");
|
|
39
38
|
const snapshot = (0, import_tool.defineTool)({
|
|
40
39
|
capability: "core",
|
|
41
40
|
schema: {
|
|
@@ -70,7 +69,7 @@ const click = (0, import_tool.defineTabTool)({
|
|
|
70
69
|
},
|
|
71
70
|
handle: async (tab, params, response) => {
|
|
72
71
|
response.setIncludeSnapshot();
|
|
73
|
-
const locator = await tab.refLocator(params);
|
|
72
|
+
const { locator, resolved } = await tab.refLocator(params);
|
|
74
73
|
const options = {
|
|
75
74
|
button: params.button,
|
|
76
75
|
modifiers: params.modifiers
|
|
@@ -78,9 +77,9 @@ const click = (0, import_tool.defineTabTool)({
|
|
|
78
77
|
const formatted = javascript.formatObject(options, " ", "oneline");
|
|
79
78
|
const optionsAttr = formatted !== "{}" ? formatted : "";
|
|
80
79
|
if (params.doubleClick)
|
|
81
|
-
response.addCode(`await page.${
|
|
80
|
+
response.addCode(`await page.${resolved}.dblclick(${optionsAttr});`);
|
|
82
81
|
else
|
|
83
|
-
response.addCode(`await page.${
|
|
82
|
+
response.addCode(`await page.${resolved}.click(${optionsAttr});`);
|
|
84
83
|
await tab.waitForCompletion(async () => {
|
|
85
84
|
if (params.doubleClick)
|
|
86
85
|
await locator.dblclick(options);
|
|
@@ -105,14 +104,14 @@ const drag = (0, import_tool.defineTabTool)({
|
|
|
105
104
|
},
|
|
106
105
|
handle: async (tab, params, response) => {
|
|
107
106
|
response.setIncludeSnapshot();
|
|
108
|
-
const [
|
|
107
|
+
const [start, end] = await tab.refLocators([
|
|
109
108
|
{ ref: params.startRef, element: params.startElement },
|
|
110
109
|
{ ref: params.endRef, element: params.endElement }
|
|
111
110
|
]);
|
|
112
111
|
await tab.waitForCompletion(async () => {
|
|
113
|
-
await
|
|
112
|
+
await start.locator.dragTo(end.locator);
|
|
114
113
|
});
|
|
115
|
-
response.addCode(`await page.${
|
|
114
|
+
response.addCode(`await page.${start.resolved}.dragTo(page.${end.resolved});`);
|
|
116
115
|
}
|
|
117
116
|
});
|
|
118
117
|
const hover = (0, import_tool.defineTabTool)({
|
|
@@ -126,8 +125,8 @@ const hover = (0, import_tool.defineTabTool)({
|
|
|
126
125
|
},
|
|
127
126
|
handle: async (tab, params, response) => {
|
|
128
127
|
response.setIncludeSnapshot();
|
|
129
|
-
const locator = await tab.refLocator(params);
|
|
130
|
-
response.addCode(`await page.${
|
|
128
|
+
const { locator, resolved } = await tab.refLocator(params);
|
|
129
|
+
response.addCode(`await page.${resolved}.hover();`);
|
|
131
130
|
await tab.waitForCompletion(async () => {
|
|
132
131
|
await locator.hover();
|
|
133
132
|
});
|
|
@@ -147,8 +146,8 @@ const selectOption = (0, import_tool.defineTabTool)({
|
|
|
147
146
|
},
|
|
148
147
|
handle: async (tab, params, response) => {
|
|
149
148
|
response.setIncludeSnapshot();
|
|
150
|
-
const locator = await tab.refLocator(params);
|
|
151
|
-
response.addCode(`await page.${
|
|
149
|
+
const { locator, resolved } = await tab.refLocator(params);
|
|
150
|
+
response.addCode(`await page.${resolved}.selectOption(${javascript.formatObject(params.values)});`);
|
|
152
151
|
await tab.waitForCompletion(async () => {
|
|
153
152
|
await locator.selectOption(params.values);
|
|
154
153
|
});
|
|
@@ -164,8 +163,8 @@ const pickLocator = (0, import_tool.defineTabTool)({
|
|
|
164
163
|
type: "readOnly"
|
|
165
164
|
},
|
|
166
165
|
handle: async (tab, params, response) => {
|
|
167
|
-
const
|
|
168
|
-
response.addResult(
|
|
166
|
+
const { resolved } = await tab.refLocator(params);
|
|
167
|
+
response.addResult(resolved);
|
|
169
168
|
}
|
|
170
169
|
});
|
|
171
170
|
var snapshot_default = [
|
|
@@ -20,11 +20,9 @@ var utils_exports = {};
|
|
|
20
20
|
__export(utils_exports, {
|
|
21
21
|
callOnPageNoTrace: () => callOnPageNoTrace,
|
|
22
22
|
dateAsFileName: () => dateAsFileName,
|
|
23
|
-
generateLocator: () => generateLocator,
|
|
24
23
|
waitForCompletion: () => waitForCompletion
|
|
25
24
|
});
|
|
26
25
|
module.exports = __toCommonJS(utils_exports);
|
|
27
|
-
var import_utils = require("playwright-core/lib/utils");
|
|
28
26
|
async function waitForCompletion(tab, callback) {
|
|
29
27
|
const requests = /* @__PURE__ */ new Set();
|
|
30
28
|
let frameNavigated = false;
|
|
@@ -76,14 +74,6 @@ async function waitForCompletion(tab, callback) {
|
|
|
76
74
|
dispose();
|
|
77
75
|
}
|
|
78
76
|
}
|
|
79
|
-
async function generateLocator(locator) {
|
|
80
|
-
try {
|
|
81
|
-
const { resolvedSelector } = await locator._resolveSelector();
|
|
82
|
-
return (0, import_utils.asLocator)("javascript", resolvedSelector);
|
|
83
|
-
} catch (e) {
|
|
84
|
-
throw new Error("Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.");
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
77
|
async function callOnPageNoTrace(page, callback) {
|
|
88
78
|
return await page._wrapApiCall(() => callback(page), { internal: true });
|
|
89
79
|
}
|
|
@@ -95,6 +85,5 @@ function dateAsFileName(extension) {
|
|
|
95
85
|
0 && (module.exports = {
|
|
96
86
|
callOnPageNoTrace,
|
|
97
87
|
dateAsFileName,
|
|
98
|
-
generateLocator,
|
|
99
88
|
waitForCompletion
|
|
100
89
|
});
|
|
@@ -34,7 +34,6 @@ module.exports = __toCommonJS(verify_exports);
|
|
|
34
34
|
var import_bundle = require("../../sdk/bundle");
|
|
35
35
|
var import_tool = require("./tool");
|
|
36
36
|
var javascript = __toESM(require("../codegen"));
|
|
37
|
-
var import_utils = require("./utils");
|
|
38
37
|
const verifyElement = (0, import_tool.defineTabTool)({
|
|
39
38
|
capability: "testing",
|
|
40
39
|
schema: {
|
|
@@ -92,7 +91,7 @@ const verifyList = (0, import_tool.defineTabTool)({
|
|
|
92
91
|
type: "assertion"
|
|
93
92
|
},
|
|
94
93
|
handle: async (tab, params, response) => {
|
|
95
|
-
const locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
|
94
|
+
const { locator } = await tab.refLocator({ ref: params.ref, element: params.element });
|
|
96
95
|
const itemTexts = [];
|
|
97
96
|
for (const item of params.items) {
|
|
98
97
|
const itemLocator = locator.getByText(item);
|
|
@@ -125,8 +124,8 @@ const verifyValue = (0, import_tool.defineTabTool)({
|
|
|
125
124
|
type: "assertion"
|
|
126
125
|
},
|
|
127
126
|
handle: async (tab, params, response) => {
|
|
128
|
-
const locator = await tab.refLocator({ ref: params.ref, element: params.element });
|
|
129
|
-
const locatorSource = `page.${
|
|
127
|
+
const { locator, resolved } = await tab.refLocator({ ref: params.ref, element: params.element });
|
|
128
|
+
const locatorSource = `page.${resolved}`;
|
|
130
129
|
if (params.type === "textbox" || params.type === "slider" || params.type === "combobox") {
|
|
131
130
|
const value = await locator.inputValue();
|
|
132
131
|
if (value !== params.value) {
|
package/lib/reporters/html.js
CHANGED
|
@@ -197,8 +197,6 @@ function startHtmlReportServer(folder) {
|
|
|
197
197
|
return false;
|
|
198
198
|
}
|
|
199
199
|
}
|
|
200
|
-
if (relativePath.endsWith("/stall.js"))
|
|
201
|
-
return true;
|
|
202
200
|
if (relativePath === "/")
|
|
203
201
|
relativePath = "/index.html";
|
|
204
202
|
const absolutePath = import_path.default.join(folder, ...relativePath.split("/"));
|
|
@@ -274,25 +272,6 @@ class HtmlBuilder {
|
|
|
274
272
|
const testFile = data.values().next().value.testFile;
|
|
275
273
|
singleTestId = testFile.tests[0].testId;
|
|
276
274
|
}
|
|
277
|
-
if (process.env.PW_HMR === "1") {
|
|
278
|
-
const redirectFile = import_path.default.join(this._reportFolder, "index.html");
|
|
279
|
-
await this._writeReportData(redirectFile);
|
|
280
|
-
async function redirect() {
|
|
281
|
-
const hmrURL = new URL("http://localhost:44224");
|
|
282
|
-
const popup = window.open(hmrURL);
|
|
283
|
-
const listener = (evt) => {
|
|
284
|
-
if (evt.source === popup && evt.data === "ready") {
|
|
285
|
-
const element = document.getElementById("playwrightReportBase64");
|
|
286
|
-
popup.postMessage(element?.textContent ?? "", hmrURL.origin);
|
|
287
|
-
window.removeEventListener("message", listener);
|
|
288
|
-
window.close();
|
|
289
|
-
}
|
|
290
|
-
};
|
|
291
|
-
window.addEventListener("message", listener);
|
|
292
|
-
}
|
|
293
|
-
import_fs.default.appendFileSync(redirectFile, `<script>(${redirect.toString()})()</script>`);
|
|
294
|
-
return { ok, singleTestId };
|
|
295
|
-
}
|
|
296
275
|
const appFolder = import_path.default.join(require.resolve("playwright-core"), "..", "lib", "vite", "htmlReport");
|
|
297
276
|
await (0, import_utils.copyFileAndMakeWritable)(import_path.default.join(appFolder, "index.html"), import_path.default.join(this._reportFolder, "index.html"));
|
|
298
277
|
if (this._hasTraces) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "playwright",
|
|
3
|
-
"version": "1.57.0-alpha-2025-10-
|
|
3
|
+
"version": "1.57.0-alpha-2025-10-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.57.0-alpha-2025-10-
|
|
67
|
+
"playwright-core": "1.57.0-alpha-2025-10-11"
|
|
68
68
|
},
|
|
69
69
|
"optionalDependencies": {
|
|
70
70
|
"fsevents": "2.3.2"
|