### Install browsers and dependencies using playwright install Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-cli-js.md Examples for installing all supported browsers, specific browsers like Chromium or WebKit, and installing browsers alongside required OS dependencies. ```bash # Install all browsers npx playwright install # Install only Chromium npx playwright install chromium # Install specific browsers npx playwright install chromium webkit # Install browsers with dependencies npx playwright install --with-deps ``` -------------------------------- ### Install Firefox beta and run BiDi tests with BIDI_FFPATH Source: https://github.com/microsoft/playwright/blob/main/tests/bidi/README.md Installs the Firefox beta channel in the project root and executes the BiDi test suite against the installed custom binary path. ```sh npx -y @puppeteer/browsers install firefox@beta ``` ```sh BIDI_FFPATH='/Users/myself/playwright/firefox/mac_arm-beta_138.0b5/Firefox.app/Contents/MacOS/firefox' npm run biditest -- --project='moz-firefox-*' ``` -------------------------------- ### Control time with page.clock.install, pause_at, and fast_forward Source: https://github.com/microsoft/playwright/blob/main/docs/src/release-notes-python.md Use the Clock API to install a fixed time, pause at a specific moment, and fast-forward. This example verifies time-related behavior by asserting the displayed time. ```python # Initialize clock with some time before the test time and let the page load # naturally. `Date.now` will progress as the timers fire. page.clock.install(time=datetime.datetime(2024, 2, 2, 8, 0, 0)) page.goto("http://localhost:3333") # Pretend that the user closed the laptop lid and opened it again at 10am. # Pause the time once reached that point. page.clock.pause_at(datetime.datetime(2024, 2, 2, 10, 0, 0)) # Assert the page state. expect(page.get_by_test_id("current-time")).to_have_text("2/2/2024, 10:00:00 AM") # Close the laptop lid again and open it at 10:30am. page.clock.fast_forward("30:00") expect(page.get_by_test_id("current-time")).to_have_text("2/2/2024, 10:30:00 AM") ``` -------------------------------- ### Install a different .NET SDK version using dotnet-install.sh Source: https://github.com/microsoft/playwright/blob/main/docs/src/docker.md Uses the official .NET install script to install a specified .NET SDK channel into `/usr/share/dotnet`. ```bash curl -sSL https://dot.net/v1/dotnet-install.sh | bash /dev/stdin --install-dir /usr/share/dotnet --channel 9.0 ``` -------------------------------- ### Define setup project in playwright.config.ts Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-global-setup-teardown-js.md Configure a setup project matching the setup test file using testMatch in the Playwright configuration. ```js import { defineConfig } from '@playwright/test'; export default defineConfig({ testDir: './tests', // ... projects: [ { name: 'setup db', testMatch: /global\.setup\.ts/, }, // { // other project // } ] }); ``` -------------------------------- ### Install dependencies and run build in watch mode Source: https://github.com/microsoft/playwright/blob/main/CONTRIBUTING.md Install clean dependencies via npm ci, run the continuous watch build, and install required browsers. Note that watch mode automatically regenerates certain files. ```bash npm ci npm run watch npx playwright install ``` -------------------------------- ### Install Playwright with uv Source: https://github.com/microsoft/playwright/blob/main/docs/src/library-python.md Updates uv, adds Playwright to the environment, and installs the required browser binaries. ```bash uv self update uv add playwright playwright install ``` -------------------------------- ### List supported browsers using Python CLI Source: https://github.com/microsoft/playwright/blob/main/docs/src/browsers.md Run the install command with the --help flag to view all supported browser installation options. ```bash playwright install --help ``` -------------------------------- ### Capture trace on failures during global setup Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-global-setup-teardown-js.md Wraps globalSetup actions in a try...catch block to start and stop Playwright tracing, ensuring failed setups save a trace file before throwing. ```typescript import { chromium, type FullConfig } from '@playwright/test'; async function globalSetup(config: FullConfig) { const { baseURL, storageState } = config.projects[0].use; const browser = await chromium.launch(); const context = await browser.newContext(); const page = await context.newPage(); try { await context.tracing.start({ screenshots: true, snapshots: true }); await page.goto(baseURL!); await page.getByLabel('User Name').fill('user'); await page.getByLabel('Password').fill('password'); await page.getByText('Sign in').click(); await context.storageState({ path: storageState as string }); await context.tracing.stop({ path: './test-results/setup-trace.zip', }); await browser.close(); } catch (error) { await context.tracing.stop({ path: './test-results/failed-setup-trace.zip', }); await browser.close(); throw error; } } export default globalSetup; ``` -------------------------------- ### Create a page, navigate, and take a screenshot Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md This example launches a WebKit browser, creates a new context and page, navigates to 'https://example.com', and saves a screenshot as 'screenshot.png'. It demonstrates the basic workflow for interacting with a page. ```javascript const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'. (async () => { const browser = await webkit.launch(); const context = await browser.newContext(); const page = await context.newPage(); await page.goto('https://example.com'); await page.screenshot({ path: 'screenshot.png' }); await browser.close(); })(); ``` ```java import com.microsoft.playwright.*; public class Example { public static void main(String[] args) { try (Playwright playwright = Playwright.create()) { BrowserType webkit = playwright.webkit(); Browser browser = webkit.launch(); BrowserContext context = browser.newContext(); Page page = context.newPage(); page.navigate("https://example.com"); page.screenshot(new Page.ScreenshotOptions().setPath(Paths.get("screenshot.png"))); browser.close(); } } } ``` ```python import asyncio from playwright.async_api import async_playwright, Playwright async def run(playwright: Playwright): webkit = playwright.webkit browser = await webkit.launch() context = await browser.new_context() page = await context.new_page() await page.goto("https://example.com") await page.screenshot(path="screenshot.png") await browser.close() async def main(): async with async_playwright() as playwright: await run(playwright) asyncio.run(main()) ``` ```python from playwright.sync_api import sync_playwright, Playwright def run(playwright: Playwright): webkit = playwright.webkit browser = webkit.launch() context = browser.new_context() page = context.new_page() page.goto("https://example.com") page.screenshot(path="screenshot.png") browser.close() with sync_playwright() as playwright: run(playwright) ``` ```csharp using Microsoft.Playwright; using System.Threading.Tasks; class PageExamples { public static async Task Run() { using var playwright = await Playwright.CreateAsync(); await using var browser = await playwright.Webkit.LaunchAsync(); var page = await browser.NewPageAsync(); await page.GotoAsync("https://www.theverge.com"); await page.ScreenshotAsync(new() { Path = "theverge.png" }); } } ``` -------------------------------- ### List supported browsers using Node.js CLI Source: https://github.com/microsoft/playwright/blob/main/docs/src/browsers.md Run the install command with the --help flag to view all supported browser installation options. ```bash npx playwright install --help ``` -------------------------------- ### Disposable.close Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-disposable.md Removes the associated resource in Python. For example, removes an init script installed via Page.addInitScript or BrowserContext.addInitScript. ```APIDOC ## async method: Disposable.close() * **Languages:** Python * **Since:** v1.59 ### Description Removes the associated resource. For example, removes the init script installed via `Page.addInitScript` or `BrowserContext.addInitScript`. ``` -------------------------------- ### Install skills globally across projects Source: https://github.com/microsoft/playwright/blob/main/docs/src/getting-started-cli.md Installs skills into the home directory (~/.claude/skills or ~/.agents/skills) to share them across all projects. ```bash playwright-cli install --skills -g ``` -------------------------------- ### Disposable.dispose Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-disposable.md Removes the associated resource in JavaScript. For example, removes an init script installed via Page.addInitScript or BrowserContext.addInitScript. ```APIDOC ## async method: Disposable.dispose() * **Languages:** JavaScript * **Since:** v1.59 ### Description Removes the associated resource. For example, removes the init script installed via `Page.addInitScript` or `BrowserContext.addInitScript`. ``` -------------------------------- ### Quick start with playwright-cli Source: https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/tools/skills/playwright-cli/SKILL.md Demonstrates opening a browser, navigating to a page, interacting with elements using snapshot references, taking a screenshot, and closing the browser. ```bash # open new browser playwright-cli open # navigate to a page playwright-cli goto https://playwright.dev # interact with the page using refs from the snapshot playwright-cli click e15 playwright-cli type "page.click" playwright-cli press Enter # take a screenshot (rarely used, as snapshot is more common) playwright-cli screenshot # close the browser playwright-cli close ``` -------------------------------- ### Start seed test and attach playwright-cli Source: https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/tools/skills/playwright-cli/references/test-generation.md Starts the Playwright test seed in background debug mode and attaches playwright-cli to the active session. Always run scenarios sequentially through the test seed to preserve setup state. ```bash PLAYWRIGHT_HTML_OPEN=never npx playwright test --debug=cli # background playwright-cli attach tw-XXXX # resume ``` -------------------------------- ### Example file structure for snapshot path tokens Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/params.md Shows a typical project layout with a config file and a test file, used to illustrate how tokens like {testFilePath} and {testFileDir} are resolved. ```text playwright.config.ts tests/ └── page/ └── page-click.spec.ts ``` -------------------------------- ### Install browsers in CI configuration Source: https://github.com/microsoft/playwright/blob/main/docs/src/release-notes-js.md Run `npx playwright install --with-deps` after `npm ci` to explicitly download browsers in CI pipelines. This migration is recommended starting in Playwright v1.38 when using the `playwright` package. ```yml - run: npm ci - run: npx playwright install --with-deps ``` -------------------------------- ### async method: Credentials.install Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-credentials.md Installs the virtual WebAuthn authenticator into the context, overriding navigator.credentials.create() and navigator.credentials.get() in all current and future pages. Must be called before the page first touches navigator.credentials; until then no interception is in place and the page sees the platform's native (or absent) WebAuthn behaviour. ```APIDOC ## async method: Credentials.install ### Description Installs the virtual WebAuthn authenticator into the context, overriding `navigator.credentials.create()` and `navigator.credentials.get()` in all current and future pages. Call this before the page first touches `navigator.credentials`. Required: until `Credentials.install` is called, no interception is in place and the page sees the platform's native (or absent) WebAuthn behaviour. Seeding credentials with `Credentials.create` without installing populates the authenticator, but the page will never see those credentials. ### Method async method: Credentials.install ### Since v1.61 ### Parameters None documented. ### Returns None documented. ``` -------------------------------- ### Convert FrameLocator to Locator with FrameLocator.Owner Source: https://github.com/microsoft/playwright/blob/main/docs/src/release-notes-csharp.md Use FrameLocator.Owner to get the iframe element as a Locator. The example checks that the iframe is visible. ```csharp var frameLocator = page.FrameLocator("iframe[name='embedded']"); // ... var locator = frameLocator.Owner; await Expect(locator).ToBeVisibleAsync(); ``` -------------------------------- ### List supported browsers using Java CLI Source: https://github.com/microsoft/playwright/blob/main/docs/src/browsers.md Pass the --help flag via Maven CLI execution to view all supported browser installation options. ```bash mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --help" ``` -------------------------------- ### Browser.disconnected Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browser.md Event emitted when the Browser gets disconnected from the browser application, for example because the browser application closed or crashed, or because Browser.close was called. ```APIDOC ## event: Browser.disconnected ### Description Emitted when Browser gets disconnected from the browser application. This might happen because of one of the following: - Browser application is closed or crashed. - The `Browser.close` method was called. ### Event Browser.disconnected ### Parameters - **browser** (Browser) - The browser that was disconnected. ### Since v1.8 ``` -------------------------------- ### Record trace in NUnit using BrowserContext.Tracing Source: https://github.com/microsoft/playwright/blob/main/docs/src/trace-viewer-intro-csharp.md Start tracing in the SetUp hook with screenshots, snapshots, and sources enabled, and save the trace file in TearDown. ```csharp namespace PlaywrightTests; [Parallelizable(ParallelScope.Self)] [TestFixture] public class Tests : PageTest { [SetUp] public async Task Setup() { await Context.Tracing.StartAsync(new() { Title = $"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}", Screenshots = true, Snapshots = true, Sources = true }); } [TearDown] public async Task TearDown() { await Context.Tracing.StopAsync(new() { Path = Path.Combine( TestContext.CurrentContext.WorkDirectory, "playwright-traces", $"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}.zip" ) }); } [Test] public async Task GetStartedLink() { // .. } } ``` -------------------------------- ### Default Playwright project scaffold Source: https://github.com/microsoft/playwright/blob/main/docs/src/intro-js.md Displays the files and directories created by Playwright upon installation, including the central configuration file and example tests. ```bash playwright.config.ts # Test configuration package.json package-lock.json # Or yarn.lock / pnpm-lock.yaml tests/ example.spec.ts # Minimal example test ``` -------------------------------- ### Setup and teardown with autouse fixtures in test_example.py Source: https://github.com/microsoft/playwright/blob/main/docs/src/writing-tests-python.md Defines a function-scoped autouse fixture that runs setup before each test and teardown after each test. ```python import pytest from playwright.sync_api import Page, expect @pytest.fixture(scope="function", autouse=True) def before_each_after_each(page: Page): print("before the test runs") # Go to the starting url before each test. page.goto("https://playwright.dev/") yield print("after the test runs") def test_main_navigation(page: Page): # Assertions use the expect API. expect(page).to_have_url("https://playwright.dev/") ``` -------------------------------- ### Iterate all matching elements with Locator.all Source: https://github.com/microsoft/playwright/blob/main/docs/src/release-notes-python.md Use Locator.all to get every element matching a locator and act on each one. The example checks all checkboxes returned by get_by_role. ```python # Check all checkboxes! checkboxes = page.get_by_role("checkbox") for checkbox in checkboxes.all(): checkbox.check() ``` -------------------------------- ### Authenticate multiple roles in setup and apply via test.use Source: https://github.com/microsoft/playwright/blob/main/docs/src/auth.md Use when you have multiple roles across tests and accounts can be reused. Authenticate each role in the setup project to generate storage state JSON files, then set storageState on test files or describe blocks instead of the global config. ```javascript import { test as setup, expect } from '@playwright/test'; const adminFile = 'playwright/.auth/admin.json'; setup('authenticate as admin', async ({ page }) => { // Perform authentication steps. Replace these actions with your own. await page.goto('https://github.com/login'); await page.getByLabel('Username or email address').fill('admin'); await page.getByLabel('Password').fill('password'); await page.getByRole('button', { name: 'Sign in' }).click(); // Wait until the page receives the cookies. // // Sometimes login flow sets cookies in the process of several redirects. // Wait for the final URL to ensure that the cookies are actually set. await page.waitForURL('https://github.com/'); // Alternatively, you can wait until the page reaches a state where all cookies are set. await expect(page.getByRole('button', { name: 'View profile and more' })).toBeVisible(); // End of authentication steps. await page.context().storageState({ path: adminFile }); }); const userFile = 'playwright/.auth/user.json'; setup('authenticate as user', async ({ page }) => { // Perform authentication steps. Replace these actions with your own. await page.goto('https://github.com/login'); await page.getByLabel('Username or email address').fill('user'); await page.getByLabel('Password').fill('password'); await page.getByRole('button', { name: 'Sign in' }).click(); // Wait until the page receives the cookies. // // Sometimes login flow sets cookies in the process of several redirects. // Wait for the final URL to ensure that the cookies are actually set. await page.waitForURL('https://github.com/'); // Alternatively, you can wait until the page reaches a state where all cookies are set. await expect(page.getByRole('button', { name: 'View profile and more' })).toBeVisible(); // End of authentication steps. await page.context().storageState({ path: userFile }); }); ``` ```javascript import { test } from '@playwright/test'; test.use({ storageState: 'playwright/.auth/admin.json' }); test('admin test', async ({ page }) => { // page is authenticated as admin }); test.describe(() => { test.use({ storageState: 'playwright/.auth/user.json' }); test('user test', async ({ page }) => { // page is authenticated as a user }); }); ``` -------------------------------- ### Set up and tear down repositories with beforeAll and afterAll Source: https://github.com/microsoft/playwright/blob/main/docs/src/api-testing-js.md Creates a repository before running tests and deletes it afterwards using test.beforeAll and test.afterAll hooks with the request fixture. ```javascript test.beforeAll(async ({ request }) => { // Create a new repository const response = await request.post('/user/repos', { data: { name: REPO } }); expect(response.ok()).toBeTruthy(); }); test.afterAll(async ({ request }) => { // Delete the repository const response = await request.delete(`/repos/${USER}/${REPO}`); expect(response.ok()).toBeTruthy(); }); ``` -------------------------------- ### Capture ARIA snapshot of a link element Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-locator.md Use ariaSnapshot() on a locator to get the ARIA snapshot of the matched element. The example uses getByRole to locate a link. ```javascript await page.getByRole('link').ariaSnapshot(); ``` ```java page.getByRole(AriaRole.LINK).ariaSnapshot(); ``` ```python await page.get_by_role("link").aria_snapshot() ``` ```python page.get_by_role("link").aria_snapshot() ``` ```csharp await page.GetByRole(AriaRole.Link).AriaSnapshotAsync(); ``` -------------------------------- ### Set up WebView2Test base class and example test in C# Source: https://github.com/microsoft/playwright/blob/main/docs/src/webview2.md Defines a custom Playwright test fixture that launches the WebView2 executable with CDP debugging enabled and connects to it, followed by an example test class inheriting from it. Use this setup to automate and assert against WebView2 desktop applications in .NET. ```csharp using System.Diagnostics; using Microsoft.Playwright; using Microsoft.Playwright.Xunit.v3; namespace PlaywrightTests; public class WebView2Test : PlaywrightTest { public IBrowser Browser { get; internal set; } = null!; public IBrowserContext Context { get; internal set; } = null!; public IPage Page { get; internal set; } = null!; private Process? _webView2Process = null; private string _userDataDir = null!; private string _executablePath = Path.Join(Directory.GetCurrentDirectory(), @"..\..\..\..\webview2-app\bin\Debug\net8.0-windows\webview2.exe"); public override async Task InitializeAsync() { await base.InitializeAsync(); var cdpPort = 10000 + WorkerIndex; Assert.True(File.Exists(_executablePath), "Make sure that the executable exists"); _userDataDir = Path.Join(Path.GetTempPath(), $"playwright-webview2-tests/user-data-dir-{WorkerIndex}"); // WebView2 does some lazy cleanups on shutdown so we can't clean it up after each test if (Directory.Exists(_userDataDir)) { Directory.Delete(_userDataDir, true); } _webView2Process = Process.Start(new ProcessStartInfo(_executablePath) { EnvironmentVariables = { ["WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS"] = $"--remote-debugging-port={cdpPort}", ["WEBVIEW2_USER_DATA_FOLDER"] = _userDataDir, }, RedirectStandardOutput = true, }); while (!_webView2Process!.HasExited) { var output = await _webView2Process!.StandardOutput.ReadLineAsync(); if (_webView2Process!.HasExited) { throw new Exception("WebView2 process exited unexpectedly"); } if (output != null && output.Contains("WebView2 initialized")) { break; } } var cdpAddress = $"http://127.0.0.1:{cdpPort}"; Browser = await Playwright.Chromium.ConnectOverCDPAsync(cdpAddress); Context = Browser.Contexts[0]; Page = Context.Pages[0]; } public override async Task DisposeAsync() { _webView2Process!.Kill(true); await Browser.CloseAsync(); await base.DisposeAsync(); } } ``` ```csharp using Microsoft.Playwright; using Microsoft.Playwright.Xunit.v3; namespace PlaywrightTests; public class ExampleTest : WebView2Test { [Fact] public async Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage() { await Page.GotoAsync("https://playwright.dev"); var getStarted = Page.GetByText("Get Started"); await Expect(getStarted).ToBeVisibleAsync(); } } ``` -------------------------------- ### Credentials.InstallAsync Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-credentials.md Installs the created credentials into the browser context, making them available for passkey authentication flows such as navigator.credentials.get(). ```APIDOC ## Credentials.InstallAsync ### Description Installs the credentials created via `Credentials.CreateAsync()` into the browser context. After installation, the virtual authenticator is active and passkey operations will resolve using the installed credentials. ### Method `InstallAsync` ### Parameters None. ### Example ```csharp await context.Credentials.InstallAsync(); ``` ``` -------------------------------- ### Set viewport size in Python (async) Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md Creates a new page, sets its viewport to 640x480, and navigates to example.com. Use this to ensure the page loads with the desired viewport size. ```python page = await browser.new_page() await page.set_viewport_size({"width": 640, "height": 480}) await page.goto("https://example.com") ``` -------------------------------- ### Record user actions and generate tests with playwright codegen Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-cli-js.md Examples demonstrating how to start recording with the interactive UI, target a specific URL, and generate test code for Python. ```bash # Start recording with interactive UI npx playwright codegen # Record on specific site npx playwright codegen https://playwright.dev # Generate Python code npx playwright codegen --target=python ``` -------------------------------- ### List supported browsers using PowerShell (.NET) Source: https://github.com/microsoft/playwright/blob/main/docs/src/browsers.md Run the PowerShell install script with the --help flag to view all supported browser installation options. ```bash pwsh bin/Debug/netX/playwright.ps1 install --help ``` -------------------------------- ### Get FrameLocator from Locator using ContentFrame in C# Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-locator.md Use when you have a Locator for an iframe and need to interact with its content. The example locates an iframe by name and clicks a button inside the frame. ```csharp var locator = Page.Locator("iframe[name=\"embedded\"]"); // ... var frameLocator = locator.ContentFrame; await frameLocator.GetByRole(AriaRole.Button).ClickAsync(); ``` -------------------------------- ### Capture a credential and save to file in JavaScript Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-credentials.md In a setup test, let the app register a passkey, then read it back with context.credentials.get() and save it to a JSON file for reuse. ```javascript // setup test: let the app register a passkey, then save the storage state with it. const context = await browser.newContext(); await context.credentials.install(); const page = await context.newPage(); await page.goto('https://example.com/register'); await page.getByRole('button', { name: 'Create a passkey' }).click(); // Read back the passkey the page registered — it includes the private key. const [credential] = await context.credentials.get({ rpId: 'example.com' }); fs.writeFileSync('playwright/.auth/passkey.json', JSON.stringify(credential)); ``` -------------------------------- ### Get FrameLocator from Locator using contentFrame in Java Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-locator.md Use when you have a Locator for an iframe and need to interact with its content. The example locates an iframe by name and clicks a button inside the frame. ```java Locator locator = page.locator("iframe[name=\"embedded\"]"); // ... FrameLocator frameLocator = locator.contentFrame(); frameLocator.getByRole(AriaRole.BUTTON).click(); ``` -------------------------------- ### Set viewport size in Python (sync) Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md Creates a new page, sets its viewport to 640x480, and navigates to example.com. Use this to ensure the page loads with the desired viewport size. ```python page = browser.new_page() page.set_viewport_size({"width": 640, "height": 480}) page.goto("https://example.com") ``` -------------------------------- ### Get FrameLocator from Locator using contentFrame in JavaScript Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-locator.md Use when you have a Locator for an iframe and need to interact with its content. The example locates an iframe by name and clicks a button inside the frame. ```javascript const locator = page.locator('iframe[name="embedded"]'); // ... const frameLocator = locator.contentFrame(); await frameLocator.getByRole('button').click(); ``` -------------------------------- ### Wait for download event in JavaScript Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md Start waiting for the 'download' event before clicking, then await the promise to get the download object. Note that `page.waitForEvent` returns a promise that resolves with the event data. ```javascript // Start waiting for download before clicking. Note no await. const downloadPromise = page.waitForEvent('download'); await page.getByText('Download file').click(); const download = await downloadPromise; ``` -------------------------------- ### Install default browsers using Node.js CLI Source: https://github.com/microsoft/playwright/blob/main/docs/src/browsers.md Run the install command without arguments to download the default set of supported browser binaries. ```bash npx playwright install ``` -------------------------------- ### Record trace in NUnit using BrowserContext.Tracing Source: https://github.com/microsoft/playwright/blob/main/docs/src/trace-viewer.md Configures trace recording in NUnit using [SetUp] to start tracing with screenshots, snapshots, and sources, and [TearDown] to save the resulting zip archive. ```csharp namespace PlaywrightTests; [Parallelizable(ParallelScope.Self)] [TestFixture] public class Tests : PageTest { [SetUp] public async Task Setup() { await Context.Tracing.StartAsync(new() { Title = TestContext.CurrentContext.Test.ClassName + "." + TestContext.CurrentContext.Test.Name, Screenshots = true, Snapshots = true, Sources = true }); } [TearDown] public async Task TearDown() { // This will produce e.g.: // bin/Debug/net8.0/playwright-traces/PlaywrightTests.Tests.Test1.zip await Context.Tracing.StopAsync(new() { Path = Path.Combine( TestContext.CurrentContext.WorkDirectory, "playwright-traces", $"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}.zip" ) }); } [Test] public async Task TestYourOnlineShop() { // .. } } ``` -------------------------------- ### Managing setup and teardown without fixtures using hooks and Page Object Model Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-fixtures-js.md Illustrates the traditional approach to test environment setup using `beforeEach` and `afterEach` lifecycle hooks with a `TodoPage` Page Object Model class (`todo-page.ts` and `todo.spec.ts`). ```javascript import type { Page, Locator } from '@playwright/test'; export class TodoPage { private readonly inputBox: Locator; private readonly todoItems: Locator; constructor(public readonly page: Page) { this.inputBox = this.page.locator('input.new-todo'); this.todoItems = this.page.getByTestId('todo-item'); } async goto() { await this.page.goto('https://demo.playwright.dev/todomvc/'); } async addToDo(text: string) { await this.inputBox.fill(text); await this.inputBox.press('Enter'); } async remove(text: string) { const todo = this.todoItems.filter({ hasText: text }); await todo.hover(); await todo.getByLabel('Delete').click(); } async removeAll() { while ((await this.todoItems.count()) > 0) { await this.todoItems.first().hover(); await this.todoItems.getByLabel('Delete').first().click(); } } } ``` ```javascript const { test } = require('@playwright/test'); const { TodoPage } = require('./todo-page'); test.describe('todo tests', () => { let todoPage; test.beforeEach(async ({ page }) => { todoPage = new TodoPage(page); await todoPage.goto(); await todoPage.addToDo('item1'); await todoPage.addToDo('item2'); }); test.afterEach(async () => { await todoPage.removeAll(); }); test('should add an item', async () => { await todoPage.addToDo('my item'); // ... }); test('should remove an item', async () => { await todoPage.remove('item1'); // ... }); }); ``` -------------------------------- ### Seed a captured passkey with Credentials in JavaScript Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-credentials.md Reads the saved passkey from playwright/.auth/passkey.json, creates it in the context, and installs credentials so navigator.credentials.get() resolves the captured passkey and the app starts already signed in. ```javascript // later test: seed the captured passkey so the app starts already enrolled. const credential = JSON.parse(fs.readFileSync('playwright/.auth/passkey.json', 'utf8')); const context = await browser.newContext(); await context.credentials.create(credential.rpId, credential); await context.credentials.install(); const page = await context.newPage(); await page.goto('https://example.com/login'); // navigator.credentials.get() resolves the captured passkey — already signed in. ``` -------------------------------- ### Credentials.install Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-credentials.md Installs the virtual authenticator into the browser context. After installation, the page's WebAuthn API calls (navigator.credentials.create() and navigator.credentials.get()) will be handled by the virtual authenticator using the stored credentials. ```APIDOC ## Credentials.install ### Description Installs the virtual authenticator into the browser context. Once installed, WebAuthn ceremonies in the page will be answered using the credentials managed by this instance. ### Method `install` ### Parameters None. ### Returns - Promise - Resolves when the authenticator is installed. ### Example ```js await context.credentials.install(); ``` ``` -------------------------------- ### Wait for Worker using expect_worker in Python sync Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md Use this sync context manager to wait for a Worker event. The example clicks a 'Start worker' button and then prints the worker URL. ```python with page.expect_worker() as worker_info: page.get_by_text("Start worker").click() worker = worker_info.value print(worker.url) ``` -------------------------------- ### Wait for Worker using expect_worker in Python async Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md Use this async context manager to wait for a Worker event. The example clicks a 'Start worker' button and then prints the worker URL. ```python async with page.expect_worker() as worker_info: await page.get_by_text("Start worker").click() worker = await worker_info.value print(worker.url) ``` -------------------------------- ### Get FrameLocator from Locator using content_frame in Python sync Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-locator.md Use when you have a Locator for an iframe and need to interact with its content. The example locates an iframe by name and clicks a button inside the frame. ```python locator = page.locator("iframe[name=\"embedded\"]") # ... frame_locator = locator.content_frame frame_locator.get_by_role("button").click() ``` -------------------------------- ### Create context, resize viewport, and emulate high-DPI (Python async) Source: https://github.com/microsoft/playwright/blob/main/docs/src/emulation.md Creates a context with a 1280x1024 viewport, resizes an individual page to 1600x1200, and creates a high-DPI context with a 2560x1440 viewport and device_scale_factor 2 using the async API. ```python # Create context with given viewport context = await browser.new_context( viewport={ 'width': 1280, 'height': 1024 } ) # Resize viewport for individual page await page.set_viewport_size({"width": 1600, "height": 1200}) # Emulate high-DPI context = await browser.new_context( viewport={ 'width': 2560, 'height': 1440 }, device_scale_factor=2, ) ``` -------------------------------- ### Get FrameLocator from Locator using content_frame in Python async Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-locator.md Use when you have a Locator for an iframe and need to interact with its content. The example locates an iframe by name and clicks a button inside the frame. ```python locator = page.locator("iframe[name=\"embedded\"]") # ... frame_locator = locator.content_frame await frame_locator.get_by_role("button").click() ``` -------------------------------- ### BrowserType.LaunchAsync(options) Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/params.md Launches a new browser instance using the specified launch options. Returns a Browser instance that can be used to create pages and contexts. ```APIDOC ## BrowserType.LaunchAsync(options) ### Description Launches a new browser instance with the given launch options. Returns a `Browser` instance that can be used to create pages and contexts. ### Method `Task LaunchAsync(BrowserTypeLaunchOptions options)` ### Parameters #### Options - **Headless** (bool) - Optional - Whether to run the browser in headless mode. Defaults to `true`. - **HandleSIGTERM** (bool) - Optional - Close the browser process on SIGTERM. Defaults to `true`. - **HandleSIGHUP** (bool) - Optional - Close the browser process on SIGHUP. Defaults to `true`. - **FirefoxUserPrefs** (IDictionary) - Optional - Firefox user preferences. Learn more at `about:config`. You can also provide a path to a custom `policies.json` file via the `PLAYWRIGHT_FIREFOX_POLICIES_JSON` environment variable. - **Logger** (ILogger) - Optional - Logger sink for Playwright logging. Deprecated: the logs received by the logger are incomplete; use tracing instead. ### Returns - **IBrowser** - The launched browser instance. ### Example ```csharp using Microsoft.Playwright; using var playwright = await Playwright.CreateAsync(); var browser = await playwright.Chromium.LaunchAsync(new() { Headless = true, HandleSIGTERM = true, HandleSIGHUP = true }); ``` ``` -------------------------------- ### Start Playwright Server in Docker Source: https://github.com/microsoft/playwright/blob/main/docs/src/docker.md Runs Playwright Server inside a Docker container listening on port 3000. Useful for executing tests against unsupported Linux distributions or remote execution setups. ```bash docker run -p 3000:3000 --rm --init -it --workdir /home/pwuser --user pwuser mcr.microsoft.com/playwright:v%%VERSION%%-noble /bin/sh -c "npx -y playwright@%%VERSION%% run-server --port 3000 --host 0.0.0.0" ``` -------------------------------- ### Set viewport size in Java Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md Creates a new page, sets its viewport to 640x480, and navigates to example.com. Use this to ensure the page loads with the desired viewport size. ```java Page page = browser.newPage(); page.setViewportSize(640, 480); page.navigate("https://example.com"); ``` -------------------------------- ### Record Playwright trace on test failure in NUnit Source: https://github.com/microsoft/playwright/blob/main/docs/src/trace-viewer.md Configures NUnit setup and teardown methods to start tracing and save the resulting trace zip file only if the test outcome resulted in Error or Failure. ```csharp namespace PlaywrightTests; [Parallelizable(ParallelScope.Self)] [TestFixture] public class ExampleTest : PageTest { [SetUp] public async Task Setup() { await Context.Tracing.StartAsync(new() { Title = $"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}", Screenshots = true, Snapshots = true, Sources = true }); } [TearDown] public async Task TearDown() { var failed = TestContext.CurrentContext.Result.Outcome == NUnit.Framework.Interfaces.ResultState.Error || TestContext.CurrentContext.Result.Outcome == NUnit.Framework.Interfaces.ResultState.Failure; await Context.Tracing.StopAsync(new() { Path = failed ? Path.Combine( TestContext.CurrentContext.WorkDirectory, "playwright-traces", $"{TestContext.CurrentContext.Test.ClassName}.{TestContext.CurrentContext.Test.Name}.zip" ) : null, }); } [Test] public async Task GetStartedLink() { // .. } } ``` -------------------------------- ### Seed and install a WebAuthn passkey with BrowserContext.credentials Source: https://github.com/microsoft/playwright/blob/main/docs/src/release-notes-java.md Use the Credentials virtual authenticator to register passkeys and answer navigator.credentials.create()/get() ceremonies without real hardware, in all browsers. Seed a passkey your backend provisioned for a test user, then call install() before navigating. ```java BrowserContext context = browser.newContext(); // Seed a passkey your backend provisioned for a test user. context.credentials().create("example.com", new Credentials.CreateOptions() .setId(credentialId) .setUserHandle(userHandle) .setPrivateKey(privateKey) .setPublicKey(publicKey)); context.credentials().install(); Page page = context.newPage(); page.navigate("https://example.com/login"); // The page's navigator.credentials.get() is answered with the seeded passkey. ``` -------------------------------- ### TestInfo.SnapshotSuffix Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-api/class-testinfo.md Gets or sets the suffix used to differentiate snapshots between multiple test configurations. For example, setting it to the platform name allows platform-specific snapshots. Note that using this property is discouraged in favor of TestConfig.SnapshotPathTemplate. ```APIDOC ## TestInfo.SnapshotSuffix ### Description Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on the platform, you can set `testInfo.SnapshotSuffix` equal to the platform name. In this case `Expect(value).ToMatchSnapshot(snapshotName)` will use different snapshots depending on the platform. :::note Use of `TestInfo.SnapshotSuffix` is discouraged. Please use `TestConfig.SnapshotPathTemplate` to configure snapshot paths. ::: ### Type - **string** ### Since v1.10 ``` -------------------------------- ### fullProject.use Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-api/class-fullproject.md Fixtures and options configured for all tests within the project, such as browser options and context settings. ```APIDOC ### Property `fullProject.use` ### Type - `Fixtures` ### Description Fixture configuration options for this project. See `TestProject.use`. ``` -------------------------------- ### TestInfo.workerIndex Source: https://github.com/microsoft/playwright/blob/main/docs/src/test-api/class-testinfo.md The unique index of the worker process running the test. When a worker is restarted, for example after a failure, the new worker process gets a new unique workerIndex. Also available as process.env.TEST_WORKER_INDEX. Available since v1.10. ```APIDOC ## TestInfo.workerIndex ### Description The unique index of the worker process that is running the test. When a worker is restarted, for example after a failure, the new worker process gets a new unique `workerIndex`. Also available as `process.env.TEST_WORKER_INDEX`. ### Type - `int` ### Since - v1.10 ``` -------------------------------- ### BrowserType.launch Source: https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsertype.md Launches a new browser instance with optional configuration settings such as ignoring default arguments, setting custom preferences, or throttling execution. ```APIDOC ## BrowserType.launch ### Description Returns the browser instance. ### Returns - **Browser** - The launched browser instance. ### Options - **executablePath** - Optional path to a browser executable to run instead of the bundled browser. - **firefoxUserPrefs** - Optional Firefox user preferences (JS/Python). - **firefoxUserPrefs2** - Optional Firefox user preferences (C#/Java). - **logger** - Optional logger sink. - **slowMo** - Optional slow-down factor for Playwright operations. - **ignoreDefaultArgs** - Optional list of default arguments to filter out or ignore. - **ignoreAllDefaultArgs** - Optional flag to ignore all default arguments. ### Usage Example ```js const browser = await chromium.launch({ ignoreDefaultArgs: ['--mute-audio'] }); ``` ```java Browser browser = chromium.launch(new BrowserType.LaunchOptions() .setIgnoreDefaultArgs(Arrays.asList("--mute-audio"))); ``` ```python browser = await playwright.chromium.launch( ignore_default_args=["--mute-audio"] ) ``` ```csharp var browser = await playwright.Chromium.LaunchAsync(new() { IgnoreDefaultArgs = new[] { "--mute-audio" } }); ``` ### Since v1.8 ``` -------------------------------- ### Seed and install a WebAuthn passkey Source: https://github.com/microsoft/playwright/blob/main/docs/src/release-notes-python.md Create a Credentials virtual authenticator via BrowserContext.Credentials, seed a passkey provisioned for a test user, and install it. The page's navigator.credentials.get() is then answered with the seeded passkey. ```csharp var context = await browser.NewContextAsync(); // Seed a passkey your backend provisioned for a test user. await context.Credentials.CreateAsync("example.com", id: credentialId, userHandle: userHandle, privateKey: privateKey, publicKey: publicKey ); await context.Credentials.InstallAsync(); var page = await context.NewPageAsync(); await page.GotoAsync("https://example.com/login"); // The page's navigator.credentials.get() is answered with the seeded passkey. ```