Simon Knott commited on
Commit
841bb41
·
unverified ·
1 Parent(s): 59f1d67

chore: update to 1.54.0 (#653)

Browse files

Closes https://github.com/microsoft/playwright-mcp/issues/535

package-lock.json CHANGED
@@ -13,7 +13,7 @@
13
  "commander": "^13.1.0",
14
  "debug": "^4.4.1",
15
  "mime": "^4.0.7",
16
- "playwright": "1.53.0",
17
  "ws": "^8.18.1",
18
  "zod-to-json-schema": "^3.24.4"
19
  },
@@ -23,7 +23,7 @@
23
  "devDependencies": {
24
  "@eslint/eslintrc": "^3.2.0",
25
  "@eslint/js": "^9.19.0",
26
- "@playwright/test": "1.53.0",
27
  "@stylistic/eslint-plugin": "^3.0.1",
28
  "@types/chrome": "^0.0.315",
29
  "@types/debug": "^4.1.12",
@@ -292,12 +292,13 @@
292
  }
293
  },
294
  "node_modules/@playwright/test": {
295
- "version": "1.53.0",
296
- "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.53.0.tgz",
297
- "integrity": "sha512-15hjKreZDcp7t6TL/7jkAo6Df5STZN09jGiv5dbP9A6vMVncXRqE7/B2SncsyOwrkZRBH2i6/TPOL8BVmm3c7w==",
298
  "dev": true,
 
299
  "dependencies": {
300
- "playwright": "1.53.0"
301
  },
302
  "bin": {
303
  "playwright": "cli.js"
@@ -2032,6 +2033,7 @@
2032
  "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
2033
  "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
2034
  "hasInstallScript": true,
 
2035
  "optional": true,
2036
  "os": [
2037
  "darwin"
@@ -3298,11 +3300,12 @@
3298
  }
3299
  },
3300
  "node_modules/playwright": {
3301
- "version": "1.53.0",
3302
- "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.0.tgz",
3303
- "integrity": "sha512-ghGNnIEYZC4E+YtclRn4/p6oYbdPiASELBIYkBXfaTVKreQUYbMUYQDwS12a8F0/HtIjr/CkGjtwABeFPGcS4Q==",
 
3304
  "dependencies": {
3305
- "playwright-core": "1.53.0"
3306
  },
3307
  "bin": {
3308
  "playwright": "cli.js"
@@ -3315,9 +3318,10 @@
3315
  }
3316
  },
3317
  "node_modules/playwright-core": {
3318
- "version": "1.53.0",
3319
- "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.0.tgz",
3320
- "integrity": "sha512-mGLg8m0pm4+mmtB7M89Xw/GSqoNC+twivl8ITteqvAndachozYe2ZA7srU6uleV1vEdAHYqjq+SV8SNxRRFYBw==",
 
3321
  "bin": {
3322
  "playwright-core": "cli.js"
3323
  },
 
13
  "commander": "^13.1.0",
14
  "debug": "^4.4.1",
15
  "mime": "^4.0.7",
16
+ "playwright": "1.54.0",
17
  "ws": "^8.18.1",
18
  "zod-to-json-schema": "^3.24.4"
19
  },
 
23
  "devDependencies": {
24
  "@eslint/eslintrc": "^3.2.0",
25
  "@eslint/js": "^9.19.0",
26
+ "@playwright/test": "1.54.0",
27
  "@stylistic/eslint-plugin": "^3.0.1",
28
  "@types/chrome": "^0.0.315",
29
  "@types/debug": "^4.1.12",
 
292
  }
293
  },
