From 89f4d4ce4f0d7f019f515eafa8aeb4aa7a25a0a3 Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 20 Nov 2024 16:35:39 +0100 Subject: [PATCH 01/23] chore(html): hmr report should survive reload (#33696) --- packages/html-reporter/src/index.tsx | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/html-reporter/src/index.tsx b/packages/html-reporter/src/index.tsx index 0c3f0a6dc0..16c1ae1a88 100644 --- a/packages/html-reporter/src/index.tsx +++ b/packages/html-reporter/src/index.tsx @@ -50,6 +50,8 @@ window.onload = () => { ReactDOM.createRoot(document.querySelector('#root')!).render(); }; +const kPlaywrightReportStorageForHMR = 'playwrightReportStorageForHMR'; + class ZipReport implements LoadedReport { private _entries = new Map(); private _json!: HTMLReport; @@ -58,8 +60,20 @@ class ZipReport implements LoadedReport { const zipURI = await new Promise(resolve => { if (window.playwrightReportBase64) return resolve(window.playwrightReportBase64); - window.addEventListener('message', event => event.source === window.opener && resolve(event.data), { once: true }); - window.opener.postMessage('ready', '*'); + if (window.opener) { + window.addEventListener('message', event => { + if (event.source === window.opener) { + localStorage.setItem(kPlaywrightReportStorageForHMR, event.data); + resolve(event.data); + } + }, { once: true }); + window.opener.postMessage('ready', '*'); + } else { + const oldReport = localStorage.getItem(kPlaywrightReportStorageForHMR); + if (oldReport) + return resolve(oldReport); + alert('couldnt find report, something with HMR is broken'); + } }); const zipReader = new zipjs.ZipReader(new zipjs.Data64URIReader(zipURI), { useWebWorkers: false }); From 6a32589330d7440ea79148add215afaf8430c0fa Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Wed, 20 Nov 2024 17:13:07 +0100 Subject: [PATCH 02/23] test: update 'should work for canvas' test expectation (#33685) --- tests/android/androidTest.ts | 1 + tests/electron/electronTest.ts | 1 + tests/page/page-screenshot.spec.ts | 4 ++-- tests/page/pageTestApi.ts | 1 + tests/webview2/webView2Test.ts | 1 + 5 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/android/androidTest.ts b/tests/android/androidTest.ts index e81e4a401f..0a5292c763 100644 --- a/tests/android/androidTest.ts +++ b/tests/android/androidTest.ts @@ -61,6 +61,7 @@ export const androidTest = baseTest.extend { await closeAllActivities(androidDeviceWorker); diff --git a/tests/electron/electronTest.ts b/tests/electron/electronTest.ts index 33210e9116..c418236f55 100644 --- a/tests/electron/electronTest.ts +++ b/tests/electron/electronTest.ts @@ -35,6 +35,7 @@ export const electronTest = baseTest.extend(traceViewerFixt isAndroid: [false, { scope: 'worker' }], isElectron: [true, { scope: 'worker' }], isWebView2: [false, { scope: 'worker' }], + isHeadlessShell: [false, { scope: 'worker' }], launchElectronApp: async ({ playwright }, use) => { // This env prevents 'Electron Security Policy' console message. diff --git a/tests/page/page-screenshot.spec.ts b/tests/page/page-screenshot.spec.ts index 7e6856c24c..76985e758c 100644 --- a/tests/page/page-screenshot.spec.ts +++ b/tests/page/page-screenshot.spec.ts @@ -280,12 +280,12 @@ it.describe('page screenshot', () => { expect(screenshot).toMatchSnapshot('screenshot-clip-odd-size.png'); }); - it('should work for canvas', async ({ page, server, isElectron, isMac, isLinux, macVersion, browserName, headless }) => { + it('should work for canvas', async ({ page, server, isElectron, isMac, isLinux, macVersion, browserName, isHeadlessShell }) => { it.fixme(isElectron && isMac, 'Fails on the bots'); await page.setViewportSize({ width: 500, height: 500 }); await page.goto(server.PREFIX + '/screenshots/canvas.html'); const screenshot = await page.screenshot(); - if ((!headless && browserName === 'chromium' && isMac && os.arch() === 'arm64' && macVersion >= 14) || + if ((!isHeadlessShell && browserName === 'chromium' && isMac && os.arch() === 'arm64' && macVersion >= 14) || (browserName === 'webkit' && isLinux && os.arch() === 'x64')) expect(screenshot).toMatchSnapshot('screenshot-canvas-with-accurate-corners.png'); else diff --git a/tests/page/pageTestApi.ts b/tests/page/pageTestApi.ts index 1ccfd608e9..f29af2c92f 100644 --- a/tests/page/pageTestApi.ts +++ b/tests/page/pageTestApi.ts @@ -36,4 +36,5 @@ export type PageWorkerFixtures = { isAndroid: boolean; isElectron: boolean; isWebView2: boolean; + isHeadlessShell: boolean; }; diff --git a/tests/webview2/webView2Test.ts b/tests/webview2/webView2Test.ts index dcadcebe6d..a72fc9f2b6 100644 --- a/tests/webview2/webView2Test.ts +++ b/tests/webview2/webView2Test.ts @@ -32,6 +32,7 @@ export const webView2Test = baseTest.extend(traceViewerFixt isElectron: [false, { scope: 'worker' }], electronMajorVersion: [0, { scope: 'worker' }], isWebView2: [true, { scope: 'worker' }], + isHeadlessShell: [false, { scope: 'worker' }], browser: [async ({ playwright }, use, testInfo) => { const cdpPort = 10000 + testInfo.workerIndex; From fc19e6e7b4224bb9acecb89cbd73a8646a63eccf Mon Sep 17 00:00:00 2001 From: Simon Knott Date: Wed, 20 Nov 2024 17:28:56 +0100 Subject: [PATCH 03/23] fix(test): export TestDetailsAnnotation (#33698) --- packages/playwright/types/test.d.ts | 2 +- utils/generate_types/overrides-test.d.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/playwright/types/test.d.ts b/packages/playwright/types/test.d.ts index 3111aa8764..84111533c9 100644 --- a/packages/playwright/types/test.d.ts +++ b/packages/playwright/types/test.d.ts @@ -1849,7 +1849,7 @@ export interface FullConfig { export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted'; -type TestDetailsAnnotation = { +export type TestDetailsAnnotation = { type: string; description?: string; }; diff --git a/utils/generate_types/overrides-test.d.ts b/utils/generate_types/overrides-test.d.ts index fc0d90a7db..5775917382 100644 --- a/utils/generate_types/overrides-test.d.ts +++ b/utils/generate_types/overrides-test.d.ts @@ -65,7 +65,7 @@ export interface FullConfig { export type TestStatus = 'passed' | 'failed' | 'timedOut' | 'skipped' | 'interrupted'; -type TestDetailsAnnotation = { +export type TestDetailsAnnotation = { type: string; description?: string; }; From f43b86fea43aeb99cfea4a0773c577dd9801b35d Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 21 Nov 2024 12:22:45 +0100 Subject: [PATCH 04/23] devops: delete .devcontainer/devcontainer.json (#33709) Signed-off-by: Max Schmitt --- .devcontainer/devcontainer.json | 11 ----------- 1 file changed, 11 deletions(-) delete mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index b6524c2c49..0000000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "Playwright", - "image": "mcr.microsoft.com/playwright:next", - "postCreateCommand": "npm install && npm run build && apt-get update && apt-get install -y software-properties-common && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && add-apt-repository \"deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable\" && apt-get install -y docker-ce-cli", - "settings": { - "terminal.integrated.shell.linux": "/bin/bash" - }, - "runArgs": [ - "-v", "/var/run/docker.sock:/var/run/docker.sock" - ] -} \ No newline at end of file From d3ffdefd504916589480211981d3344ce1d65f68 Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Thu, 21 Nov 2024 13:45:00 +0000 Subject: [PATCH 05/23] docs: release notes for languages v1.49 (#33706) --- docs/src/api/class-locatorassertions.md | 4 +- docs/src/api/class-tracing.md | 8 +-- docs/src/aria-snapshots.md | 8 +-- docs/src/release-notes-csharp.md | 85 +++++++++++++++++++++++++ docs/src/release-notes-java.md | 73 +++++++++++++++++++++ docs/src/release-notes-python.md | 74 +++++++++++++++++++++ 6 files changed, 242 insertions(+), 10 deletions(-) diff --git a/docs/src/api/class-locatorassertions.md b/docs/src/api/class-locatorassertions.md index 3102ef085e..e070bbc607 100644 --- a/docs/src/api/class-locatorassertions.md +++ b/docs/src/api/class-locatorassertions.md @@ -2122,7 +2122,7 @@ await expect(page.locator('body')).toMatchAriaSnapshot(` ``` ```python async -await page.goto('https://demo.playwright.dev/todomvc/') +await page.goto("https://demo.playwright.dev/todomvc/") await expect(page.locator('body')).to_match_aria_snapshot(''' - heading "todos" - textbox "What needs to be done?" @@ -2130,7 +2130,7 @@ await expect(page.locator('body')).to_match_aria_snapshot(''' ``` ```python sync -page.goto('https://demo.playwright.dev/todomvc/') +page.goto("https://demo.playwright.dev/todomvc/") expect(page.locator('body')).to_match_aria_snapshot(''' - heading "todos" - textbox "What needs to be done?" diff --git a/docs/src/api/class-tracing.md b/docs/src/api/class-tracing.md index 5a89dbdac1..3b0011c7b1 100644 --- a/docs/src/api/class-tracing.md +++ b/docs/src/api/class-tracing.md @@ -302,10 +302,10 @@ await test.step('Log in', async () => { ```java // All actions between group and groupEnd // will be shown in the trace viewer as a group. -page.context().tracing.group("Open Playwright.dev > API"); +page.context().tracing().group("Open Playwright.dev > API"); page.navigate("https://playwright.dev/"); page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("API")).click(); -page.context().tracing.groupEnd(); +page.context().tracing().groupEnd(); ``` ```python sync @@ -329,10 +329,10 @@ await page.context.tracing.group_end() ```csharp // All actions between GroupAsync and GroupEndAsync // will be shown in the trace viewer as a group. -await Page.Context().Tracing.GroupAsync("Open Playwright.dev > API"); +await Page.Context.Tracing.GroupAsync("Open Playwright.dev > API"); await Page.GotoAsync("https://playwright.dev/"); await Page.GetByRole(AriaRole.Link, new() { Name = "API" }).ClickAsync(); -await Page.Context().Tracing.GroupEndAsync(); +await Page.Context.Tracing.GroupEndAsync(); ``` ### param: Tracing.group.name diff --git a/docs/src/aria-snapshots.md b/docs/src/aria-snapshots.md index 0b4673abef..c26178bbe8 100644 --- a/docs/src/aria-snapshots.md +++ b/docs/src/aria-snapshots.md @@ -67,19 +67,19 @@ await expect(page.locator('body')).toMatchAriaSnapshot(` ``` ```python sync -page.locator("body").to_match_aria_snapshot(""" +expect(page.locator("body")).to_match_aria_snapshot(""" - heading "title" """) ``` ```python async -await page.locator("body").to_match_aria_snapshot(""" +await expect(page.locator("body")).to_match_aria_snapshot(""" - heading "title" """) ``` ```java -page.locator("body").expect().toMatchAriaSnapshot(""" +assertThat(page.locator("body")).matchesAriaSnapshot(""" - heading "title" """); ``` @@ -185,7 +185,7 @@ interactive interface: - **"Assert snapshot" Action**: In the code generator, you can use the "Assert snapshot" action to automatically create a snapshot assertion for the selected elements. This is a quick way to capture the aria snapshot as part of your recorded test flow. - + - **"Aria snapshot" Tab**: The "Aria snapshot" tab within the code generator interface visually represents the aria snapshot for a selected locator, letting you explore, inspect, and verify element roles, attributes, and accessible names to aid snapshot creation and review. diff --git a/docs/src/release-notes-csharp.md b/docs/src/release-notes-csharp.md index c39e454ebc..7c1ffc87ab 100644 --- a/docs/src/release-notes-csharp.md +++ b/docs/src/release-notes-csharp.md @@ -5,6 +5,91 @@ toc_max_heading_level: 2 --- +## Version 1.49 + +### Aria snapshots + +New assertion [`method: LocatorAssertions.toMatchAriaSnapshot`] verifies page structure by comparing to an expected accessibility tree, represented as YAML. + +```csharp +await page.GotoAsync("https://playwright.dev"); +await Expect(page.Locator("body")).ToMatchAriaSnapshotAsync(@" + - banner: + - heading /Playwright enables reliable/ [level=1] + - link ""Get started"" + - link ""Star microsoft/playwright on GitHub"" + - main: + - img ""Browsers (Chromium, Firefox, WebKit)"" + - heading ""Any browser • Any platform • One API"" +"); +``` + +You can generate this assertion with [Test Generator](./codegen) or by calling [`method: Locator.ariaSnapshot`]. + +Learn more in the [aria snapshots guide](./aria-snapshots). + +### Tracing groups + +New method [`method: Tracing.group`] allows you to visually group actions in the trace viewer. + +```csharp +// All actions between GroupAsync and GroupEndAsync +// will be shown in the trace viewer as a group. +await Page.Context.Tracing.GroupAsync("Open Playwright.dev > API"); +await Page.GotoAsync("https://playwright.dev/"); +await Page.GetByRole(AriaRole.Link, new() { Name = "API" }).ClickAsync(); +await Page.Context.Tracing.GroupEndAsync(); +``` + +### Breaking: `chrome` and `msedge` channels switch to new headless mode + +This change affects you if you're using one of the following channels in your `playwright.config.ts`: +- `chrome`, `chrome-dev`, `chrome-beta`, or `chrome-canary` +- `msedge`, `msedge-dev`, `msedge-beta`, or `msedge-canary` + +After updating to Playwright v1.49, run your test suite. If it still passes, you're good to go. If not, you will probably need to update your snapshots, and adapt some of your test code around PDF viewers and extensions. See [issue #33566](https://github.com/microsoft/playwright/issues/33566) for more details. + +### Try new Chromium headless + +You can opt into the new headless mode by using `'chromium'` channel. As [official Chrome documentation puts it](https://developer.chrome.com/blog/chrome-headless-shell): + +> New Headless on the other hand is the real Chrome browser, and is thus more authentic, reliable, and offers more features. This makes it more suitable for high-accuracy end-to-end web app testing or browser extension testing. + +See [issue #33566](https://github.com/microsoft/playwright/issues/33566) for the list of possible breakages you could encounter and more details on Chromium headless. Please file an issue if you see any problems after opting in. + +```xml csharp title="runsettings.xml" + + + + chromium + + chromium + + + +``` + +```bash csharp +dotnet test -- Playwright.BrowserName=chromium Playwright.LaunchOptions.Channel=chromium +``` + +### Miscellaneous + +- There will be no more updates for WebKit on Ubuntu 20.04 and Debian 11. We recommend updating your OS to a later version. +- `` elements inside a snapshot now draw a preview. + +### Browser Versions + +- Chromium 131.0.6778.33 +- Mozilla Firefox 132.0 +- WebKit 18.2 + +This version was also tested against the following stable channels: + +- Google Chrome 130 +- Microsoft Edge 130 + + ## Version 1.48 ### WebSocket routing diff --git a/docs/src/release-notes-java.md b/docs/src/release-notes-java.md index a5d01668de..8130c77f07 100644 --- a/docs/src/release-notes-java.md +++ b/docs/src/release-notes-java.md @@ -4,6 +4,79 @@ title: "Release notes" toc_max_heading_level: 2 --- +## Version 1.49 + +### Aria snapshots + +New assertion [`method: LocatorAssertions.toMatchAriaSnapshot`] verifies page structure by comparing to an expected accessibility tree, represented as YAML. + +```java +page.navigate("https://playwright.dev"); +assertThat(page.locator("body")).matchesAriaSnapshot(""" + - banner: + - heading /Playwright enables reliable/ [level=1] + - link "Get started" + - link "Star microsoft/playwright on GitHub" + - main: + - img "Browsers (Chromium, Firefox, WebKit)" + - heading "Any browser • Any platform • One API" +"""); +``` + +You can generate this assertion with [Test Generator](./codegen) or by calling [`method: Locator.ariaSnapshot`]. + +Learn more in the [aria snapshots guide](./aria-snapshots). + +### Tracing groups + +New method [`method: Tracing.group`] allows you to visually group actions in the trace viewer. + +```java +// All actions between group and groupEnd +// will be shown in the trace viewer as a group. +page.context().tracing().group("Open Playwright.dev > API"); +page.navigate("https://playwright.dev/"); +page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("API")).click(); +page.context().tracing().groupEnd(); +``` + +### Breaking: `chrome` and `msedge` channels switch to new headless mode + +This change affects you if you're using one of the following channels in your `playwright.config.ts`: +- `chrome`, `chrome-dev`, `chrome-beta`, or `chrome-canary` +- `msedge`, `msedge-dev`, `msedge-beta`, or `msedge-canary` + +After updating to Playwright v1.49, run your test suite. If it still passes, you're good to go. If not, you will probably need to update your snapshots, and adapt some of your test code around PDF viewers and extensions. See [issue #33566](https://github.com/microsoft/playwright/issues/33566) for more details. + +### Try new Chromium headless + +You can opt into the new headless mode by using `'chromium'` channel. As [official Chrome documentation puts it](https://developer.chrome.com/blog/chrome-headless-shell): + +> New Headless on the other hand is the real Chrome browser, and is thus more authentic, reliable, and offers more features. This makes it more suitable for high-accuracy end-to-end web app testing or browser extension testing. + +See [issue #33566](https://github.com/microsoft/playwright/issues/33566) for the list of possible breakages you could encounter and more details on Chromium headless. Please file an issue if you see any problems after opting in. + +```java +Browser browser = playwright.chromium().launch(new BrowserType.LaunchOptions().setChannel("chromium")); +``` + +### Miscellaneous + +- There will be no more updates for WebKit on Ubuntu 20.04 and Debian 11. We recommend updating your OS to a later version. +- `` elements inside a snapshot now draw a preview. + +### Browser Versions + +- Chromium 131.0.6778.33 +- Mozilla Firefox 132.0 +- WebKit 18.2 + +This version was also tested against the following stable channels: + +- Google Chrome 130 +- Microsoft Edge 130 + + ## Version 1.48 ### WebSocket routing diff --git a/docs/src/release-notes-python.md b/docs/src/release-notes-python.md index 211e0ad5c2..fc7dd1ccd1 100644 --- a/docs/src/release-notes-python.md +++ b/docs/src/release-notes-python.md @@ -4,6 +4,80 @@ title: "Release notes" toc_max_heading_level: 2 --- +## Version 1.49 + +### Aria snapshots + +New assertion [`method: LocatorAssertions.toMatchAriaSnapshot`] verifies page structure by comparing to an expected accessibility tree, represented as YAML. + +```python +page.goto("https://playwright.dev") +expect(page.locator('body')).to_match_aria_snapshot(''' + - banner: + - heading /Playwright enables reliable/ [level=1] + - link "Get started" + - link "Star microsoft/playwright on GitHub" + - main: + - img "Browsers (Chromium, Firefox, WebKit)" + - heading "Any browser • Any platform • One API" +''') +``` + +You can generate this assertion with [Test Generator](./codegen) or by calling [`method: Locator.ariaSnapshot`]. + +Learn more in the [aria snapshots guide](./aria-snapshots). + +### Tracing groups + +New method [`method: Tracing.group`] allows you to visually group actions in the trace viewer. + +```python +# All actions between group and group_end +# will be shown in the trace viewer as a group. +page.context.tracing.group("Open Playwright.dev > API") +page.goto("https://playwright.dev/") +page.get_by_role("link", name="API").click() +page.context.tracing.group_end() +``` + +### Breaking: `chrome` and `msedge` channels switch to new headless mode + +This change affects you if you're using one of the following channels in your `playwright.config.ts`: +- `chrome`, `chrome-dev`, `chrome-beta`, or `chrome-canary` +- `msedge`, `msedge-dev`, `msedge-beta`, or `msedge-canary` + +After updating to Playwright v1.49, run your test suite. If it still passes, you're good to go. If not, you will probably need to update your snapshots, and adapt some of your test code around PDF viewers and extensions. See [issue #33566](https://github.com/microsoft/playwright/issues/33566) for more details. + +### Try new Chromium headless + +You can opt into the new headless mode by using `'chromium'` channel. As [official Chrome documentation puts it](https://developer.chrome.com/blog/chrome-headless-shell): + +> New Headless on the other hand is the real Chrome browser, and is thus more authentic, reliable, and offers more features. This makes it more suitable for high-accuracy end-to-end web app testing or browser extension testing. + +See [issue #33566](https://github.com/microsoft/playwright/issues/33566) for the list of possible breakages you could encounter and more details on Chromium headless. Please file an issue if you see any problems after opting in. + +```bash python +pytest test_login.py --browser-channel chromium +``` + +### Miscellaneous + +- There will be no more updates for WebKit on Ubuntu 20.04 and Debian 11. We recommend updating your OS to a later version. +- `` elements inside a snapshot now draw a preview. +- Python 3.8 is not supported anymore. + +### Browser Versions + +- Chromium 131.0.6778.33 +- Mozilla Firefox 132.0 +- WebKit 18.2 + +This version was also tested against the following stable channels: + +- Google Chrome 130 +- Microsoft Edge 130 + + ## Version 1.48 ### WebSocket routing From 77d82b8b071d203f8f9f2d2bce04e8e8d8b88679 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 21 Nov 2024 15:53:28 +0100 Subject: [PATCH 06/23] chore: remove dead code in urlMatches (#33714) --- docs/src/docker.md | 2 +- packages/playwright-core/src/server/frames.ts | 2 +- packages/playwright-core/src/server/har/harTracer.ts | 2 +- packages/playwright-core/src/server/network.ts | 2 +- packages/playwright-core/src/utils/isomorphic/urlMatch.ts | 8 ++------ 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/docs/src/docker.md b/docs/src/docker.md index bfcf5e73b5..b2a3e906b9 100644 --- a/docs/src/docker.md +++ b/docs/src/docker.md @@ -132,7 +132,7 @@ Browser builds for Firefox and WebKit are built for the [glibc](https://en.wikip You can use the [.NET install script](https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-install-script) in order to install different SDK versions: ```bash -curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --install-dir /usr/share/dotnet --channel 6.0 +curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --install-dir /usr/share/dotnet --channel 9.0 ``` ## Build your own image diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 81f04d94eb..ad793aded8 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -942,7 +942,7 @@ export class Frame extends SdkObject { origin(): string | undefined { if (!this._url.startsWith('http')) return; - return network.parsedURL(this._url)?.origin; + return network.parseURL(this._url)?.origin; } parentFrame(): Frame | null { diff --git a/packages/playwright-core/src/server/har/harTracer.ts b/packages/playwright-core/src/server/har/harTracer.ts index b4b90d7976..ba0e8b46c2 100644 --- a/packages/playwright-core/src/server/har/harTracer.ts +++ b/packages/playwright-core/src/server/har/harTracer.ts @@ -257,7 +257,7 @@ export class HarTracer { const page = request.frame()?._page; if (this._page && page !== this._page) return; - const url = network.parsedURL(request.url()); + const url = network.parseURL(request.url()); if (!url) return; diff --git a/packages/playwright-core/src/server/network.ts b/packages/playwright-core/src/server/network.ts index 42c94fe97b..006f2f4cbf 100644 --- a/packages/playwright-core/src/server/network.ts +++ b/packages/playwright-core/src/server/network.ts @@ -74,7 +74,7 @@ export function rewriteCookies(cookies: channels.SetNetworkCookie[]): channels.S }); } -export function parsedURL(url: string): URL | null { +export function parseURL(url: string): URL | null { try { return new URL(url); } catch (e) { diff --git a/packages/playwright-core/src/utils/isomorphic/urlMatch.ts b/packages/playwright-core/src/utils/isomorphic/urlMatch.ts index f5d6efb70d..1d3bd011dc 100644 --- a/packages/playwright-core/src/utils/isomorphic/urlMatch.ts +++ b/packages/playwright-core/src/utils/isomorphic/urlMatch.ts @@ -107,19 +107,15 @@ export function urlMatches(baseURL: string | undefined, urlString: string, match match = globToRegex(match); if (isRegExp(match)) return match.test(urlString); - if (typeof match === 'string' && match === urlString) - return true; - const url = parsedURL(urlString); + const url = parseURL(urlString); if (!url) return false; - if (typeof match === 'string') - return url.pathname === match; if (typeof match !== 'function') throw new Error('url parameter should be string, RegExp or function'); return match(url); } -function parsedURL(url: string): URL | null { +function parseURL(url: string): URL | null { try { return new URL(url); } catch (e) { From 92436518ff0837ad37117a4c29868911551d65b7 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 21 Nov 2024 15:53:37 +0100 Subject: [PATCH 07/23] docs(python): add LocatorAssertions.NotToMatchAriaSnapshot (#33712) --- docs/src/api/class-locatorassertions.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/docs/src/api/class-locatorassertions.md b/docs/src/api/class-locatorassertions.md index e070bbc607..7a640c4ef6 100644 --- a/docs/src/api/class-locatorassertions.md +++ b/docs/src/api/class-locatorassertions.md @@ -442,6 +442,23 @@ Expected options currently selected. ### option: LocatorAssertions.NotToHaveValues.timeout = %%-csharp-java-python-assertions-timeout-%% * since: v1.23 +## async method: LocatorAssertions.NotToMatchAriaSnapshot +* since: v1.49 +* langs: python + +The opposite of [`method: LocatorAssertions.toMatchAriaSnapshot`]. + +### param: LocatorAssertions.NotToMatchAriaSnapshot.expected +* since: v1.49 +- `expected` + +### option: LocatorAssertions.NotToMatchAriaSnapshot.timeout = %%-js-assertions-timeout-%% +* since: v1.49 + +### option: LocatorAssertions.NotToMatchAriaSnapshot.timeout = %%-csharp-java-python-assertions-timeout-%% +* since: v1.49 + + ## async method: LocatorAssertions.toBeAttached * since: v1.33 From c2a8375ef2532fd1be6dfe0ef9ceda79eb3d6c7c Mon Sep 17 00:00:00 2001 From: Playwright Service <89237858+playwrightmachine@users.noreply.github.com> Date: Thu, 21 Nov 2024 13:36:39 -0800 Subject: [PATCH 08/23] feat(chromium-tip-of-tree): roll to r1280 (#33719) Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- packages/playwright-core/browsers.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index c3b8f66203..1f0d20cb60 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -15,9 +15,9 @@ }, { "name": "chromium-tip-of-tree", - "revision": "1279", + "revision": "1280", "installByDefault": false, - "browserVersion": "133.0.6846.0" + "browserVersion": "133.0.6850.0" }, { "name": "firefox", From 5da0b94357ad9f341d55264747933da2fabb3b56 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 21 Nov 2024 23:42:21 +0100 Subject: [PATCH 09/23] feat(webkit): roll to r2108 (#33710) Co-authored-by: Yury Semikhatsky --- packages/playwright-core/browsers.json | 4 +++- .../src/server/registry/nativeDeps.ts | 9 ++++++--- .../playwright-core/src/server/webkit/webkit.ts | 2 +- tests/library/emulation-focus.spec.ts | 3 ++- tests/page/elementhandle-screenshot.spec.ts | 2 +- ...screenshot-element-padding-border-webkit.png | Bin 179 -> 332 bytes tests/page/page-screenshot.spec.ts | 3 ++- 7 files changed, 15 insertions(+), 8 deletions(-) diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index 1f0d20cb60..884e6dd413 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -33,9 +33,11 @@ }, { "name": "webkit", - "revision": "2105", + "revision": "2108", "installByDefault": true, "revisionOverrides": { + "debian11-x64": "2105", + "debian11-arm64": "2105", "mac10.14": "1446", "mac10.15": "1616", "mac11": "1816", diff --git a/packages/playwright-core/src/server/registry/nativeDeps.ts b/packages/playwright-core/src/server/registry/nativeDeps.ts index d569f13258..6e25e3a14f 100644 --- a/packages/playwright-core/src/server/registry/nativeDeps.ts +++ b/packages/playwright-core/src/server/registry/nativeDeps.ts @@ -329,7 +329,7 @@ export const deps: any = { 'libgstreamer-gl1.0-0', 'libgstreamer-plugins-base1.0-0', 'libgstreamer1.0-0', - 'libgtk-3-0', + 'libgtk-4-1', 'libgudev-1.0-0', 'libharfbuzz-icu0', 'libharfbuzz0b', @@ -400,6 +400,7 @@ export const deps: any = { 'libgsttag-1.0.so.0': 'libgstreamer-plugins-base1.0-0', 'libgstvideo-1.0.so.0': 'libgstreamer-plugins-base1.0-0', 'libgtk-3.so.0': 'libgtk-3-0', + 'libgtk-4.so.1': 'libgtk-4-1', 'libgudev-1.0.so.0': 'libgudev-1.0-0', 'libharfbuzz-icu.so.0': 'libharfbuzz-icu0', 'libharfbuzz.so.0': 'libharfbuzz0b', @@ -544,7 +545,7 @@ export const deps: any = { 'libgstreamer-plugins-bad1.0-0', 'libgstreamer-plugins-base1.0-0', 'libgstreamer1.0-0', - 'libgtk-3-0t64', + 'libgtk-4-1', 'libharfbuzz-icu0', 'libharfbuzz0b', 'libhyphen0', @@ -621,6 +622,7 @@ export const deps: any = { 'libgsttag-1.0.so.0': 'libgstreamer-plugins-base1.0-0', 'libgstvideo-1.0.so.0': 'libgstreamer-plugins-base1.0-0', 'libgtk-3.so.0': 'libgtk-3-0t64', + 'libgtk-4.so.1': 'libgtk-4-1', 'libharfbuzz-icu.so.0': 'libharfbuzz-icu0', 'libharfbuzz.so.0': 'libharfbuzz0b', 'libhyphen.so.0': 'libhyphen0', @@ -967,7 +969,7 @@ export const deps: any = { 'libgstreamer-gl1.0-0', 'libgstreamer-plugins-base1.0-0', 'libgstreamer1.0-0', - 'libgtk-3-0', + 'libgtk-4-1', 'libgudev-1.0-0', 'libharfbuzz-icu0', 'libharfbuzz0b', @@ -1028,6 +1030,7 @@ export const deps: any = { 'libXfixes.so.3': 'libxfixes3', 'libxkbcommon.so.0': 'libxkbcommon0', 'libXrandr.so.2': 'libxrandr2', + 'libgtk-4.so.1': 'libgtk-4-1', } }, }; diff --git a/packages/playwright-core/src/server/webkit/webkit.ts b/packages/playwright-core/src/server/webkit/webkit.ts index 9a11f6c56d..5159f8cecb 100644 --- a/packages/playwright-core/src/server/webkit/webkit.ts +++ b/packages/playwright-core/src/server/webkit/webkit.ts @@ -43,7 +43,7 @@ export class WebKit extends BrowserType { override doRewriteStartupLog(error: ProtocolError): ProtocolError { if (!error.logs) return error; - if (error.logs.includes('cannot open display')) + if (error.logs.includes('Failed to open display') || error.logs.includes('cannot open display')) error.logs = '\n' + wrapInASCIIBox(kNoXServerRunningError, 1); return error; } diff --git a/tests/library/emulation-focus.spec.ts b/tests/library/emulation-focus.spec.ts index dc8b541608..90cbdb6016 100644 --- a/tests/library/emulation-focus.spec.ts +++ b/tests/library/emulation-focus.spec.ts @@ -101,8 +101,9 @@ it('should change document.activeElement', async ({ page, server }) => { expect(active).toEqual(['INPUT', 'TEXTAREA']); }); -it('should not affect screenshots', async ({ page, server, browserName, headless, isWindows, isHeadlessShell }) => { +it('should not affect screenshots', async ({ page, server, browserName, headless, isWindows, isLinux, isHeadlessShell }) => { it.skip(browserName === 'webkit' && isWindows && !headless, 'WebKit/Windows/headed has a larger minimal viewport. See https://github.com/microsoft/playwright/issues/22616'); + it.skip(browserName === 'webkit' && isLinux && !headless, 'WebKit headed has a larger minimal viewport on gtk4.'); it.skip(browserName === 'firefox' && !headless, 'Firefox headed produces a different image'); it.fixme(browserName === 'chromium' && !isHeadlessShell, 'https://github.com/microsoft/playwright/issues/33330'); diff --git a/tests/page/elementhandle-screenshot.spec.ts b/tests/page/elementhandle-screenshot.spec.ts index 042fb7c565..3d5d7c5709 100644 --- a/tests/page/elementhandle-screenshot.spec.ts +++ b/tests/page/elementhandle-screenshot.spec.ts @@ -45,7 +45,7 @@ it.describe('element screenshot', () => { expect(screenshot).toMatchSnapshot('screenshot-element-bounding-box.png'); }); - it('should take into account padding and border', async ({ page }) => { + it('should take into account padding and border', async ({ page, isLinux, headless, browserName }) => { await page.setViewportSize({ width: 500, height: 500 }); await page.setContent(`
oooo
diff --git a/tests/page/elementhandle-screenshot.spec.ts-snapshots/screenshot-element-padding-border-webkit.png b/tests/page/elementhandle-screenshot.spec.ts-snapshots/screenshot-element-padding-border-webkit.png index 971006d83d332b7fffd1f34db9858eaa805756b2..b7e971b762b6d5c9f1fc737f0bb773db31590bb7 100644 GIT binary patch literal 332 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1|)l2v+e>Z#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyy~yTfmH9gA{&t)>{Ikwt2cZhGek5 zy=BPPV8C$rKvP9UJs*ckTK_U5VdplJ>l<%NJhv44^NscV7nzqo_{_Gy|9;*6^WKKj zU8NiL$DThTG+F0D=oE(sQk@T1svJC`BCx|PsY1)sz>t$=-9(9bUP3-TOpVzpZObRI q2v4R+*~T?D{;t_#e(;BsM3eX;akk7k^DeCe`NY%J&t;ucLK6UhPiH^? literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^W+2SL1SFZ&|8@Z>wj^(N7l!{JxM1({$v}||PZ!6K zjK;UO47nN{1XvDQe|-48*w^Ri635n6DVNh8%}thhe0$q==6P?g$9}%rBmG)pe?(xC gBS|pvS1-q$d=Hjv#tm$ffOax?y85}Sb4q9e0CpKZAOHXW diff --git a/tests/page/page-screenshot.spec.ts b/tests/page/page-screenshot.spec.ts index 76985e758c..4e9114ad5d 100644 --- a/tests/page/page-screenshot.spec.ts +++ b/tests/page/page-screenshot.spec.ts @@ -280,8 +280,9 @@ it.describe('page screenshot', () => { expect(screenshot).toMatchSnapshot('screenshot-clip-odd-size.png'); }); - it('should work for canvas', async ({ page, server, isElectron, isMac, isLinux, macVersion, browserName, isHeadlessShell }) => { + it('should work for canvas', async ({ page, server, isElectron, isMac, isLinux, macVersion, browserName, isHeadlessShell, headless }) => { it.fixme(isElectron && isMac, 'Fails on the bots'); + it.fixme(browserName === 'webkit' && isLinux && !headless, 'WebKit has slightly different corners on gtk4.'); await page.setViewportSize({ width: 500, height: 500 }); await page.goto(server.PREFIX + '/screenshots/canvas.html'); const screenshot = await page.screenshot(); From 605df0be8f05ca346ab8f3cad3eadfe4fd1ae9cd Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 21 Nov 2024 16:11:01 -0800 Subject: [PATCH 10/23] chore: add more info about snapshot testing (#33721) --- docs/src/aria-snapshots.md | 138 ++++++++++++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 16 deletions(-) diff --git a/docs/src/aria-snapshots.md b/docs/src/aria-snapshots.md index c26178bbe8..e190fd3022 100644 --- a/docs/src/aria-snapshots.md +++ b/docs/src/aria-snapshots.md @@ -1,36 +1,142 @@ --- id: aria-snapshots -title: "Aria snapshots" +title: "Snapshot testing" --- import LiteYouTube from '@site/src/components/LiteYouTube'; ## Overview -In Playwright, aria snapshots provide a YAML representation of the accessibility tree of a page. -These snapshots can be stored and compared later to verify if the page structure remains consistent or meets defined -expectations. +With the Playwright Snapshot testing you can assert the accessibility tree of a page against a predefined snapshot template. + +```js +await page.goto('https://playwright.dev/'); +await expect(page.getByRole('banner')).toMatchAriaSnapshot(` + - banner: + - heading /Playwright enables reliable end-to-end/ [level=1] + - link "Get started" + - link "Star microsoft/playwright on GitHub" + - link /[\\d]+k\\+ stargazers on GitHub/ +`); +``` + +```python sync +page.goto('https://playwright.dev/') +expect(page.query_selector('banner')).to_match_aria_snapshot(""" + - banner: + - heading /Playwright enables reliable end-to-end/ [level=1] + - link "Get started" + - link "Star microsoft/playwright on GitHub" + - link /[\\d]+k\\+ stargazers on GitHub/ +""") +``` + +```python async +await page.goto('https://playwright.dev/') +await expect(page.query_selector('banner')).to_match_aria_snapshot(""" + - banner: + - heading /Playwright enables reliable end-to-end/ [level=1] + - link "Get started" + - link "Star microsoft/playwright on GitHub" + - link /[\\d]+k\\+ stargazers on GitHub/ +""") +``` + +```java +page.navigate("https://playwright.dev/"); +assertThat(page.locator("banner")).matchesAriaSnapshot(""" + - banner: + - heading /Playwright enables reliable end-to-end/ [level=1] + - link "Get started" + - link "Star microsoft/playwright on GitHub" + - link /[\\d]+k\\+ stargazers on GitHub/ +"""); +``` + +```csharp +await page.GotoAsync("https://playwright.dev/"); +await Expect(page.Locator("banner")).ToMatchAriaSnapshotAsync(@" + - banner: + - heading ""Playwright enables reliable end-to-end testing for modern web apps."" [level=1] + - link ""Get started"" + - link ""Star microsoft/playwright on GitHub"" + - link /[\\d]+k\\+ stargazers on GitHub/ +"); +``` +## Assertion testing vs Snapshot testing + +Snapshot testing and assertion testing serve different purposes in test automation: + +### Assertion testing +Assertion testing is a targeted approach where you assert specific values or conditions about elements or components. For instance, with Playwright, [`method: LocatorAssertions.toHaveText`] +verifies that an element contains the expected text, and [`method: LocatorAssertions.toHaveValue`] +confirms that an input field has the expected value. +Assertion tests are specific and generally check the current state of an element or property +against an expected, predefined state. +They work well for predictable, single-value checks but are limited in scope when testing the +broader structure or variations. + +**Advantages** +- **Clarity**: The intent of the test is explicit and easy to understand. +- **Specificity**: Tests focus on particular aspects of functionality, making them more robust + against unrelated changes. +- **Debugging**: Failures provide targeted feedback, pointing directly to the problematic aspect. + +**Disadvantages** +- **Verbose for complex outputs**: Writing assertions for complex data structures or large outputs + can be cumbersome and error-prone. +- **Maintenance overhead**: As code evolves, manually updating assertions can be time-consuming. + +### Snapshot testing +Snapshot testing captures a “snapshot” or representation of the entire +state of an element, component, or data at a given moment, which is then saved for future +comparisons. When re-running tests, the current state is compared to the snapshot, and if there +are differences, the test fails. This approach is especially useful for complex or dynamic +structures, where manually asserting each detail would be too time-consuming. Snapshot testing +is broader and more holistic than assertion testing, allowing you to track more complex changes over time. + +**Advantages** +- **Simplifies complex outputs**: For example, testing a UI component's rendered output can be tedious with traditional assertions. Snapshots capture the entire output for easy comparison. +- **Quick Feedback loop**: Developers can easily spot unintended changes in the output. +- **Encourages consistency**: Helps maintain consistent output as code evolves. + +**Disadvantages** +- **Over-Reliance**: It can be tempting to accept changes to snapshots without fully understanding + them, potentially hiding bugs. +- **Granularity**: Large snapshots may be hard to interpret when differences arise, especially + if minor changes affect large portions of the output. +- **Suitability**: Not ideal for highly dynamic content where outputs change frequently or + unpredictably. + +### When to use + +- **Snapshot testing** is ideal for: + - UI testing of whole pages and components. + - Broad structural checks for complex UI components. + - Regression testing for outputs that rarely change structure. + +- **Assertion testing** is ideal for: + - Core logic validation. + - Computed value testing. + - Fine-grained tests requiring precise conditions. + +By combining snapshot testing for broad, structural checks and assertion testing for specific functionality, you can achieve a well-rounded testing strategy. + +## Aria snapshots + +In Playwright, aria snapshots provide a YAML representation of the accessibility tree of a page. +These snapshots can be stored and compared later to verify if the page structure remains consistent or meets defined +expectations. + The YAML format describes the hierarchical structure of accessible elements on the page, detailing **roles**, **attributes**, **values**, and **text content**. The structure follows a tree-like syntax, where each node represents an accessible element, and indentation indicates nested elements. -Following is a simple example of an aria snapshot for the playwright.dev homepage: - -```yaml -- banner: - - heading /Playwright enables reliable/ [level=1] - - link "Get started" - - link "Star microsoft/playwright on GitHub" -- main: - - img "Browsers (Chromium, Firefox, WebKit)" - - heading "Any browser • Any platform • One API" -``` - Each accessible element in the tree is represented as a YAML node: ```yaml From e0f0996bbdeb11e238ac2c2b198dc1a3ecd07a49 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Thu, 21 Nov 2024 17:32:07 -0800 Subject: [PATCH 11/23] chore: climb file tree to git root for patches (#33722) --- packages/playwright/src/runner/rebase.ts | 26 ++++++++++++++++++- .../update-aria-snapshot.spec.ts | 8 ++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/playwright/src/runner/rebase.ts b/packages/playwright/src/runner/rebase.ts index bc59e8374a..780735499b 100644 --- a/packages/playwright/src/runner/rebase.ts +++ b/packages/playwright/src/runner/rebase.ts @@ -54,6 +54,7 @@ export async function applySuggestedRebaselines(config: FullConfigInternal, repo const patches: string[] = []; const files: string[] = []; + const gitCache = new Map(); for (const fileName of [...suggestedRebaselines.keys()].sort()) { const source = await fs.promises.readFile(fileName, 'utf8'); @@ -96,7 +97,8 @@ export async function applySuggestedRebaselines(config: FullConfigInternal, repo for (const range of ranges) result = result.substring(0, range.start) + range.newText + result.substring(range.end); - const relativeName = path.relative(process.cwd(), fileName); + const gitFolder = findGitRoot(path.dirname(fileName), gitCache); + const relativeName = path.relative(gitFolder || process.cwd(), fileName); files.push(relativeName); patches.push(createPatch(relativeName, source, result)); } @@ -119,3 +121,25 @@ function createPatch(fileName: string, before: string, after: string) { ...text.split('\n').slice(4) ].join('\n'); } + +function findGitRoot(dir: string, cache: Map): string | null { + const result = cache.get(dir); + if (result !== undefined) + return result; + + const gitPath = path.join(dir, '.git'); + if (fs.existsSync(gitPath) && fs.lstatSync(gitPath).isDirectory()) { + cache.set(dir, dir); + return dir; + } + + const parentDir = path.dirname(dir); + if (dir === parentDir) { + cache.set(dir, null); + return null; + } + + const parentResult = findGitRoot(parentDir, cache); + cache.set(dir, parentResult); + return parentResult; +} diff --git a/tests/playwright-test/update-aria-snapshot.spec.ts b/tests/playwright-test/update-aria-snapshot.spec.ts index 63769f8408..f7bc744561 100644 --- a/tests/playwright-test/update-aria-snapshot.spec.ts +++ b/tests/playwright-test/update-aria-snapshot.spec.ts @@ -26,6 +26,7 @@ function trimPatch(patch: string) { test('should update snapshot with the update-snapshots flag with multiple projects', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'playwright.config.ts': ` export default { projects: [{ name: 'p1' }, { name: 'p2' }] }; `, @@ -73,6 +74,7 @@ test('should update snapshot with the update-snapshots flag with multiple projec test('should update missing snapshots', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'a.spec.ts': ` import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { @@ -116,6 +118,7 @@ test('should update missing snapshots', async ({ runInlineTest }, testInfo) => { test('should generate baseline with regex', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'a.spec.ts': ` import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { @@ -172,6 +175,7 @@ test('should generate baseline with regex', async ({ runInlineTest }, testInfo) test('should generate baseline with special characters', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'a.spec.ts': ` import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { @@ -241,6 +245,7 @@ test('should generate baseline with special characters', async ({ runInlineTest test('should update missing snapshots in tsx', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'playwright.config.ts': playwrightCtConfigText, 'playwright/index.html': ``, 'playwright/index.ts': ``, @@ -286,6 +291,7 @@ test('should update missing snapshots in tsx', async ({ runInlineTest }, testInf test('should update multiple files', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'playwright.config.ts': playwrightCtConfigText, 'playwright/index.html': ``, 'playwright/index.ts': ``, @@ -365,6 +371,7 @@ diff --git a/src/button-2.test.tsx b/src/button-2.test.tsx test('should generate baseline for input values', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'a.spec.ts': ` import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { @@ -400,6 +407,7 @@ test('should generate baseline for input values', async ({ runInlineTest }, test test('should not update snapshots when locator did not match', async ({ runInlineTest }, testInfo) => { const result = await runInlineTest({ + '.git/marker': '', 'a.spec.ts': ` import { test, expect } from '@playwright/test'; test('test', async ({ page }) => { From b32fdade169e2e140db883e0222a83c6f4bac70c Mon Sep 17 00:00:00 2001 From: Playwright Service <89237858+playwrightmachine@users.noreply.github.com> Date: Fri, 22 Nov 2024 03:05:16 -0800 Subject: [PATCH 12/23] feat(chromium): roll to r1150 (#33718) Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com> --- README.md | 4 +- packages/playwright-core/browsers.json | 8 +- .../src/server/deviceDescriptorsSource.json | 96 +++++++++---------- 3 files changed, 54 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index 2f04b28a4f..625e13fb11 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # 🎭 Playwright -[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-132.0.6834.6-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-132.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-18.2-blue.svg?logo=safari)](https://webkit.org/) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord) +[![npm version](https://img.shields.io/npm/v/playwright.svg)](https://www.npmjs.com/package/playwright) [![Chromium version](https://img.shields.io/badge/chromium-132.0.6834.15-blue.svg?logo=google-chrome)](https://www.chromium.org/Home) [![Firefox version](https://img.shields.io/badge/firefox-132.0-blue.svg?logo=firefoxbrowser)](https://www.mozilla.org/en-US/firefox/new/) [![WebKit version](https://img.shields.io/badge/webkit-18.2-blue.svg?logo=safari)](https://webkit.org/) [![Join Discord](https://img.shields.io/badge/join-discord-infomational)](https://aka.ms/playwright/discord) ## [Documentation](https://playwright.dev) | [API reference](https://playwright.dev/docs/api/class-playwright) @@ -8,7 +8,7 @@ Playwright is a framework for Web Testing and Automation. It allows testing [Chr | | Linux | macOS | Windows | | :--- | :---: | :---: | :---: | -| Chromium 132.0.6834.6 | :white_check_mark: | :white_check_mark: | :white_check_mark: | +| Chromium 132.0.6834.15 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | WebKit 18.2 | :white_check_mark: | :white_check_mark: | :white_check_mark: | | Firefox 132.0 | :white_check_mark: | :white_check_mark: | :white_check_mark: | diff --git a/packages/playwright-core/browsers.json b/packages/playwright-core/browsers.json index 884e6dd413..b1d8b9487e 100644 --- a/packages/playwright-core/browsers.json +++ b/packages/playwright-core/browsers.json @@ -3,15 +3,15 @@ "browsers": [ { "name": "chromium", - "revision": "1149", + "revision": "1150", "installByDefault": true, - "browserVersion": "132.0.6834.6" + "browserVersion": "132.0.6834.15" }, { "name": "chromium-headless-shell", - "revision": "1149", + "revision": "1150", "installByDefault": true, - "browserVersion": "132.0.6834.6" + "browserVersion": "132.0.6834.15" }, { "name": "chromium-tip-of-tree", diff --git a/packages/playwright-core/src/server/deviceDescriptorsSource.json b/packages/playwright-core/src/server/deviceDescriptorsSource.json index e82744b73c..ea07b3140a 100644 --- a/packages/playwright-core/src/server/deviceDescriptorsSource.json +++ b/packages/playwright-core/src/server/deviceDescriptorsSource.json @@ -110,7 +110,7 @@ "defaultBrowserType": "webkit" }, "Galaxy S5": { - "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -121,7 +121,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -132,7 +132,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S8": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 360, "height": 740 @@ -143,7 +143,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S8 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; SM-G950U Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 740, "height": 360 @@ -154,7 +154,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S9+": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 320, "height": 658 @@ -165,7 +165,7 @@ "defaultBrowserType": "chromium" }, "Galaxy S9+ landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; SM-G965U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 658, "height": 320 @@ -176,7 +176,7 @@ "defaultBrowserType": "chromium" }, "Galaxy Tab S4": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "viewport": { "width": 712, "height": 1138 @@ -187,7 +187,7 @@ "defaultBrowserType": "chromium" }, "Galaxy Tab S4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.1.0; SM-T837A) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "viewport": { "width": 1138, "height": 712 @@ -1098,7 +1098,7 @@ "defaultBrowserType": "webkit" }, "LG Optimus L70": { - "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 384, "height": 640 @@ -1109,7 +1109,7 @@ "defaultBrowserType": "chromium" }, "LG Optimus L70 landscape": { - "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 640, "height": 384 @@ -1120,7 +1120,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 550": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 640, "height": 360 @@ -1131,7 +1131,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 550 landscape": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 360, "height": 640 @@ -1142,7 +1142,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 950": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 360, "height": 640 @@ -1153,7 +1153,7 @@ "defaultBrowserType": "chromium" }, "Microsoft Lumia 950 landscape": { - "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36 Edge/14.14263", + "userAgent": "Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36 Edge/14.14263", "viewport": { "width": 640, "height": 360 @@ -1164,7 +1164,7 @@ "defaultBrowserType": "chromium" }, "Nexus 10": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "viewport": { "width": 800, "height": 1280 @@ -1175,7 +1175,7 @@ "defaultBrowserType": "chromium" }, "Nexus 10 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "viewport": { "width": 1280, "height": 800 @@ -1186,7 +1186,7 @@ "defaultBrowserType": "chromium" }, "Nexus 4": { - "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 384, "height": 640 @@ -1197,7 +1197,7 @@ "defaultBrowserType": "chromium" }, "Nexus 4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 640, "height": 384 @@ -1208,7 +1208,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -1219,7 +1219,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -1230,7 +1230,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5X": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1241,7 +1241,7 @@ "defaultBrowserType": "chromium" }, "Nexus 5X landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1252,7 +1252,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1263,7 +1263,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1274,7 +1274,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6P": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 412, "height": 732 @@ -1285,7 +1285,7 @@ "defaultBrowserType": "chromium" }, "Nexus 6P landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 732, "height": 412 @@ -1296,7 +1296,7 @@ "defaultBrowserType": "chromium" }, "Nexus 7": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "viewport": { "width": 600, "height": 960 @@ -1307,7 +1307,7 @@ "defaultBrowserType": "chromium" }, "Nexus 7 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "viewport": { "width": 960, "height": 600 @@ -1362,7 +1362,7 @@ "defaultBrowserType": "webkit" }, "Pixel 2": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 411, "height": 731 @@ -1373,7 +1373,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 731, "height": 411 @@ -1384,7 +1384,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 XL": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 411, "height": 823 @@ -1395,7 +1395,7 @@ "defaultBrowserType": "chromium" }, "Pixel 2 XL landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 823, "height": 411 @@ -1406,7 +1406,7 @@ "defaultBrowserType": "chromium" }, "Pixel 3": { - "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 393, "height": 786 @@ -1417,7 +1417,7 @@ "defaultBrowserType": "chromium" }, "Pixel 3 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 9; Pixel 3 Build/PQ1A.181105.017.A1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 786, "height": 393 @@ -1428,7 +1428,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4": { - "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 353, "height": 745 @@ -1439,7 +1439,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 10; Pixel 4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 745, "height": 353 @@ -1450,7 +1450,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4a (5G)": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "screen": { "width": 412, "height": 892 @@ -1465,7 +1465,7 @@ "defaultBrowserType": "chromium" }, "Pixel 4a (5G) landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 4a (5G)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "screen": { "height": 892, "width": 412 @@ -1480,7 +1480,7 @@ "defaultBrowserType": "chromium" }, "Pixel 5": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "screen": { "width": 393, "height": 851 @@ -1495,7 +1495,7 @@ "defaultBrowserType": "chromium" }, "Pixel 5 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "screen": { "width": 851, "height": 393 @@ -1510,7 +1510,7 @@ "defaultBrowserType": "chromium" }, "Pixel 7": { - "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "screen": { "width": 412, "height": 915 @@ -1525,7 +1525,7 @@ "defaultBrowserType": "chromium" }, "Pixel 7 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 14; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "screen": { "width": 915, "height": 412 @@ -1540,7 +1540,7 @@ "defaultBrowserType": "chromium" }, "Moto G4": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 360, "height": 640 @@ -1551,7 +1551,7 @@ "defaultBrowserType": "chromium" }, "Moto G4 landscape": { - "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Mobile Safari/537.36", + "userAgent": "Mozilla/5.0 (Linux; Android 7.0; Moto G (4)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Mobile Safari/537.36", "viewport": { "width": 640, "height": 360 @@ -1562,7 +1562,7 @@ "defaultBrowserType": "chromium" }, "Desktop Chrome HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "screen": { "width": 1792, "height": 1120 @@ -1577,7 +1577,7 @@ "defaultBrowserType": "chromium" }, "Desktop Edge HiDPI": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36 Edg/132.0.6834.6", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36 Edg/132.0.6834.15", "screen": { "width": 1792, "height": 1120 @@ -1622,7 +1622,7 @@ "defaultBrowserType": "webkit" }, "Desktop Chrome": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36", "screen": { "width": 1920, "height": 1080 @@ -1637,7 +1637,7 @@ "defaultBrowserType": "chromium" }, "Desktop Edge": { - "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.6 Safari/537.36 Edg/132.0.6834.6", + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.6834.15 Safari/537.36 Edg/132.0.6834.15", "screen": { "width": 1920, "height": 1080 From b7e47dc0bd9863f1c36b96f8b68b87ca8a1ff717 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Fri, 22 Nov 2024 12:35:14 +0100 Subject: [PATCH 13/23] docs(test-runners): restructure .NET test-runners doc (#33727) --- docs/src/intro-csharp.md | 2 +- docs/src/languages.md | 2 +- docs/src/library-csharp.md | 2 +- docs/src/test-runners-csharp.md | 293 ++++++++++++++++++-------------- 4 files changed, 166 insertions(+), 133 deletions(-) diff --git a/docs/src/intro-csharp.md b/docs/src/intro-csharp.md index e0491aa3cc..3a6eb16e0b 100644 --- a/docs/src/intro-csharp.md +++ b/docs/src/intro-csharp.md @@ -7,7 +7,7 @@ title: "Installation" Playwright was created specifically to accommodate the needs of end-to-end testing. Playwright supports all modern rendering engines including Chromium, WebKit, and Firefox. Test on Windows, Linux, and macOS, locally or on CI, headless or headed with native mobile emulation. -You can choose to use [MSTest base classes](./test-runners.md#mstest) or [NUnit base classes](./test-runners.md#nunit) that Playwright provides to write end-to-end tests. These classes support running tests on multiple browser engines, parallelizing tests, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. Alternatively you can use the [library](./library.md) to manually write the testing infrastructure. +You can choose to use [MSTest base classes](./test-runners.md) or [NUnit base classes](./test-runners.md) that Playwright provides to write end-to-end tests. These classes support running tests on multiple browser engines, parallelizing tests, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. Alternatively you can use the [library](./library.md) to manually write the testing infrastructure. 1. Start by creating a new project with `dotnet new`. This will create the `PlaywrightTests` directory which includes a `UnitTest1.cs` file: diff --git a/docs/src/languages.md b/docs/src/languages.md index 050c1597b3..8e362def84 100644 --- a/docs/src/languages.md +++ b/docs/src/languages.md @@ -30,7 +30,7 @@ You can choose any testing framework such as JUnit or TestNG based on your proje ## .NET -Playwright for .NET comes with [MSTest base classes](https://playwright.dev/dotnet/docs/test-runners#mstest) and [NUnit base classes](https://playwright.dev/dotnet/docs/test-runners#nunit) for writing end-to-end tests. +Playwright for .NET comes with [MSTest base classes](https://playwright.dev/dotnet/docs/test-runners) and [NUnit base classes](https://playwright.dev/dotnet/docs/test-runners) for writing end-to-end tests. * [Documentation](https://playwright.dev/dotnet/docs/intro) * [GitHub repo](https://github.com/microsoft/playwright-dotnet) diff --git a/docs/src/library-csharp.md b/docs/src/library-csharp.md index db501645ea..fba2d12ba2 100644 --- a/docs/src/library-csharp.md +++ b/docs/src/library-csharp.md @@ -5,7 +5,7 @@ title: "Getting started - Library" ## Introduction -Playwright can either be used with the [MSTest](./test-runners.md#mstest) or [NUnit](./test-runners.md#nunit), or as a Playwright Library (this guide). If you are working on an application that utilizes Playwright capabilities or you are using Playwright with another test runner, read on. +Playwright can either be used with the [MSTest](./test-runners.md) or [NUnit](./test-runners.md), or as a Playwright Library (this guide). If you are working on an application that utilizes Playwright capabilities or you are using Playwright with another test runner, read on. ## Usage diff --git a/docs/src/test-runners-csharp.md b/docs/src/test-runners-csharp.md index 74c0f0ff08..e1446f3f0c 100644 --- a/docs/src/test-runners-csharp.md +++ b/docs/src/test-runners-csharp.md @@ -5,19 +5,57 @@ title: "Test Runners" ## Introduction -While Playwright for .NET isn't tied to a particular test runner or testing framework, in our experience the easiest way of getting started is by using the base classes we provide for [MSTest](#mstest) and [NUnit](#nunit). These classes support running tests on multiple browser engines, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. +While Playwright for .NET isn't tied to a particular test runner or testing framework, in our experience the easiest way of getting started is by using the base classes we provide for MSTest and NUnit. These classes support running tests on multiple browser engines, adjusting launch/context options and getting a [Page]/[BrowserContext] instance per test out of the box. Playwright and Browser instances will be reused between tests for better performance. We recommend running each test case in a new BrowserContext, this way browser state will be isolated between the tests. -## MSTest + + + +Playwright provides base classes to write tests with NUnit via the [`Microsoft.Playwright.NUnit`](https://www.nuget.org/packages/Microsoft.Playwright.NUnit) package. + + + Playwright provides base classes to write tests with MSTest via the [`Microsoft.Playwright.MSTest`](https://www.nuget.org/packages/Microsoft.Playwright.MSTest) package. + + + Check out the [installation guide](./intro.md) to get started. -### Running MSTest tests in Parallel +## Running tests in Parallel + + + + +By default NUnit will run all test files in parallel, while running tests inside each file sequentially (`ParallelScope.Self`). It will create as many processes as there are cores on the host system. You can adjust this behavior using the NUnit.NumberOfTestWorkers parameter. +Only `ParallelScope.Self` is supported. + +For CPU-bound tests, we recommend using as many workers as there are cores on your system, divided by 2. For IO-bound tests you can use as many workers as you have cores. + +```bash +dotnet test -- NUnit.NumberOfTestWorkers=5 +``` + + + By default MSTest will run all classes in parallel, while running tests inside each class sequentially (`ExecutionScope.ClassLevel`). It will create as many processes as there are cores on the host system. You can adjust this behavior by using the following CLI parameter or using a `.runsettings` file, see below. Running tests in parallel at the method level (`ExecutionScope.MethodLevel`) is not supported. @@ -26,7 +64,58 @@ Running tests in parallel at the method level (`ExecutionScope.MethodLevel`) is dotnet test --settings:.runsettings -- MSTest.Parallelize.Workers=4 ``` -### Customizing [BrowserContext] options + + + + +## Customizing [BrowserContext] options + + + + +To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example: + +```csharp +using Microsoft.Playwright.NUnit; + +namespace PlaywrightTests; + +[Parallelizable(ParallelScope.Self)] +[TestFixture] +public class MyTest : PageTest +{ + [Test] + public async Task TestWithCustomContextOptions() + { + // The following Page (and BrowserContext) instance has the custom colorScheme, viewport and baseURL set: + await Page.GotoAsync("/login"); + } + + public override BrowserNewContextOptions ContextOptions() + { + return new BrowserNewContextOptions() + { + ColorScheme = ColorScheme.Light, + ViewportSize = new() + { + Width = 1920, + Height = 1080 + }, + BaseURL = "https://github.com", + }; + } +} +``` + + + To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example: @@ -65,7 +154,11 @@ public class ExampleTest : PageTest ``` -### Customizing [Browser]/launch options + + + + +## Customizing [Browser]/launch options [Browser]/launch options can be overridden either using a run settings file or by setting the run settings options directly via the CLI. See the following example: @@ -87,14 +180,55 @@ CLI. See the following example: dotnet test -- Playwright.BrowserName=chromium Playwright.LaunchOptions.Headless=false Playwright.LaunchOptions.Channel=msedge ``` -### Using Verbose API Logs +## Using Verbose API Logs -When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. In MSTest, within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test. +When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. Within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test. -### Using the .runsettings file +## Using the .runsettings file When running tests from Visual Studio, you can take advantage of the `.runsettings` file. The following shows a reference of the supported values. + + + +For example, to specify the number of workers you can use `NUnit.NumberOfTestWorkers` or to enable `DEBUG` logs `RunConfiguration.EnvironmentVariables`. + +```xml + + + + + 24 + + + + + + pw:api + + + + + chromium + 5000 + + false + msedge + + + +``` + + + + For example, to specify the number of workers, you can use `MSTest.Parallelize.Workers`. You can also enable `DEBUG` logs using `RunConfiguration.EnvironmentVariables`. ```xml @@ -125,131 +259,30 @@ For example, to specify the number of workers, you can use `MSTest.Parallelize.W ``` -### Base MSTest classes for Playwright + + + +## Base classes for Playwright + + + + +There are a few base classes available to you in `Microsoft.Playwright.NUnit` namespace: + + + There are a few base classes available to you in `Microsoft.Playwright.MSTest` namespace: -|Test |Description| -|--------------|-----------| -|PageTest |Each test gets a fresh copy of a web [Page] created in its own unique [BrowserContext]. Extending this class is the simplest way of writing a fully-functional Playwright test.



