@playwright/mcp 0.0.30 → 0.0.31
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 +160 -321
- package/config.d.ts +3 -17
- package/lib/browserContextFactory.js +3 -35
- package/lib/config.js +62 -6
- package/lib/connection.js +2 -3
- package/lib/context.js +39 -29
- package/lib/log.js +21 -0
- package/lib/pageSnapshot.js +1 -1
- package/lib/program.js +10 -9
- package/lib/tab.js +37 -3
- package/lib/tools/common.js +4 -4
- package/lib/tools/console.js +1 -1
- package/lib/tools/dialogs.js +4 -4
- package/lib/tools/evaluate.js +62 -0
- package/lib/tools/files.js +5 -5
- package/lib/tools/install.js +1 -1
- package/lib/tools/keyboard.js +50 -4
- package/lib/tools/{vision.js → mouse.js} +14 -81
- package/lib/tools/navigate.js +12 -12
- package/lib/tools/screenshot.js +1 -1
- package/lib/tools/snapshot.js +7 -47
- package/lib/tools/tabs.js +14 -14
- package/lib/tools/utils.js +5 -4
- package/lib/tools/wait.js +6 -6
- package/lib/tools.js +12 -26
- package/package.json +4 -3
- package/lib/browserServer.js +0 -151
- package/lib/tools/testing.js +0 -60
package/lib/tools/files.js
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { defineTool } from './tool.js';
|
|
18
|
-
const uploadFile =
|
|
19
|
-
capability: '
|
|
18
|
+
const uploadFile = defineTool({
|
|
19
|
+
capability: 'core',
|
|
20
20
|
schema: {
|
|
21
21
|
name: 'browser_file_upload',
|
|
22
22
|
title: 'Upload files',
|
|
@@ -40,12 +40,12 @@ const uploadFile = captureSnapshot => defineTool({
|
|
|
40
40
|
return {
|
|
41
41
|
code,
|
|
42
42
|
action,
|
|
43
|
-
captureSnapshot,
|
|
43
|
+
captureSnapshot: true,
|
|
44
44
|
waitForNetwork: true,
|
|
45
45
|
};
|
|
46
46
|
},
|
|
47
47
|
clearsModalState: 'fileChooser',
|
|
48
48
|
});
|
|
49
|
-
export default
|
|
50
|
-
uploadFile
|
|
49
|
+
export default [
|
|
50
|
+
uploadFile,
|
|
51
51
|
];
|
package/lib/tools/install.js
CHANGED
|
@@ -19,7 +19,7 @@ import { z } from 'zod';
|
|
|
19
19
|
import { defineTool } from './tool.js';
|
|
20
20
|
import { fileURLToPath } from 'node:url';
|
|
21
21
|
const install = defineTool({
|
|
22
|
-
capability: 'install',
|
|
22
|
+
capability: 'core-install',
|
|
23
23
|
schema: {
|
|
24
24
|
name: 'browser_install',
|
|
25
25
|
title: 'Install the browser specified in the config',
|
package/lib/tools/keyboard.js
CHANGED
|
@@ -15,7 +15,10 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { defineTool } from './tool.js';
|
|
18
|
-
|
|
18
|
+
import { elementSchema } from './snapshot.js';
|
|
19
|
+
import { generateLocator } from './utils.js';
|
|
20
|
+
import * as javascript from '../javascript.js';
|
|
21
|
+
const pressKey = defineTool({
|
|
19
22
|
capability: 'core',
|
|
20
23
|
schema: {
|
|
21
24
|
name: 'browser_press_key',
|
|
@@ -36,11 +39,54 @@ const pressKey = captureSnapshot => defineTool({
|
|
|
36
39
|
return {
|
|
37
40
|
code,
|
|
38
41
|
action,
|
|
39
|
-
captureSnapshot,
|
|
42
|
+
captureSnapshot: true,
|
|
40
43
|
waitForNetwork: true
|
|
41
44
|
};
|
|
42
45
|
},
|
|
43
46
|
});
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
const typeSchema = elementSchema.extend({
|
|
48
|
+
text: z.string().describe('Text to type into the element'),
|
|
49
|
+
submit: z.boolean().optional().describe('Whether to submit entered text (press Enter after)'),
|
|
50
|
+
slowly: z.boolean().optional().describe('Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.'),
|
|
51
|
+
});
|
|
52
|
+
const type = defineTool({
|
|
53
|
+
capability: 'core',
|
|
54
|
+
schema: {
|
|
55
|
+
name: 'browser_type',
|
|
56
|
+
title: 'Type text',
|
|
57
|
+
description: 'Type text into editable element',
|
|
58
|
+
inputSchema: typeSchema,
|
|
59
|
+
type: 'destructive',
|
|
60
|
+
},
|
|
61
|
+
handle: async (context, params) => {
|
|
62
|
+
const snapshot = context.currentTabOrDie().snapshotOrDie();
|
|
63
|
+
const locator = snapshot.refLocator(params);
|
|
64
|
+
const code = [];
|
|
65
|
+
const steps = [];
|
|
66
|
+
if (params.slowly) {
|
|
67
|
+
code.push(`// Press "${params.text}" sequentially into "${params.element}"`);
|
|
68
|
+
code.push(`await page.${await generateLocator(locator)}.pressSequentially(${javascript.quote(params.text)});`);
|
|
69
|
+
steps.push(() => locator.pressSequentially(params.text));
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
code.push(`// Fill "${params.text}" into "${params.element}"`);
|
|
73
|
+
code.push(`await page.${await generateLocator(locator)}.fill(${javascript.quote(params.text)});`);
|
|
74
|
+
steps.push(() => locator.fill(params.text));
|
|
75
|
+
}
|
|
76
|
+
if (params.submit) {
|
|
77
|
+
code.push(`// Submit text`);
|
|
78
|
+
code.push(`await page.${await generateLocator(locator)}.press('Enter');`);
|
|
79
|
+
steps.push(() => locator.press('Enter'));
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
code,
|
|
83
|
+
action: () => steps.reduce((acc, step) => acc.then(step), Promise.resolve()),
|
|
84
|
+
captureSnapshot: true,
|
|
85
|
+
waitForNetwork: true,
|
|
86
|
+
};
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
export default [
|
|
90
|
+
pressKey,
|
|
91
|
+
type,
|
|
46
92
|
];
|
|
@@ -15,43 +15,13 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { defineTool } from './tool.js';
|
|
18
|
-
import * as javascript from '../javascript.js';
|
|
19
18
|
const elementSchema = z.object({
|
|
20
19
|
element: z.string().describe('Human-readable element description used to obtain permission to interact with the element'),
|
|
21
20
|
});
|
|
22
|
-
const
|
|
23
|
-
capability: '
|
|
21
|
+
const mouseMove = defineTool({
|
|
22
|
+
capability: 'vision',
|
|
24
23
|
schema: {
|
|
25
|
-
name: '
|
|
26
|
-
title: 'Take a screenshot',
|
|
27
|
-
description: 'Take a screenshot of the current page',
|
|
28
|
-
inputSchema: z.object({}),
|
|
29
|
-
type: 'readOnly',
|
|
30
|
-
},
|
|
31
|
-
handle: async (context) => {
|
|
32
|
-
const tab = await context.ensureTab();
|
|
33
|
-
const options = { type: 'jpeg', quality: 50, scale: 'css' };
|
|
34
|
-
const code = [
|
|
35
|
-
`// Take a screenshot of the current page`,
|
|
36
|
-
`await page.screenshot(${javascript.formatObject(options)});`,
|
|
37
|
-
];
|
|
38
|
-
const action = () => tab.page.screenshot(options).then(buffer => {
|
|
39
|
-
return {
|
|
40
|
-
content: [{ type: 'image', data: buffer.toString('base64'), mimeType: 'image/jpeg' }],
|
|
41
|
-
};
|
|
42
|
-
});
|
|
43
|
-
return {
|
|
44
|
-
code,
|
|
45
|
-
action,
|
|
46
|
-
captureSnapshot: false,
|
|
47
|
-
waitForNetwork: false
|
|
48
|
-
};
|
|
49
|
-
},
|
|
50
|
-
});
|
|
51
|
-
const moveMouse = defineTool({
|
|
52
|
-
capability: 'core',
|
|
53
|
-
schema: {
|
|
54
|
-
name: 'browser_screen_move_mouse',
|
|
24
|
+
name: 'browser_mouse_move_xy',
|
|
55
25
|
title: 'Move mouse',
|
|
56
26
|
description: 'Move mouse to a given position',
|
|
57
27
|
inputSchema: elementSchema.extend({
|
|
@@ -75,12 +45,12 @@ const moveMouse = defineTool({
|
|
|
75
45
|
};
|
|
76
46
|
},
|
|
77
47
|
});
|
|
78
|
-
const
|
|
79
|
-
capability: '
|
|
48
|
+
const mouseClick = defineTool({
|
|
49
|
+
capability: 'vision',
|
|
80
50
|
schema: {
|
|
81
|
-
name: '
|
|
51
|
+
name: 'browser_mouse_click_xy',
|
|
82
52
|
title: 'Click',
|
|
83
|
-
description: 'Click left mouse button',
|
|
53
|
+
description: 'Click left mouse button at a given position',
|
|
84
54
|
inputSchema: elementSchema.extend({
|
|
85
55
|
x: z.number().describe('X coordinate'),
|
|
86
56
|
y: z.number().describe('Y coordinate'),
|
|
@@ -108,12 +78,12 @@ const click = defineTool({
|
|
|
108
78
|
};
|
|
109
79
|
},
|
|
110
80
|
});
|
|
111
|
-
const
|
|
112
|
-
capability: '
|
|
81
|
+
const mouseDrag = defineTool({
|
|
82
|
+
capability: 'vision',
|
|
113
83
|
schema: {
|
|
114
|
-
name: '
|
|
84
|
+
name: 'browser_mouse_drag_xy',
|
|
115
85
|
title: 'Drag mouse',
|
|
116
|
-
description: 'Drag left mouse button',
|
|
86
|
+
description: 'Drag left mouse button to a given position',
|
|
117
87
|
inputSchema: elementSchema.extend({
|
|
118
88
|
startX: z.number().describe('Start X coordinate'),
|
|
119
89
|
startY: z.number().describe('Start Y coordinate'),
|
|
@@ -145,45 +115,8 @@ const drag = defineTool({
|
|
|
145
115
|
};
|
|
146
116
|
},
|
|
147
117
|
});
|
|
148
|
-
const type = defineTool({
|
|
149
|
-
capability: 'core',
|
|
150
|
-
schema: {
|
|
151
|
-
name: 'browser_screen_type',
|
|
152
|
-
title: 'Type text',
|
|
153
|
-
description: 'Type text',
|
|
154
|
-
inputSchema: z.object({
|
|
155
|
-
text: z.string().describe('Text to type into the element'),
|
|
156
|
-
submit: z.boolean().optional().describe('Whether to submit entered text (press Enter after)'),
|
|
157
|
-
}),
|
|
158
|
-
type: 'destructive',
|
|
159
|
-
},
|
|
160
|
-
handle: async (context, params) => {
|
|
161
|
-
const tab = context.currentTabOrDie();
|
|
162
|
-
const code = [
|
|
163
|
-
`// Type ${params.text}`,
|
|
164
|
-
`await page.keyboard.type('${params.text}');`,
|
|
165
|
-
];
|
|
166
|
-
const action = async () => {
|
|
167
|
-
await tab.page.keyboard.type(params.text);
|
|
168
|
-
if (params.submit)
|
|
169
|
-
await tab.page.keyboard.press('Enter');
|
|
170
|
-
};
|
|
171
|
-
if (params.submit) {
|
|
172
|
-
code.push(`// Submit text`);
|
|
173
|
-
code.push(`await page.keyboard.press('Enter');`);
|
|
174
|
-
}
|
|
175
|
-
return {
|
|
176
|
-
code,
|
|
177
|
-
action,
|
|
178
|
-
captureSnapshot: false,
|
|
179
|
-
waitForNetwork: true,
|
|
180
|
-
};
|
|
181
|
-
},
|
|
182
|
-
});
|
|
183
118
|
export default [
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
drag,
|
|
188
|
-
type,
|
|
119
|
+
mouseMove,
|
|
120
|
+
mouseClick,
|
|
121
|
+
mouseDrag,
|
|
189
122
|
];
|
package/lib/tools/navigate.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { defineTool } from './tool.js';
|
|
18
|
-
const navigate =
|
|
18
|
+
const navigate = defineTool({
|
|
19
19
|
capability: 'core',
|
|
20
20
|
schema: {
|
|
21
21
|
name: 'browser_navigate',
|
|
@@ -35,13 +35,13 @@ const navigate = captureSnapshot => defineTool({
|
|
|
35
35
|
];
|
|
36
36
|
return {
|
|
37
37
|
code,
|
|
38
|
-
captureSnapshot,
|
|
38
|
+
captureSnapshot: true,
|
|
39
39
|
waitForNetwork: false,
|
|
40
40
|
};
|
|
41
41
|
},
|
|
42
42
|
});
|
|
43
|
-
const goBack =
|
|
44
|
-
capability: '
|
|
43
|
+
const goBack = defineTool({
|
|
44
|
+
capability: 'core',
|
|
45
45
|
schema: {
|
|
46
46
|
name: 'browser_navigate_back',
|
|
47
47
|
title: 'Go back',
|
|
@@ -58,13 +58,13 @@ const goBack = captureSnapshot => defineTool({
|
|
|
58
58
|
];
|
|
59
59
|
return {
|
|
60
60
|
code,
|
|
61
|
-
captureSnapshot,
|
|
61
|
+
captureSnapshot: true,
|
|
62
62
|
waitForNetwork: false,
|
|
63
63
|
};
|
|
64
64
|
},
|
|
65
65
|
});
|
|
66
|
-
const goForward =
|
|
67
|
-
capability: '
|
|
66
|
+
const goForward = defineTool({
|
|
67
|
+
capability: 'core',
|
|
68
68
|
schema: {
|
|
69
69
|
name: 'browser_navigate_forward',
|
|
70
70
|
title: 'Go forward',
|
|
@@ -81,13 +81,13 @@ const goForward = captureSnapshot => defineTool({
|
|
|
81
81
|
];
|
|
82
82
|
return {
|
|
83
83
|
code,
|
|
84
|
-
captureSnapshot,
|
|
84
|
+
captureSnapshot: true,
|
|
85
85
|
waitForNetwork: false,
|
|
86
86
|
};
|
|
87
87
|
},
|
|
88
88
|
});
|
|
89
|
-
export default
|
|
90
|
-
navigate
|
|
91
|
-
goBack
|
|
92
|
-
goForward
|
|
89
|
+
export default [
|
|
90
|
+
navigate,
|
|
91
|
+
goBack,
|
|
92
|
+
goForward,
|
|
93
93
|
];
|
package/lib/tools/screenshot.js
CHANGED
package/lib/tools/snapshot.js
CHANGED
|
@@ -35,12 +35,13 @@ const snapshot = defineTool({
|
|
|
35
35
|
};
|
|
36
36
|
},
|
|
37
37
|
});
|
|
38
|
-
const elementSchema = z.object({
|
|
38
|
+
export const elementSchema = z.object({
|
|
39
39
|
element: z.string().describe('Human-readable element description used to obtain permission to interact with the element'),
|
|
40
40
|
ref: z.string().describe('Exact target element reference from the page snapshot'),
|
|
41
41
|
});
|
|
42
42
|
const clickSchema = elementSchema.extend({
|
|
43
43
|
doubleClick: z.boolean().optional().describe('Whether to perform a double click instead of a single click'),
|
|
44
|
+
button: z.enum(['left', 'right', 'middle']).optional().describe('Button to click, defaults to left'),
|
|
44
45
|
});
|
|
45
46
|
const click = defineTool({
|
|
46
47
|
capability: 'core',
|
|
@@ -54,18 +55,20 @@ const click = defineTool({
|
|
|
54
55
|
handle: async (context, params) => {
|
|
55
56
|
const tab = context.currentTabOrDie();
|
|
56
57
|
const locator = tab.snapshotOrDie().refLocator(params);
|
|
58
|
+
const button = params.button;
|
|
59
|
+
const buttonAttr = button ? `{ button: '${button}' }` : '';
|
|
57
60
|
const code = [];
|
|
58
61
|
if (params.doubleClick) {
|
|
59
62
|
code.push(`// Double click ${params.element}`);
|
|
60
|
-
code.push(`await page.${await generateLocator(locator)}.dblclick();`);
|
|
63
|
+
code.push(`await page.${await generateLocator(locator)}.dblclick(${buttonAttr});`);
|
|
61
64
|
}
|
|
62
65
|
else {
|
|
63
66
|
code.push(`// Click ${params.element}`);
|
|
64
|
-
code.push(`await page.${await generateLocator(locator)}.click();`);
|
|
67
|
+
code.push(`await page.${await generateLocator(locator)}.click(${buttonAttr});`);
|
|
65
68
|
}
|
|
66
69
|
return {
|
|
67
70
|
code,
|
|
68
|
-
action: () => params.doubleClick ? locator.dblclick() : locator.click(),
|
|
71
|
+
action: () => params.doubleClick ? locator.dblclick({ button }) : locator.click({ button }),
|
|
69
72
|
captureSnapshot: true,
|
|
70
73
|
waitForNetwork: true,
|
|
71
74
|
};
|
|
@@ -125,48 +128,6 @@ const hover = defineTool({
|
|
|
125
128
|
};
|
|
126
129
|
},
|
|
127
130
|
});
|
|
128
|
-
const typeSchema = elementSchema.extend({
|
|
129
|
-
text: z.string().describe('Text to type into the element'),
|
|
130
|
-
submit: z.boolean().optional().describe('Whether to submit entered text (press Enter after)'),
|
|
131
|
-
slowly: z.boolean().optional().describe('Whether to type one character at a time. Useful for triggering key handlers in the page. By default entire text is filled in at once.'),
|
|
132
|
-
});
|
|
133
|
-
const type = defineTool({
|
|
134
|
-
capability: 'core',
|
|
135
|
-
schema: {
|
|
136
|
-
name: 'browser_type',
|
|
137
|
-
title: 'Type text',
|
|
138
|
-
description: 'Type text into editable element',
|
|
139
|
-
inputSchema: typeSchema,
|
|
140
|
-
type: 'destructive',
|
|
141
|
-
},
|
|
142
|
-
handle: async (context, params) => {
|
|
143
|
-
const snapshot = context.currentTabOrDie().snapshotOrDie();
|
|
144
|
-
const locator = snapshot.refLocator(params);
|
|
145
|
-
const code = [];
|
|
146
|
-
const steps = [];
|
|
147
|
-
if (params.slowly) {
|
|
148
|
-
code.push(`// Press "${params.text}" sequentially into "${params.element}"`);
|
|
149
|
-
code.push(`await page.${await generateLocator(locator)}.pressSequentially(${javascript.quote(params.text)});`);
|
|
150
|
-
steps.push(() => locator.pressSequentially(params.text));
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
code.push(`// Fill "${params.text}" into "${params.element}"`);
|
|
154
|
-
code.push(`await page.${await generateLocator(locator)}.fill(${javascript.quote(params.text)});`);
|
|
155
|
-
steps.push(() => locator.fill(params.text));
|
|
156
|
-
}
|
|
157
|
-
if (params.submit) {
|
|
158
|
-
code.push(`// Submit text`);
|
|
159
|
-
code.push(`await page.${await generateLocator(locator)}.press('Enter');`);
|
|
160
|
-
steps.push(() => locator.press('Enter'));
|
|
161
|
-
}
|
|
162
|
-
return {
|
|
163
|
-
code,
|
|
164
|
-
action: () => steps.reduce((acc, step) => acc.then(step), Promise.resolve()),
|
|
165
|
-
captureSnapshot: true,
|
|
166
|
-
waitForNetwork: true,
|
|
167
|
-
};
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
131
|
const selectOptionSchema = elementSchema.extend({
|
|
171
132
|
values: z.array(z.string()).describe('Array of values to select in the dropdown. This can be a single value or multiple values.'),
|
|
172
133
|
});
|
|
@@ -199,6 +160,5 @@ export default [
|
|
|
199
160
|
click,
|
|
200
161
|
drag,
|
|
201
162
|
hover,
|
|
202
|
-
type,
|
|
203
163
|
selectOption,
|
|
204
164
|
];
|
package/lib/tools/tabs.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { defineTool } from './tool.js';
|
|
18
18
|
const listTabs = defineTool({
|
|
19
|
-
capability: 'tabs',
|
|
19
|
+
capability: 'core-tabs',
|
|
20
20
|
schema: {
|
|
21
21
|
name: 'browser_tab_list',
|
|
22
22
|
title: 'List tabs',
|
|
@@ -39,8 +39,8 @@ const listTabs = defineTool({
|
|
|
39
39
|
};
|
|
40
40
|
},
|
|
41
41
|
});
|
|
42
|
-
const selectTab =
|
|
43
|
-
capability: 'tabs',
|
|
42
|
+
const selectTab = defineTool({
|
|
43
|
+
capability: 'core-tabs',
|
|
44
44
|
schema: {
|
|
45
45
|
name: 'browser_tab_select',
|
|
46
46
|
title: 'Select a tab',
|
|
@@ -57,13 +57,13 @@ const selectTab = captureSnapshot => defineTool({
|
|
|
57
57
|
];
|
|
58
58
|
return {
|
|
59
59
|
code,
|
|
60
|
-
captureSnapshot,
|
|
60
|
+
captureSnapshot: true,
|
|
61
61
|
waitForNetwork: false
|
|
62
62
|
};
|
|
63
63
|
},
|
|
64
64
|
});
|
|
65
|
-
const newTab =
|
|
66
|
-
capability: 'tabs',
|
|
65
|
+
const newTab = defineTool({
|
|
66
|
+
capability: 'core-tabs',
|
|
67
67
|
schema: {
|
|
68
68
|
name: 'browser_tab_new',
|
|
69
69
|
title: 'Open a new tab',
|
|
@@ -82,13 +82,13 @@ const newTab = captureSnapshot => defineTool({
|
|
|
82
82
|
];
|
|
83
83
|
return {
|
|
84
84
|
code,
|
|
85
|
-
captureSnapshot,
|
|
85
|
+
captureSnapshot: true,
|
|
86
86
|
waitForNetwork: false
|
|
87
87
|
};
|
|
88
88
|
},
|
|
89
89
|
});
|
|
90
|
-
const closeTab =
|
|
91
|
-
capability: 'tabs',
|
|
90
|
+
const closeTab = defineTool({
|
|
91
|
+
capability: 'core-tabs',
|
|
92
92
|
schema: {
|
|
93
93
|
name: 'browser_tab_close',
|
|
94
94
|
title: 'Close a tab',
|
|
@@ -105,14 +105,14 @@ const closeTab = captureSnapshot => defineTool({
|
|
|
105
105
|
];
|
|
106
106
|
return {
|
|
107
107
|
code,
|
|
108
|
-
captureSnapshot,
|
|
108
|
+
captureSnapshot: true,
|
|
109
109
|
waitForNetwork: false
|
|
110
110
|
};
|
|
111
111
|
},
|
|
112
112
|
});
|
|
113
|
-
export default
|
|
113
|
+
export default [
|
|
114
114
|
listTabs,
|
|
115
|
-
newTab
|
|
116
|
-
selectTab
|
|
117
|
-
closeTab
|
|
115
|
+
newTab,
|
|
116
|
+
selectTab,
|
|
117
|
+
closeTab,
|
|
118
118
|
];
|
package/lib/tools/utils.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
// @ts-ignore
|
|
17
|
+
import { asLocator } from 'playwright-core/lib/utils';
|
|
16
18
|
export async function waitForCompletion(context, tab, callback) {
|
|
17
19
|
const requests = new Set();
|
|
18
20
|
let frameNavigated = false;
|
|
@@ -67,12 +69,11 @@ export function sanitizeForFilePath(s) {
|
|
|
67
69
|
}
|
|
68
70
|
export async function generateLocator(locator) {
|
|
69
71
|
try {
|
|
70
|
-
|
|
72
|
+
const { resolvedSelector } = await locator._resolveSelector();
|
|
73
|
+
return asLocator('javascript', resolvedSelector);
|
|
71
74
|
}
|
|
72
75
|
catch (e) {
|
|
73
|
-
|
|
74
|
-
throw new Error('Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.');
|
|
75
|
-
throw e;
|
|
76
|
+
throw new Error('Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.');
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
export async function callOnPageNoTrace(page, callback) {
|
package/lib/tools/wait.js
CHANGED
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { z } from 'zod';
|
|
17
17
|
import { defineTool } from './tool.js';
|
|
18
|
-
const wait =
|
|
19
|
-
capability: '
|
|
18
|
+
const wait = defineTool({
|
|
19
|
+
capability: 'core',
|
|
20
20
|
schema: {
|
|
21
21
|
name: 'browser_wait_for',
|
|
22
22
|
title: 'Wait for',
|
|
@@ -34,7 +34,7 @@ const wait = captureSnapshot => defineTool({
|
|
|
34
34
|
const code = [];
|
|
35
35
|
if (params.time) {
|
|
36
36
|
code.push(`await new Promise(f => setTimeout(f, ${params.time} * 1000));`);
|
|
37
|
-
await new Promise(f => setTimeout(f, Math.min(
|
|
37
|
+
await new Promise(f => setTimeout(f, Math.min(30000, params.time * 1000)));
|
|
38
38
|
}
|
|
39
39
|
const tab = context.currentTabOrDie();
|
|
40
40
|
const locator = params.text ? tab.page.getByText(params.text).first() : undefined;
|
|
@@ -49,11 +49,11 @@ const wait = captureSnapshot => defineTool({
|
|
|
49
49
|
}
|
|
50
50
|
return {
|
|
51
51
|
code,
|
|
52
|
-
captureSnapshot,
|
|
52
|
+
captureSnapshot: true,
|
|
53
53
|
waitForNetwork: false,
|
|
54
54
|
};
|
|
55
55
|
},
|
|
56
56
|
});
|
|
57
|
-
export default
|
|
58
|
-
wait
|
|
57
|
+
export default [
|
|
58
|
+
wait,
|
|
59
59
|
];
|
package/lib/tools.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
import common from './tools/common.js';
|
|
17
17
|
import console from './tools/console.js';
|
|
18
18
|
import dialogs from './tools/dialogs.js';
|
|
19
|
+
import evaluate from './tools/evaluate.js';
|
|
19
20
|
import files from './tools/files.js';
|
|
20
21
|
import install from './tools/install.js';
|
|
21
22
|
import keyboard from './tools/keyboard.js';
|
|
@@ -25,37 +26,22 @@ import pdf from './tools/pdf.js';
|
|
|
25
26
|
import snapshot from './tools/snapshot.js';
|
|
26
27
|
import tabs from './tools/tabs.js';
|
|
27
28
|
import screenshot from './tools/screenshot.js';
|
|
28
|
-
import testing from './tools/testing.js';
|
|
29
|
-
import vision from './tools/vision.js';
|
|
30
29
|
import wait from './tools/wait.js';
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
import mouse from './tools/mouse.js';
|
|
31
|
+
export const allTools = [
|
|
32
|
+
...common,
|
|
33
33
|
...console,
|
|
34
|
-
...dialogs
|
|
35
|
-
...
|
|
34
|
+
...dialogs,
|
|
35
|
+
...evaluate,
|
|
36
|
+
...files,
|
|
36
37
|
...install,
|
|
37
|
-
...keyboard
|
|
38
|
-
...navigate
|
|
38
|
+
...keyboard,
|
|
39
|
+
...navigate,
|
|
39
40
|
...network,
|
|
41
|
+
...mouse,
|
|
40
42
|
...pdf,
|
|
41
43
|
...screenshot,
|
|
42
44
|
...snapshot,
|
|
43
|
-
...tabs
|
|
44
|
-
...
|
|
45
|
-
...wait(true),
|
|
46
|
-
];
|
|
47
|
-
export const visionTools = [
|
|
48
|
-
...common(false),
|
|
49
|
-
...console,
|
|
50
|
-
...dialogs(false),
|
|
51
|
-
...files(false),
|
|
52
|
-
...install,
|
|
53
|
-
...keyboard(false),
|
|
54
|
-
...navigate(false),
|
|
55
|
-
...network,
|
|
56
|
-
...pdf,
|
|
57
|
-
...tabs(false),
|
|
58
|
-
...testing,
|
|
59
|
-
...vision,
|
|
60
|
-
...wait(false),
|
|
45
|
+
...tabs,
|
|
46
|
+
...wait,
|
|
61
47
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@playwright/mcp",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"description": "Playwright Tools for MCP",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -40,14 +40,15 @@
|
|
|
40
40
|
"commander": "^13.1.0",
|
|
41
41
|
"debug": "^4.4.1",
|
|
42
42
|
"mime": "^4.0.7",
|
|
43
|
-
"playwright": "1.
|
|
43
|
+
"playwright": "1.55.0-alpha-1752701791000",
|
|
44
|
+
"playwright-core": "1.55.0-alpha-1752701791000",
|
|
44
45
|
"ws": "^8.18.1",
|
|
45
46
|
"zod-to-json-schema": "^3.24.4"
|
|
46
47
|
},
|
|
47
48
|
"devDependencies": {
|
|
48
49
|
"@eslint/eslintrc": "^3.2.0",
|
|
49
50
|
"@eslint/js": "^9.19.0",
|
|
50
|
-
"@playwright/test": "1.
|
|
51
|
+
"@playwright/test": "1.55.0-alpha-1752701791000",
|
|
51
52
|
"@stylistic/eslint-plugin": "^3.0.1",
|
|
52
53
|
"@types/chrome": "^0.0.315",
|
|
53
54
|
"@types/debug": "^4.1.12",
|