294
  "node_modules/@playwright/test": {
295
+ "version": "1.54.0",
296
+ "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.54.0.tgz",
297
+ "integrity": "sha512-6Mnd5daQmLivaLu5kxUg6FxPtXY4sXsS5SUwKjWNy4ISe4pKraNHoFxcsaTFiNUULbjy0Vlb5HT86QuM0Jy1pQ==",
298
  "dev": true,
299
+ "license": "Apache-2.0",
300
  "dependencies": {
301
+ "playwright": "1.54.0"
302
  },
303
  "bin": {
304
  "playwright": "cli.js"
 
2033
  "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
2034
  "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
2035
  "hasInstallScript": true,
2036
+ "license": "MIT",
2037
  "optional": true,
2038
  "os": [
2039
  "darwin"
 
3300
  }
3301
  },
3302
  "node_modules/playwright": {
3303
+ "version": "1.54.0",
3304
+ "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.54.0.tgz",
3305
+ "integrity": "sha512-y9yzHmXRwEUOpghM7XGcA38GjWuTOUMaTIcm/5rHcYVjh5MSp9qQMRRMc/+p1cx+csoPnX4wkxAF61v5VKirxg==",
3306
+ "license": "Apache-2.0",
3307
  "dependencies": {
3308
+ "playwright-core": "1.54.0"
3309
  },
3310
  "bin": {
3311
  "playwright": "cli.js"
 
3318
  }
3319
  },
3320
  "node_modules/playwright-core": {
3321
+ "version": "1.54.0",
3322
+ "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.54.0.tgz",
3323
+ "integrity": "sha512-uiWpWaJh3R3etpJ0QrpligEMl62Dk1iSAB6NUXylvmQz+e3eipXHDHvOvydDAssb5Oqo0E818qdn0L9GcJSTyA==",
3324
+ "license": "Apache-2.0",
3325
  "bin": {
3326
  "playwright-core": "cli.js"
3327
  },
package.json CHANGED
@@ -43,14 +43,14 @@
43
  "commander": "^13.1.0",
44
  "debug": "^4.4.1",
45
  "mime": "^4.0.7",
46
- "playwright": "1.53.0",
47
  "ws": "^8.18.1",
48
  "zod-to-json-schema": "^3.24.4"
49
  },
50
  "devDependencies": {
51
  "@eslint/eslintrc": "^3.2.0",
52
  "@eslint/js": "^9.19.0",
53
- "@playwright/test": "1.53.0",
54
  "@stylistic/eslint-plugin": "^3.0.1",
55
  "@types/chrome": "^0.0.315",
56
  "@types/debug": "^4.1.12",
 
43
  "commander": "^13.1.0",
44
  "debug": "^4.4.1",
45
  "mime": "^4.0.7",
46
+ "playwright": "1.54.0",
47
  "ws": "^8.18.1",
48
  "zod-to-json-schema": "^3.24.4"
49
  },
50
  "devDependencies": {
51
  "@eslint/eslintrc": "^3.2.0",
52
  "@eslint/js": "^9.19.0",
53
+ "@playwright/test": "1.54.0",
54
  "@stylistic/eslint-plugin": "^3.0.1",
55
  "@types/chrome": "^0.0.315",
56
  "@types/debug": "^4.1.12",
src/tools/utils.ts CHANGED
@@ -81,7 +81,7 @@ export async function generateLocator(locator: playwright.Locator): Promise<stri
81
  try {
82
  return await (locator as any)._generateLocatorString();
83
  } catch (e) {
84
- if (e instanceof Error && /locator._generateLocatorString: Timeout .* exceeded/.test(e.message))
85
  throw new Error('Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.');
86
  throw e;
87
  }
 
81
  try {
82
  return await (locator as any)._generateLocatorString();
83
  } catch (e) {
84
+ if (e instanceof Error && /locator._generateLocatorString: No element matching locator/.test(e.message))
85
  throw new Error('Ref not found, likely because element was removed. Use browser_snapshot to see what elements are currently on the page.');
86
  throw e;
87
  }
tests/cdp.spec.ts CHANGED
@@ -27,7 +27,7 @@ test('cdp server', async ({ cdpServer, startClient, server }) => {
27
  expect(await client.callTool({
28
  name: 'browser_navigate',
29
  arguments: { url: server.HELLO_WORLD },
30
- })).toContainTextContent(`- generic [ref=e1]: Hello, world!`);
31
  });
32
 
33
  test('cdp server reuse tab', async ({ cdpServer, startClient, server }) => {
@@ -57,7 +57,7 @@ test('cdp server reuse tab', async ({ cdpServer, startClient, server }) => {
57
  - Page Title: Title
58
  - Page Snapshot
59
  \`\`\`yaml
60
- - generic [ref=e1]: Hello, world!
61
  \`\`\`
62
  `);
63
  });
@@ -78,7 +78,7 @@ test('should throw connection error and allow re-connecting', async ({ cdpServer
78
  expect(await client.callTool({
79
  name: 'browser_navigate',
80
  arguments: { url: server.PREFIX },
81
- })).toContainTextContent(`- generic [ref=e1]: Hello, world!`);
82
  });
83
 
84
  // NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename.
 
27
  expect(await client.callTool({
28
  name: 'browser_navigate',
29
  arguments: { url: server.HELLO_WORLD },
30
+ })).toContainTextContent(`- generic [active] [ref=e1]: Hello, world!`);
31
  });
32
 
33
  test('cdp server reuse tab', async ({ cdpServer, startClient, server }) => {
 
57
  - Page Title: Title
58
  - Page Snapshot
59
  \`\`\`yaml
60
+ - generic [active] [ref=e1]: Hello, world!
61
  \`\`\`
62
  `);
63
  });
 
78
  expect(await client.callTool({
79
  name: 'browser_navigate',
80
  arguments: { url: server.PREFIX },
81
+ })).toContainTextContent(`- generic [active] [ref=e1]: Hello, world!`);
82
  });