Note: You can override the `ContextOptions` method in each test file to control context options, the ones typically passed into the [`method: Browser.newContext`] method. That way you can specify all kinds of emulation options for your test file individually.| -|ContextTest |Each test will get a fresh copy of a [BrowserContext]. You can create as many pages in this context as you'd like. Using this test is the easiest way to test multi-page scenarios where you need more than one tab.



Note: You can override the `ContextOptions` method in each test file to control context options, the ones typically passed into the [`method: Browser.newContext`] method. That way you can specify all kinds of emulation options for your test file individually.| -|BrowserTest |Each test will get a browser and can create as many contexts as it likes. Each test is responsible for cleaning up all the contexts it created.| -|PlaywrightTest|This gives each test a Playwright object so that the test could start and stop as many browsers as it likes.| - -## NUnit - -Playwright provides base classes to write tests with NUnit via the [`Microsoft.Playwright.NUnit`](https://www.nuget.org/packages/Microsoft.Playwright.NUnit) package. - -Check out the [installation guide](./intro.md) to get started. - -### Running NUnit tests in Parallel - -By default NUnit will run all test files in parallel, while running tests inside each file sequentially (`ParallelScope.Self`). It will create as many processes as there are cores on the host system. You can adjust this behavior using the NUnit.NumberOfTestWorkers parameter. -Only `ParallelScope.Self` is supported. - -For CPU-bound tests, we recommend using as many workers as there are cores on your system, divided by 2. For IO-bound tests you can use as many workers as you have cores. - -```bash -dotnet test -- NUnit.NumberOfTestWorkers=5 -``` - -### Customizing [BrowserContext] options - -To customize context options, you can override the `ContextOptions` method of your test class derived from `Microsoft.Playwright.MSTest.PageTest` or `Microsoft.Playwright.MSTest.ContextTest`. See the following example: - -```csharp -using Microsoft.Playwright.NUnit; - -namespace PlaywrightTests; - -[Parallelizable(ParallelScope.Self)] -[TestFixture] -public class MyTest : PageTest -{ - [Test] - public async Task TestWithCustomContextOptions() - { - // The following Page (and BrowserContext) instance has the custom colorScheme, viewport and baseURL set: - await Page.GotoAsync("/login"); - } - - public override BrowserNewContextOptions ContextOptions() - { - return new BrowserNewContextOptions() - { - ColorScheme = ColorScheme.Light, - ViewportSize = new() - { - Width = 1920, - Height = 1080 - }, - BaseURL = "https://github.com", - }; - } -} -``` - -### Customizing [Browser]/launch options - -[Browser]/launch options can be overridden either using a run settings file or by setting the run settings options directly via the -CLI. See the following example: - -```xml - - - - chromium - - false - msedge - - - -``` - -```bash -dotnet test -- Playwright.BrowserName=chromium Playwright.LaunchOptions.Headless=false Playwright.LaunchOptions.Channel=msedge -``` - -### Using Verbose API Logs - -When you have enabled the [verbose API log](./debug.md#verbose-api-logs), via the `DEBUG` environment variable, you will see the messages in the standard error stream. In NUnit, within Visual Studio, that will be the `Tests` pane of the `Output` window. It will also be displayed in the `Test Log` for each test. - -### Using the .runsettings file - -When running tests from Visual Studio, you can take advantage of the `.runsettings` file. The following shows a reference of the supported values. - -For example, to specify the amount of workers you can use `NUnit.NumberOfTestWorkers` or to enable `DEBUG` logs `RunConfiguration.EnvironmentVariables`. - -```xml - - - - - 24 - - - - - - pw:api - - - - - chromium - 5000 - - false - msedge - - - -``` - -### Base NUnit classes for Playwright - -There are a few base classes available to you in `Microsoft.Playwright.NUnit` namespace: +
+
|Test |Description| |--------------|-----------| From f123f7ac690f9184f0781c47950924e0094f605e Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 22 Nov 2024 11:40:43 +0000 Subject: [PATCH 14/23] fix: isEditable/toBeEditable throw for elements that cannot be editable/readonly (#33713) --- docs/src/actionability.md | 13 +++++++++++-- docs/src/api/class-locator.md | 2 +- .../src/server/injected/injectedScript.ts | 11 +++++++---- .../src/server/injected/roleUtils.ts | 15 +++++++++++++++ packages/playwright-core/types/types.d.ts | 4 +++- tests/page/expect-boolean.spec.ts | 7 +++++++ tests/page/locator-convenience.spec.ts | 15 ++++++++++++++- tests/page/page-fill.spec.ts | 4 ++-- 8 files changed, 60 insertions(+), 11 deletions(-) diff --git a/docs/src/actionability.md b/docs/src/actionability.md index 4a84f5f5b2..3510171e5c 100644 --- a/docs/src/actionability.md +++ b/docs/src/actionability.md @@ -93,11 +93,20 @@ Element is considered stable when it has maintained the same bounding box for at ## Enabled -Element is considered enabled unless it is a ` + `); await page.$eval('textarea', t => t.readOnly = true); const input1 = page.locator('#input1'); expect(await input1.isEditable()).toBe(false); @@ -130,6 +138,11 @@ it('isEditable should work', async ({ page }) => { const textarea = page.locator('textarea'); expect(await textarea.isEditable()).toBe(false); expect(await page.isEditable('textarea')).toBe(false); + expect(await page.locator('div').isEditable()).toBe(true); + expect(await page.locator('#span1').isEditable()).toBe(false); + expect(await page.locator('#span2').isEditable()).toBe(true); + const error = await page.locator('button').isEditable().catch(e => e); + expect(error.message).toContain('Element is not an ,