diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index 6fa27ab5af4c3..c1af96ccba44c 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -45,7 +45,7 @@ }, { "name": "webkit", - "revision": "2318", + "revision": "2319", "installByDefault": true, "revisionOverrides": { "mac14": "2251", diff --git a/packages/playwright-core/src/cli/DEPS.list b/packages/playwright-core/src/cli/DEPS.list index 956f4210d5952..f71bab90aa05f 100644 --- a/packages/playwright-core/src/cli/DEPS.list +++ b/packages/playwright-core/src/cli/DEPS.list @@ -8,6 +8,7 @@ ../remote/ ../server/trace/viewer/ ../tools/cli-client/program.ts +../tools/mcp/program.ts ../tools/trace/traceCli.ts ../bootstrap.ts node_modules/commander diff --git a/packages/playwright-core/src/cli/program.ts b/packages/playwright-core/src/cli/program.ts index b5d63420c3445..64ea909101883 100644 --- a/packages/playwright-core/src/cli/program.ts +++ b/packages/playwright-core/src/cli/program.ts @@ -29,6 +29,7 @@ import { installBrowsers, uninstallBrowsers, installDeps } from './installAction import { runTraceInBrowser, runTraceViewerApp } from '../server/trace/viewer/traceViewer'; import { screenshot, pdf } from './browserActions'; import { program as cliProgram } from '../tools/cli-client/program'; +import { decorateMCPCommand } from '../tools/mcp/program'; import type { TraceViewerServerOptions } from '../server/trace/viewer/traceViewer'; import type { Command } from 'commander'; @@ -236,7 +237,8 @@ export function decorateProgram(program: Command) { addTraceCommands(program, logErrorAndExit); program - .command('cli', { hidden: true }) + .command('cli') + .description('run playwright cli commands from terminal') .allowExcessArguments(true) .allowUnknownOption(true) .helpOption(false) @@ -244,6 +246,10 @@ export function decorateProgram(program: Command) { process.argv.splice(process.argv.indexOf('cli'), 1); cliProgram().catch(logErrorAndExit); }); + + decorateMCPCommand(program + .command('mcp') + .description('run the Playwright MCP server')); } function logErrorAndExit(e: Error) { diff --git a/packages/playwright-core/src/tools/mcp/program.ts b/packages/playwright-core/src/tools/mcp/program.ts index e29d72fed016c..f074c961e2b41 100644 --- a/packages/playwright-core/src/tools/mcp/program.ts +++ b/packages/playwright-core/src/tools/mcp/program.ts @@ -132,12 +132,18 @@ export function decorateMCPCommand(command: Command) { }, disposed: async backend => { clientCount--; - if (sharedBrowserPromise && clientCount > 0) + const browserContext = (backend as BrowserBackend).browserContext; + + if (sharedBrowserPromise && clientCount > 0) { + if (config.browser.isolated) { + testDebug('close context'); + await browserContext.close().catch(() => { }); + } return; + } testDebug('close browser'); sharedBrowserPromise = undefined; - const browserContext = (backend as BrowserBackend).browserContext; await browserContext.close().catch(() => { }); await browserContext.browser()?.close().catch(() => { }); } diff --git a/tests/library/modernizr.spec.ts b/tests/library/modernizr.spec.ts index 27a2ba720cc31..303833fb9c134 100644 --- a/tests/library/modernizr.spec.ts +++ b/tests/library/modernizr.spec.ts @@ -32,7 +32,7 @@ async function checkFeatures(name: string, context: BrowserContext, server: Test } } -it('Safari Desktop', async ({ browser, browserName, platform, httpsServer, headless, channel, isFrozenWebkit }) => { +it('Safari Desktop', async ({ browser, browserName, platform, httpsServer, channel, isFrozenWebkit }) => { it.skip(browserName !== 'webkit'); it.skip(browserName === 'webkit' && platform === 'darwin' && os.arch() === 'x64', 'Modernizr uses WebGL which is not available on Intel macOS - https://bugs.webkit.org/show_bug.cgi?id=278277'); it.skip(isFrozenWebkit); @@ -58,8 +58,7 @@ it('Safari Desktop', async ({ browser, browserName, platform, httpsServer, headl if (platform === 'linux' || channel === 'webkit-wsl') { expected.speechrecognition = false; expected.mediastream = false; - if (headless) - expected.todataurlwebp = true; + expected.todataurlwebp = true; // GHA delete actual.variablefonts; @@ -90,7 +89,7 @@ it('Safari Desktop', async ({ browser, browserName, platform, httpsServer, headl expect(actual).toEqual(expected); }); -it('Mobile Safari', async ({ playwright, browser, browserName, platform, httpsServer, headless, channel, isFrozenWebkit }) => { +it('Mobile Safari', async ({ playwright, browser, browserName, platform, httpsServer, channel, isFrozenWebkit }) => { it.skip(browserName !== 'webkit'); it.skip(browserName === 'webkit' && platform === 'darwin' && os.arch() === 'x64', 'Modernizr uses WebGL which is not available on Intel macOS - https://bugs.webkit.org/show_bug.cgi?id=278277'); it.skip(isFrozenWebkit); @@ -122,8 +121,7 @@ it('Mobile Safari', async ({ playwright, browser, browserName, platform, httpsSe if (platform === 'linux' || channel === 'webkit-wsl') { expected.speechrecognition = false; expected.mediastream = false; - if (headless) - expected.todataurlwebp = true; + expected.todataurlwebp = true; // GHA delete actual.variablefonts; diff --git a/tests/mcp/http.spec.ts b/tests/mcp/http.spec.ts index 292e7e1275aea..85dca4f8773e6 100644 --- a/tests/mcp/http.spec.ts +++ b/tests/mcp/http.spec.ts @@ -161,7 +161,7 @@ test('http transport browser sigint', async ({ serverEndpoint, server }) => { }); }); -test('http transport browser lifecycle (isolated, multiclient)', async ({ serverEndpoint, server }) => { +test('http transport browser lifecycle (isolated, multiclient)', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/41539' } }, async ({ serverEndpoint, server }) => { const { url, stderr } = await serverEndpoint({ args: ['--isolated'] }); const transport1 = new StreamableHTTPClientTransport(new URL('/mcp', url)); @@ -200,6 +200,7 @@ test('http transport browser lifecycle (isolated, multiclient)', async ({ server 'delete http session': 3, 'create context': 3, 'create browser (isolated)': 1, + 'close context': 2, 'close browser': 1, }); }); @@ -229,6 +230,7 @@ test('http transport browser lifecycle (isolated, concurrent clients)', { annota 'delete http session': 3, 'create context': 3, 'create browser (isolated)': 1, + 'close context': 2, 'close browser': 1, }); }); diff --git a/tests/mcp/sse.spec.ts b/tests/mcp/sse.spec.ts index 753b233d2839a..2ea74f488e1d6 100644 --- a/tests/mcp/sse.spec.ts +++ b/tests/mcp/sse.spec.ts @@ -161,6 +161,7 @@ test('sse transport browser lifecycle (isolated, multiclient)', async ({ serverE 'delete SSE session': 3, 'create context': 3, 'create browser (isolated)': 1, + 'close context': 2, 'close browser': 1, }); }); diff --git a/tests/page/page-click.spec.ts b/tests/page/page-click.spec.ts index fde976f76e71d..bfe0691e5cf4d 100644 --- a/tests/page/page-click.spec.ts +++ b/tests/page/page-click.spec.ts @@ -1223,6 +1223,22 @@ it('should fire contextmenu event on right click in correct order', async ({ pag await expect.poll(() => entries).toEqual(['mousedown', 'contextmenu', 'mouseup']); }); +it('should click after a right click', { annotation: { type: 'issue', description: 'https://github.com/microsoft/playwright/issues/39246' } }, async ({ page, browserName }) => { + // On webkit the native context menu opened by the right click swallows the + // following left click, so the button never receives it. + it.fixme(browserName === 'webkit'); + await page.setContent(` + + + `); + await page.getByRole('button').click({ button: 'right' }); + await page.getByRole('button').click(); + await expect(page.getByRole('button')).toHaveText('Clicked!'); +}); + it('should set PointerEvent.pressure on pointerdown', async ({ page, isLinux, headless }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/35844' }); await page.setContent(`