83
 
84
  // NOTE: Can be removed when we drop Node.js 18 support and changed to import.meta.filename.
tests/core.spec.ts CHANGED
@@ -31,13 +31,13 @@ await page.goto('${server.HELLO_WORLD}');
31
  - Page Title: Title
32
  - Page Snapshot
33
  \`\`\`yaml
34
- - generic [ref=e1]: Hello, world!
35
  \`\`\`
36
  `
37
  );
38
  });
39
 
40
- test('browser_click', async ({ client, server }) => {
41
  server.setContent('/', `
42
  <title>Title</title>
43
  <button>Submit</button>
@@ -65,7 +65,7 @@ await page.getByRole('button', { name: 'Submit' }).click();
65
  - Page Title: Title
66
  - Page Snapshot
67
  \`\`\`yaml
68
- - button "Submit" [ref=e2]
69
  \`\`\`
70
  `);
71
  });
@@ -314,3 +314,22 @@ test('old locator error message', async ({ client, server }) => {
314
  },
315
  })).toContainTextContent('Ref not found');
316
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  - Page Title: Title
32
  - Page Snapshot
33
  \`\`\`yaml
34
+ - generic [active] [ref=e1]: Hello, world!
35
  \`\`\`
36
  `
37
  );
38
  });
39
 
40
+ test('browser_click', async ({ client, server, mcpBrowser }) => {
41
  server.setContent('/', `
42
  <title>Title</title>
43
  <button>Submit</button>
 
65
  - Page Title: Title
66
  - Page Snapshot
67
  \`\`\`yaml
68
+ - button "Submit" ${mcpBrowser === 'webkit' ? '' : '[active] '}[ref=e2]
69
  \`\`\`
70
  `);
71
  });
 
314
  },
315
  })).toContainTextContent('Ref not found');
316
  });
317
+
318
+ test('visibility: hidden > visible should be shown', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright-mcp/issues/535' } }, async ({ client, server }) => {
319
+ server.setContent('/', `
320
+ <div style="visibility: hidden;">
321
+ <div style="visibility: visible;">
322
+ <button>Button</button>
323
+ </div>
324
+ </div>
325
+ `, 'text/html');
326
+
327
+ await client.callTool({
328
+ name: 'browser_navigate',
329
+ arguments: { url: server.PREFIX },
330
+ });
331
+
332
+ expect(await client.callTool({
333
+ name: 'browser_snapshot'
334
+ })).toContainTextContent('- button "Button"');
335
+ });
tests/dialogs.spec.ts CHANGED
@@ -58,7 +58,7 @@ await page.getByRole('button', { name: 'Button' }).click();
58
  - Page Title:
59
  - Page Snapshot
60
  \`\`\`yaml
61
- - button "Button" [ref=e2]
62
  \`\`\`
63
  `);
64
  });
@@ -136,7 +136,7 @@ test('confirm dialog (true)', async ({ client, server }) => {
136
  expect(result).toContainTextContent('// <internal code to handle "confirm" dialog>');
137
  expect(result).toContainTextContent(`- Page Snapshot
138
  \`\`\`yaml
139
- - generic [ref=e1]: "true"
140
  \`\`\``);
141
  });
