diff --git a/extension/tests/extension.spec.ts b/extension/tests/extension.spec.ts index 291390e..7c82e85 100644 --- a/extension/tests/extension.spec.ts +++ b/extension/tests/extension.spec.ts @@ -88,28 +88,6 @@ const test = base.extend({ } }); -async function startAndCallConnectTool(browserWithExtension: BrowserWithExtension, startClient: StartClient): Promise { - const { client } = await startClient({ - args: [`--connect-tool`], - config: { - browser: { - userDataDir: browserWithExtension.userDataDir, - } - }, - }); - - expect(await client.callTool({ - name: 'browser_connect', - arguments: { - name: 'extension' - } - })).toHaveResponse({ - result: 'Successfully changed connection method.', - }); - - return client; -} - async function startWithExtensionFlag(browserWithExtension: BrowserWithExtension, startClient: StartClient): Promise { const { client } = await startClient({ args: [`--extension`], @@ -137,144 +115,137 @@ const testWithOldExtensionVersion = test.extend({ }, }); -for (const [mode, startClientMethod] of [ - ['connect-tool', startAndCallConnectTool], - ['extension-flag', startWithExtensionFlag], -] as const) { +test(`navigate with extension`, async ({ browserWithExtension, startClient, server }) => { + const browserContext = await browserWithExtension.launch(); - test(`navigate with extension (${mode})`, async ({ browserWithExtension, startClient, server }) => { - const browserContext = await browserWithExtension.launch(); + const client = await startWithExtensionFlag(browserWithExtension, startClient); - const client = await startClientMethod(browserWithExtension, startClient); - - const confirmationPagePromise = browserContext.waitForEvent('page', page => { - return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); - }); - - const navigateResponse = client.callTool({ - name: 'browser_navigate', - arguments: { url: server.HELLO_WORLD }, - }); - - const selectorPage = await confirmationPagePromise; - // For browser_navigate command, the UI shows Allow/Reject buttons instead of tab selector - await selectorPage.getByRole('button', { name: 'Allow' }).click(); - - expect(await navigateResponse).toHaveResponse({ - pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), - }); + const confirmationPagePromise = browserContext.waitForEvent('page', page => { + return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); }); - test(`snapshot of an existing page (${mode})`, async ({ browserWithExtension, startClient, server }) => { - const browserContext = await browserWithExtension.launch(); - - const page = await browserContext.newPage(); - await page.goto(server.HELLO_WORLD); - - // Another empty page. - await browserContext.newPage(); - expect(browserContext.pages()).toHaveLength(3); - - const client = await startClientMethod(browserWithExtension, startClient); - expect(browserContext.pages()).toHaveLength(3); - - const confirmationPagePromise = browserContext.waitForEvent('page', page => { - return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); - }); - - const navigateResponse = client.callTool({ - name: 'browser_snapshot', - arguments: { }, - }); - - const selectorPage = await confirmationPagePromise; - expect(browserContext.pages()).toHaveLength(4); - - await selectorPage.locator('.tab-item', { hasText: 'Title' }).getByRole('button', { name: 'Connect' }).click(); - - expect(await navigateResponse).toHaveResponse({ - pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), - }); - - expect(browserContext.pages()).toHaveLength(4); + const navigateResponse = client.callTool({ + name: 'browser_navigate', + arguments: { url: server.HELLO_WORLD }, }); - test(`extension not installed timeout (${mode})`, async ({ browserWithExtension, startClient, server, useShortConnectionTimeout }) => { - useShortConnectionTimeout(100); + const selectorPage = await confirmationPagePromise; + // For browser_navigate command, the UI shows Allow/Reject buttons instead of tab selector + await selectorPage.getByRole('button', { name: 'Allow' }).click(); - const browserContext = await browserWithExtension.launch(); + expect(await navigateResponse).toHaveResponse({ + pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), + }); +}); - const client = await startClientMethod(browserWithExtension, startClient); +test(`snapshot of an existing page`, async ({ browserWithExtension, startClient, server }) => { + const browserContext = await browserWithExtension.launch(); - const confirmationPagePromise = browserContext.waitForEvent('page', page => { - return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); - }); + const page = await browserContext.newPage(); + await page.goto(server.HELLO_WORLD); - expect(await client.callTool({ - name: 'browser_navigate', - arguments: { url: server.HELLO_WORLD }, - })).toHaveResponse({ - result: expect.stringContaining('Extension connection timeout. Make sure the "Playwright MCP Bridge" extension is installed.'), - isError: true, - }); + // Another empty page. + await browserContext.newPage(); + expect(browserContext.pages()).toHaveLength(3); - await confirmationPagePromise; + const client = await startWithExtensionFlag(browserWithExtension, startClient); + expect(browserContext.pages()).toHaveLength(3); + + const confirmationPagePromise = browserContext.waitForEvent('page', page => { + return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); }); - testWithOldExtensionVersion(`works with old extension version (${mode})`, async ({ browserWithExtension, startClient, server, useShortConnectionTimeout }) => { - useShortConnectionTimeout(500); - - // Prelaunch the browser, so that it is properly closed after the test. - const browserContext = await browserWithExtension.launch(); - - const client = await startClientMethod(browserWithExtension, startClient); - - const confirmationPagePromise = browserContext.waitForEvent('page', page => { - return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); - }); - - const navigateResponse = client.callTool({ - name: 'browser_navigate', - arguments: { url: server.HELLO_WORLD }, - }); - - const selectorPage = await confirmationPagePromise; - // For browser_navigate command, the UI shows Allow/Reject buttons instead of tab selector - await selectorPage.getByRole('button', { name: 'Allow' }).click(); - - expect(await navigateResponse).toHaveResponse({ - pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), - }); + const navigateResponse = client.callTool({ + name: 'browser_snapshot', + arguments: { }, }); - test(`extension needs update (${mode})`, async ({ browserWithExtension, startClient, server, useShortConnectionTimeout, overrideProtocolVersion }) => { - useShortConnectionTimeout(500); - overrideProtocolVersion(1000); + const selectorPage = await confirmationPagePromise; + expect(browserContext.pages()).toHaveLength(4); - // Prelaunch the browser, so that it is properly closed after the test. - const browserContext = await browserWithExtension.launch(); + await selectorPage.locator('.tab-item', { hasText: 'Title' }).getByRole('button', { name: 'Connect' }).click(); - const client = await startClientMethod(browserWithExtension, startClient); - - const confirmationPagePromise = browserContext.waitForEvent('page', page => { - return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); - }); - - const navigateResponse = client.callTool({ - name: 'browser_navigate', - arguments: { url: server.HELLO_WORLD }, - }); - - const confirmationPage = await confirmationPagePromise; - await expect(confirmationPage.locator('.status-banner')).toContainText(`Playwright MCP version trying to connect requires newer extension version`); - - expect(await navigateResponse).toHaveResponse({ - result: expect.stringContaining('Extension connection timeout.'), - isError: true, - }); + expect(await navigateResponse).toHaveResponse({ + pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), }); -} + expect(browserContext.pages()).toHaveLength(4); +}); + +test(`extension not installed timeout`, async ({ browserWithExtension, startClient, server, useShortConnectionTimeout }) => { + useShortConnectionTimeout(100); + + const browserContext = await browserWithExtension.launch(); + + const client = await startWithExtensionFlag(browserWithExtension, startClient); + + const confirmationPagePromise = browserContext.waitForEvent('page', page => { + return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); + }); + + expect(await client.callTool({ + name: 'browser_navigate', + arguments: { url: server.HELLO_WORLD }, + })).toHaveResponse({ + result: expect.stringContaining('Extension connection timeout. Make sure the "Playwright MCP Bridge" extension is installed.'), + isError: true, + }); + + await confirmationPagePromise; +}); + +testWithOldExtensionVersion(`works with old extension version`, async ({ browserWithExtension, startClient, server, useShortConnectionTimeout }) => { + useShortConnectionTimeout(500); + + // Prelaunch the browser, so that it is properly closed after the test. + const browserContext = await browserWithExtension.launch(); + + const client = await startWithExtensionFlag(browserWithExtension, startClient); + + const confirmationPagePromise = browserContext.waitForEvent('page', page => { + return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); + }); + + const navigateResponse = client.callTool({ + name: 'browser_navigate', + arguments: { url: server.HELLO_WORLD }, + }); + + const selectorPage = await confirmationPagePromise; + // For browser_navigate command, the UI shows Allow/Reject buttons instead of tab selector + await selectorPage.getByRole('button', { name: 'Allow' }).click(); + + expect(await navigateResponse).toHaveResponse({ + pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), + }); +}); + +test(`extension needs update`, async ({ browserWithExtension, startClient, server, useShortConnectionTimeout, overrideProtocolVersion }) => { + useShortConnectionTimeout(500); + overrideProtocolVersion(1000); + + // Prelaunch the browser, so that it is properly closed after the test. + const browserContext = await browserWithExtension.launch(); + + const client = await startWithExtensionFlag(browserWithExtension, startClient); + + const confirmationPagePromise = browserContext.waitForEvent('page', page => { + return page.url().startsWith('chrome-extension://jakfalbnbhgkpmoaakfflhflbfpkailf/connect.html'); + }); + + const navigateResponse = client.callTool({ + name: 'browser_navigate', + arguments: { url: server.HELLO_WORLD }, + }); + + const confirmationPage = await confirmationPagePromise; + await expect(confirmationPage.locator('.status-banner')).toContainText(`Playwright MCP version trying to connect requires newer extension version`); + + expect(await navigateResponse).toHaveResponse({ + result: expect.stringContaining('Extension connection timeout.'), + isError: true, + }); +}); test(`custom executablePath`, async ({ startClient, server, useShortConnectionTimeout }) => { useShortConnectionTimeout(1000); @@ -331,6 +302,4 @@ test(`bypass connection dialog with token`, async ({ browserWithExtension, start expect(await navigateResponse).toHaveResponse({ pageState: expect.stringContaining(`- generic [active] [ref=e1]: Hello, world!`), }); - - }); diff --git a/package-lock.json b/package-lock.json index 6493649..85f379b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,15 +9,15 @@ "version": "0.0.52", "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.0-alpha-2025-12-11", - "playwright-core": "1.58.0-alpha-2025-12-11" + "playwright": "1.58.0-alpha-1766189059000", + "playwright-core": "1.58.0-alpha-1766189059000" }, "bin": { "mcp-server-playwright": "cli.js" }, "devDependencies": { "@modelcontextprotocol/sdk": "^1.24.0", - "@playwright/test": "1.58.0-alpha-2025-12-11", + "@playwright/test": "1.58.0-alpha-1766189059000", "@types/node": "^24.3.0" }, "engines": { @@ -63,13 +63,13 @@ } }, "node_modules/@playwright/test": { - "version": "1.58.0-alpha-2025-12-11", - "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0-alpha-2025-12-11.tgz", - "integrity": "sha512-Lo3wdh1iFDzq6s5sW5Lqj9CI9612yUjVIW0s+DQ+lA6Nqz7C9ittrSkMYBcrLNat/IVp1HnUBG1ZmGJIG0dHbA==", + "version": "1.58.0-alpha-1766189059000", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.58.0-alpha-1766189059000.tgz", + "integrity": "sha512-op1/OXuSTm7H0v0vpGtWjLylW3fchuX9TZAPvR+m2QrVKMrqfu17Bzu/l5eMCvIGyJfNqe7JTZuB2Jou9v1EDg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "playwright": "1.58.0-alpha-2025-12-11" + "playwright": "1.58.0-alpha-1766189059000" }, "bin": { "playwright": "cli.js" @@ -884,12 +884,12 @@ } }, "node_modules/playwright": { - "version": "1.58.0-alpha-2025-12-11", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0-alpha-2025-12-11.tgz", - "integrity": "sha512-wNAnyMpt4VZCy9wryVXphHfHgpoD2LRO/h4Bl8GDuvzIpvx6uU/TkRmC5/91feROZ1ng1tTjY6oTVdqIKt7uGQ==", + "version": "1.58.0-alpha-1766189059000", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.58.0-alpha-1766189059000.tgz", + "integrity": "sha512-h6yaIbcmyla/fh9jvvRBgVRMgwSmloKnCR4NDnVV18vqi1i5F4xqe3tGtgwHmkah9CJdQhhbZlTBIkY73q6+Xw==", "license": "Apache-2.0", "dependencies": { - "playwright-core": "1.58.0-alpha-2025-12-11" + "playwright-core": "1.58.0-alpha-1766189059000" }, "bin": { "playwright": "cli.js" @@ -902,9 +902,9 @@ } }, "node_modules/playwright-core": { - "version": "1.58.0-alpha-2025-12-11", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0-alpha-2025-12-11.tgz", - "integrity": "sha512-8c8vO4BMIGmEac13g4hxzWNCP/pGdRLhysUvcANU0uxH5UcN/DeFQ5RP+6NIK732u/KpLjCqI27TWdr1xgKb3A==", + "version": "1.58.0-alpha-1766189059000", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.58.0-alpha-1766189059000.tgz", + "integrity": "sha512-TzOav4UONfbqB0U1I75RrcvOGdJ1icVam2/lje1Lok/D9lX9iJjBLGB4FqNgFqaIgeOqI1hpHY8nMfA82JqJtg==", "license": "Apache-2.0", "bin": { "playwright-core": "cli.js" diff --git a/package.json b/package.json index e792a24..c4042d7 100644 --- a/package.json +++ b/package.json @@ -38,15 +38,15 @@ } }, "dependencies": { - "playwright": "1.58.0-alpha-2025-12-11", - "playwright-core": "1.58.0-alpha-2025-12-11" + "playwright": "1.58.0-alpha-1766189059000", + "playwright-core": "1.58.0-alpha-1766189059000" }, "bin": { "mcp-server-playwright": "cli.js" }, "devDependencies": { "@modelcontextprotocol/sdk": "^1.24.0", - "@playwright/test": "1.58.0-alpha-2025-12-11", + "@playwright/test": "1.58.0-alpha-1766189059000", "@types/node": "^24.3.0" } } diff --git a/tests/capabilities.spec.ts b/tests/capabilities.spec.ts index f7bc620..b5272a0 100644 --- a/tests/capabilities.spec.ts +++ b/tests/capabilities.spec.ts @@ -44,38 +44,6 @@ test('test snapshot tool list', async ({ client }) => { ])); }); -test('test tool list proxy mode', async ({ startClient }) => { - const { client } = await startClient({ - args: ['--connect-tool'], - }); - const { tools } = await client.listTools(); - expect(new Set(tools.map(t => t.name))).toEqual(new Set([ - 'browser_click', - 'browser_connect', // the extra tool - 'browser_console_messages', - 'browser_drag', - 'browser_evaluate', - 'browser_file_upload', - 'browser_fill_form', - 'browser_handle_dialog', - 'browser_hover', - 'browser_select_option', - 'browser_type', - 'browser_close', - 'browser_install', - 'browser_navigate_back', - 'browser_navigate', - 'browser_network_requests', - 'browser_press_key', - 'browser_resize', - 'browser_run_code', - 'browser_snapshot', - 'browser_tabs', - 'browser_take_screenshot', - 'browser_wait_for', - ])); -}); - test('test capabilities (pdf)', async ({ startClient }) => { const { client } = await startClient({ args: ['--caps=pdf'],