142
 
@@ -171,7 +171,7 @@ test('confirm dialog (false)', async ({ client, server }) => {
171
 
172
  expect(result).toContainTextContent(`- Page Snapshot
173
  \`\`\`yaml
174
- - generic [ref=e1]: "false"
175
  \`\`\``);
176
  });
177
 
@@ -207,6 +207,6 @@ test('prompt dialog', async ({ client, server }) => {
207
 
208
  expect(result).toContainTextContent(`- Page Snapshot
209
  \`\`\`yaml
210
- - generic [ref=e1]: Answer
211
  \`\`\``);
212
  });
 
58
  - Page Title:
59
  - Page Snapshot
60
  \`\`\`yaml
61
+ - button "Button" [active] [ref=e2]
62
  \`\`\`
63
  `);
64
  });
 
136
  expect(result).toContainTextContent('// <internal code to handle "confirm" dialog>');
137
  expect(result).toContainTextContent(`- Page Snapshot
138
  \`\`\`yaml
139
+ - generic [active] [ref=e1]: "true"
140
  \`\`\``);
141
  });
142
 
 
171
 
172
  expect(result).toContainTextContent(`- Page Snapshot
173
  \`\`\`yaml
174
+ - generic [active] [ref=e1]: "false"
175
  \`\`\``);
176
  });
177
 
 
207
 
208
  expect(result).toContainTextContent(`- Page Snapshot
209
  \`\`\`yaml
210
+ - generic [active] [ref=e1]: Answer
211
  \`\`\``);
212
  });
tests/files.spec.ts CHANGED
@@ -28,7 +28,7 @@ test('browser_file_upload', async ({ client, server }, testInfo) => {
28
  arguments: { url: server.PREFIX },
29
  })).toContainTextContent(`
30
  \`\`\`yaml
31
- - generic [ref=e1]:
32
  - button "Choose File" [ref=e2]
33
  - button "Button" [ref=e3]
34
  \`\`\``);
@@ -65,12 +65,6 @@ The tool "browser_file_upload" can only be used when there is related modal stat
65
  });
66
 
67
  expect(response).not.toContainTextContent('### Modal state');
68
- expect(response).toContainTextContent(`
69
- \`\`\`yaml
70
- - generic [ref=e1]:
71
- - button "Choose File" [ref=e2]
72
- - button "Button" [ref=e3]
73
- \`\`\``);
74
  }
75
 
76
  {
 
28
  arguments: { url: server.PREFIX },
29
  })).toContainTextContent(`
30
  \`\`\`yaml
31
+ - generic [active] [ref=e1]:
32
  - button "Choose File" [ref=e2]
33
  - button "Button" [ref=e3]
34
  \`\`\``);
 
65
  });
66
 
67
  expect(response).not.toContainTextContent('### Modal state');
 
 
 
 
 
 
68
  }
69
 
70
  {
tests/iframes.spec.ts CHANGED
@@ -24,10 +24,10 @@ test('stitched aria frames', async ({ client }) => {
24
  },
25
  })).toContainTextContent(`
26
  \`\`\`yaml
27
- - generic [ref=e1]:
28
  - heading "Hello" [level=1] [ref=e2]
29
  - iframe [ref=e3]:
30
- - generic [ref=f1e1]:
31
  - button "World" [ref=f1e2]
32
  - main [ref=f1e3]:
33
  - iframe [ref=f1e4]:
 
24
  },
25
  })).toContainTextContent(`
26
  \`\`\`yaml
27
+ - generic [active] [ref=e1]:
28
  - heading "Hello" [level=1] [ref=e2]
29
  - iframe [ref=e3]:
30
+ - generic [active] [ref=f1e1]:
31
  - button "World" [ref=f1e2]
32
  - main [ref=f1e3]:
33
  - iframe [ref=f1e4]:
tests/launch.spec.ts CHANGED
@@ -34,7 +34,7 @@ test('test reopen browser', async ({ startClient, server, mcpMode }) => {
34
  expect(await client.callTool({
35
  name: 'browser_navigate',
36
  arguments: { url: server.HELLO_WORLD },
37
- })).toContainTextContent(`- generic [ref=e1]: Hello, world!`);
38
 
39
  await client.close();
40
 
 
34
  expect(await client.callTool({
35
  name: 'browser_navigate',
36
  arguments: { url: server.HELLO_WORLD },
37
+ })).toContainTextContent(`- generic [active] [ref=e1]: Hello, world!`);
38
 
39
  await client.close();
40
 
tests/pdf.spec.ts CHANGED
@@ -40,7 +40,7 @@ test('save as pdf', async ({ startClient, mcpBrowser, server }, testInfo) => {
40
  expect(await client.callTool({
41
  name: 'browser_navigate',
42
  arguments: { url: server.HELLO_WORLD },
43
- })).toContainTextContent(`- generic [ref=e1]: Hello, world!`);
44
 
45
  const response = await client.callTool({
46
  name: 'browser_pdf_save',
@@ -58,7 +58,7 @@ test('save as pdf (filename: output.pdf)', async ({ startClient, mcpBrowser, ser
58
  expect(await client.callTool({
59
  name: 'browser_navigate',
60
  arguments: { url: server.HELLO_WORLD },
61
- })).toContainTextContent(`- generic [ref=e1]: Hello, world!`);
62
 
63
  expect(await client.callTool({
64
  name: 'browser_pdf_save',
 
40
  expect(await client.callTool({
41
  name: 'browser_navigate',
42
  arguments: { url: server.HELLO_WORLD },
43
+ })).toContainTextContent(`- generic [active] [ref=e1]: Hello, world!`);
44
 
45
  const response = await client.callTool({
46
  name: 'browser_pdf_save',
 
58
  expect(await client.callTool({
59
  name: 'browser_navigate',
60
  arguments: { url: server.HELLO_WORLD },
61
+ })).toContainTextContent(`- generic [active] [ref=e1]: Hello, world!`);
62
 
63
  expect(await client.callTool({
64
  name: 'browser_pdf_save',
tests/tabs.spec.ts CHANGED
@@ -61,7 +61,7 @@ test('create new tab', async ({ client }) => {
61
  - Page Title: Tab one
62
  - Page Snapshot
63
  \`\`\`yaml
64
- - generic [ref=e1]: Body one
65
  \`\`\``);
66
 
67
  expect(await createTab(client, 'Tab two', 'Body two')).toHaveTextContent(`
@@ -80,7 +80,7 @@ test('create new tab', async ({ client }) => {
80
  - Page Title: Tab two
81
  - Page Snapshot
82
  \`\`\`yaml
83
- - generic [ref=e1]: Body two
84
  \`\`\``);
85
  });
86
 
@@ -108,7 +108,7 @@ test('select tab', async ({ client }) => {
108
  - Page Title: Tab one
109
  - Page Snapshot
110
  \`\`\`yaml
111
- - generic [ref=e1]: Body one
112
  \`\`\``);
113
  });
114
 
@@ -135,7 +135,7 @@ test('close tab', async ({ client }) => {
135
  - Page Title: Tab one
136
  - Page Snapshot
137
  \`\`\`yaml
138
- - generic [ref=e1]: Body one
139
  \`\`\``);
140
  });
141
 
 
61
  - Page Title: Tab one
62
  - Page Snapshot
63
  \`\`\`yaml
64
+ - generic [active] [ref=e1]: Body one
65
  \`\`\``);
66
 
67
  expect(await createTab(client, 'Tab two', 'Body two')).toHaveTextContent(`
 
80
  - Page Title: Tab two
81
  - Page Snapshot
82
  \`\`\`yaml
83
+ - generic [active] [ref=e1]: Body two
84
  \`\`\``);
85
  });
86
 
 
108
  - Page Title: Tab one
109
  - Page Snapshot
110
  \`\`\`yaml
111
+ - generic [active] [ref=e1]: Body one
112
  \`\`\``);
113
  });
114
 
 
135
  - Page Title: Tab one
136
  - Page Snapshot
137
  \`\`\`yaml
138
+ - generic [active] [ref=e1]: Body one
139
  \`\`\``);
140
  });
141