### Run TodoMVC Example with Wrangler Source: https://github.com/cloudflare/playwright/blob/main/README.md Navigate to the example directory, install dependencies, and start the development server with `wrangler dev --remote`. Press 'b' to open the browser. ```sh cd packages/playwright-cloudflare/examples/todomvc npm ci npx wrangler dev --remote ``` -------------------------------- ### Install Dependencies and Start Development Server Source: https://github.com/cloudflare/playwright/blob/main/tests/components/ct-svelte/README.md Install project dependencies using npm and start the development server to see your Svelte app in action. Changes are reflected on hot reload. ```bash cd svelte-app npm install ``` ```bash npm run dev ``` -------------------------------- ### Install Dependencies and Watch Mode Source: https://github.com/cloudflare/playwright/blob/main/CONTRIBUTING.md Install project dependencies and start the build in watch mode for continuous development. Also installs Playwright browsers. ```bash npm ci npm run watch npx playwright install ``` -------------------------------- ### Clock.install Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api/class-clock.md Installs the clock with a specific starting time. Time will progress naturally as timers fire. ```APIDOC ## async method: Clock.install * since: v1.45 Installs the clock with a specific starting time. Time will progress naturally as timers fire. **Usage** ```js await page.clock.install(time=datetime.datetime(2024, 12, 10, 8, 0, 0)) await page.goto("http://localhost:3333") await page.clock.pause_at(datetime.datetime(2024, 12, 10, 10, 0, 0)) ``` ```python sync # 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, 12, 10, 8, 0, 0)) page.goto("http://localhost:3333") page.clock.pause_at(datetime.datetime(2024, 12, 10, 10, 0, 0)) ``` ```java // Initialize clock with some time before the test time and let the page load // naturally. `Date.now` will progress as the timers fire. SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd'T'HH:mm:ss"); page.clock().install(new Clock.InstallOptions().setTime(format.parse("2024-12-10T08:00:00"))); page.navigate("http://localhost:3333"); page.clock().pauseAt(format.parse("2024-12-10T10:00:00")); ``` ### param: Clock.install.time * langs: js, python, java * since: v1.45 - `time` <[long]|[string]|[Date]|[float]> Time to install. For example, `new Date(2020, 7, 20)`. ``` -------------------------------- ### Global Setup with Trace Capture on Failure Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-global-setup-teardown-js.md Capture traces of failures during global setup by starting tracing before potential errors and stopping it in a `catch` block. ```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; ``` -------------------------------- ### Listing Installed Browsers with Maven Source: https://github.com/cloudflare/playwright/blob/main/docs/src/release-notes-java.md Illustrates how to use the `install --list` command with Maven to display all installed browsers, their versions, and locations. ```bash mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --list" ``` -------------------------------- ### Complete API Test Example in C# Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api-testing-csharp.md This example shows a full test class for API testing GitHub issues. It includes setup, test methods for creating bug reports and feature requests, and cleanup logic. Ensure GITHUB_USER and GITHUB_API_TOKEN environment variables are set. ```csharp using System.Text.Json; using Microsoft.Playwright; using Microsoft.Playwright.MSTest; namespace PlaywrightTests; [TestClass] public class TestGitHubAPI : PlaywrightTest { static string REPO = "test-repo-2"; static string USER = Environment.GetEnvironmentVariable("GITHUB_USER"); static string? API_TOKEN = Environment.GetEnvironmentVariable("GITHUB_API_TOKEN"); private IAPIRequestContext Request = null!; [TestMethod] public async Task ShouldCreateBugReport() { var data = new Dictionary { { "title", "[Bug] report 1" }, { "body", "Bug description" } }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); await Expect(newIssue).ToBeOKAsync(); var issues = await Request.GetAsync("/repos/" + USER + "/" + REPO + "/issues"); await Expect(newIssue).ToBeOKAsync(); var issuesJsonResponse = await issues.JsonAsync(); JsonElement? issue = null; foreach (JsonElement issueObj in issuesJsonResponse?.EnumerateArray()) { if (issueObj.TryGetProperty("title", out var title) == true) { if (title.GetString() == "[Bug] report 1") { issue = issueObj; } } } Assert.IsNotNull(issue); Assert.AreEqual("Bug description", issue?.GetProperty("body").GetString()); } [TestMethod] public async Task ShouldCreateFeatureRequests() { var data = new Dictionary { { "title", "[Feature] request 1" }, { "body", "Feature description" } }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); await Expect(newIssue).ToBeOKAsync(); var issues = await Request.GetAsync("/repos/" + USER + "/" + REPO + "/issues"); await Expect(newIssue).ToBeOKAsync(); var issuesJsonResponse = await issues.JsonAsync(); JsonElement? issue = null; foreach (JsonElement issueObj in issuesJsonResponse?.EnumerateArray()) { if (issueObj.TryGetProperty("title", out var title) == true) { if (title.GetString() == "[Feature] request 1") { issue = issueObj; } } } Assert.IsNotNull(issue); Assert.AreEqual("Feature description", issue?.GetProperty("body").GetString()); } [TestInitialize] public async Task SetUpAPITesting() { await CreateAPIRequestContext(); await CreateTestRepository(); } private async Task CreateAPIRequestContext() { var headers = new Dictionary { // We set this header per GitHub guidelines. { "Accept", "application/vnd.github.v3+json" }, // Add authorization token to all requests. // Assuming personal access token available in the environment. { "Authorization", "token " + API_TOKEN } }; Request = await Playwright.APIRequest.NewContextAsync(new() { // All requests we send go to this API endpoint. BaseURL = "https://api.github.com", ExtraHTTPHeaders = headers, }); } private async Task CreateTestRepository() { var resp = await Request.PostAsync("/user/repos", new() { DataObject = new Dictionary() { ["name"] = REPO, }, }); await Expect(resp).ToBeOKAsync(); } [TestCleanup] public async Task TearDownAPITesting() { await DeleteTestRepository(); await Request.DisposeAsync(); } private async Task DeleteTestRepository() { var resp = await Request.DeleteAsync("/repos/" + USER + "/" + REPO); await Expect(resp).ToBeOKAsync(); } } ``` -------------------------------- ### Install Dependencies Source: https://github.com/cloudflare/playwright/blob/main/packages/playwright-cloudflare/examples/todomvc/README.md Run this command to install the necessary project dependencies. ```bash npm ci ``` -------------------------------- ### Start Development Server Source: https://github.com/cloudflare/playwright/blob/main/tests/components/ct-vue-cli/README.md Use this command to compile the project and start a hot-reloading development server. ```bash npm run serve ``` -------------------------------- ### NUnit Trace Recording Setup and Teardown Source: https://github.com/cloudflare/playwright/blob/main/docs/src/trace-viewer-intro-csharp.md Configure trace recording for NUnit tests. Ensure to import necessary namespaces and use the [SetUp] and [TearDown] attributes for starting and stopping tracing. ```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() { // .. } } ``` -------------------------------- ### Declare beforeAll hook with a title Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-test.md Declare a beforeAll hook with a title for setup operations. This example logs a message indicating the setup phase. ```js test.beforeAll('Setup', async () => { console.log('Before tests'); }); ``` -------------------------------- ### Define Setup and Teardown Projects Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-testproject.md Illustrates a common pattern for resource management where a 'setup' project acquires resources and a 'teardown' project cleans them up. Other projects depend on the 'setup'. ```typescript import { defineConfig } from '@playwright/test'; export default defineConfig({ projects: [ { name: 'setup', testMatch: /global.setup\.ts/, teardown: 'teardown', }, { name: 'teardown', testMatch: /global.teardown\.ts/, }, { name: 'chromium', use: devices['Desktop Chrome'], dependencies: ['setup'], }, { name: 'firefox', use: devices['Desktop Firefox'], dependencies: ['setup'], }, { name: 'webkit', use: devices['Desktop Safari'], dependencies: ['setup'], }, ], }); ``` -------------------------------- ### Install Project Dependencies Source: https://github.com/cloudflare/playwright/blob/main/tests/components/ct-vue-cli/README.md Run this command to install all necessary project dependencies after cloning the repository. ```bash npm install ``` -------------------------------- ### xUnit Trace Recording Setup and Teardown Source: https://github.com/cloudflare/playwright/blob/main/docs/src/trace-viewer-intro-csharp.md Set up trace recording for xUnit tests using the `WithTestNameAttribute`. Override `InitializeAsync` and `DisposeAsync` to manage trace start and stop operations. Ensure correct path construction for trace files. ```csharp using System.Reflection; using Microsoft.Playwright; using Microsoft.Playwright.Xunit; using Xunit.Sdk; namespace PlaywrightTests; [WithTestName] public class UnitTest1 : PageTest { public override async Task InitializeAsync() { await base.InitializeAsync().ConfigureAwait(false); await Context.Tracing.StartAsync(new() { Title = $"{WithTestNameAttribute.CurrentClassName}.{WithTestNameAttribute.CurrentTestName}", Screenshots = true, Snapshots = true, Sources = true }); } public override async Task DisposeAsync() { await Context.Tracing.StopAsync(new() { Path = Path.Combine( Environment.CurrentDirectory, "playwright-traces", $"{WithTestNameAttribute.CurrentClassName}.{WithTestNameAttribute.CurrentTestName}.zip" ) }); await base.DisposeAsync().ConfigureAwait(false); } [Fact] public async Task GetStartedLink() { // ... await Page.GotoAsync("https://playwright.dev/dotnet/docs/intro"); } } public class WithTestNameAttribute : BeforeAfterTestAttribute { public static string CurrentTestName = string.Empty; public static string CurrentClassName = string.Empty; public override void Before(MethodInfo methodInfo) { CurrentTestName = methodInfo.Name; CurrentClassName = methodInfo.DeclaringType!.Name; } public override void After(MethodInfo methodInfo) { } } ``` -------------------------------- ### Basic Test Setup with xUnit Source: https://github.com/cloudflare/playwright/blob/main/docs/src/writing-tests-csharp.md Example of a basic test class using Playwright with the xUnit test runner. Ensures test isolation by providing a separate Page instance for each test. ```csharp using Microsoft.Playwright; using Microsoft.Playwright.Xunit; namespace PlaywrightTests; public class UnitTest1: PageTest { [Fact] public async Task BasicTest() { await Page.GotoAsync("https://playwright.dev"); } } ``` -------------------------------- ### Install Browsers and Dependencies Source: https://github.com/cloudflare/playwright/blob/main/docs/src/browsers.md Installs both specified browsers and their system dependencies in a single command. ```js npx playwright install --with-deps chromium ``` ```java mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --with-deps chromium" ``` ```python playwright install --with-deps chromium ``` ```csharp pwsh bin/Debug/netX/playwright.ps1 install --with-deps chromium ``` -------------------------------- ### Install Azure CLI Source: https://github.com/cloudflare/playwright/blob/main/utils/flakiness-dashboard/README.md Installs the Azure Command Line Interface using Homebrew. ```bash brew update && brew install azure-cli ``` -------------------------------- ### Install Beta Firefox Source: https://github.com/cloudflare/playwright/blob/main/tests/bidi/README.md Install the beta channel of Firefox using the Puppeteer browser installer. ```sh npx -y @puppeteer/browsers install firefox@beta ``` -------------------------------- ### Basic Test Setup with xUnit v3 Source: https://github.com/cloudflare/playwright/blob/main/docs/src/writing-tests-csharp.md Example of a basic test class using Playwright with the xUnit v3 test runner. Ensures test isolation by providing a separate Page instance for each test. ```csharp using Microsoft.Playwright; using Microsoft.Playwright.Xunit.v3; namespace PlaywrightTests; public class UnitTest1: PageTest { [Fact] public async Task BasicTest() { await Page.GotoAsync("https://playwright.dev"); } } ``` -------------------------------- ### Install Default Browsers Source: https://github.com/cloudflare/playwright/blob/main/docs/src/browsers.md Installs the default set of supported browsers. Run this command after updating Playwright. ```js npx playwright install ``` ```java mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install" ``` ```python playwright install ``` ```csharp pwsh bin/Debug/netX/playwright.ps1 install ``` -------------------------------- ### Global setup test in tests/global.setup.ts Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-global-setup-teardown-js.md Define a setup test using `test as setup` to perform initialization tasks before other tests run. This code is executed as a regular test. ```js import { test as setup } from '@playwright/test'; setup('create new database', async ({ }) => { console.log('creating new database...'); // Initialize the database }); ``` -------------------------------- ### Using Playwright Assertions with Custom Timeout Source: https://github.com/cloudflare/playwright/blob/main/docs/src/library-csharp.md Demonstrates how to use Playwright's web-first assertions with a custom default timeout. This example checks for the visibility of a 'Get started' link. ```csharp using Microsoft.Playwright; using static Microsoft.Playwright.Assertions; // Change the default 5 seconds timeout if you'd like. SetDefaultExpectTimeout(10_000); using var playwright = await Playwright.CreateAsync(); await using var browser = await playwright.Chromium.LaunchAsync(); var page = await browser.NewPageAsync(); await page.GotoAsync("https://playwright.dev/dotnet"); await Expect(page.GetByRole(AriaRole.Link, new() { Name = "Get started" })).ToBeVisibleAsync(); ``` -------------------------------- ### Show Browser Install Help Source: https://github.com/cloudflare/playwright/blob/main/docs/src/browsers.md Displays help information for the 'install' command, including available browser options. ```js npx playwright install --help ``` ```java mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install --help" ``` ```python playwright install --help ``` ```csharp pwsh bin/Debug/netX/playwright.ps1 install --help ``` -------------------------------- ### FileChooser Usage Examples Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api/class-filechooser.md Examples of how to handle file choosers in different programming languages. ```APIDOC ## JavaScript Example ```js // Start waiting for file chooser before clicking. Note no await. const fileChooserPromise = page.waitForEvent('filechooser'); await page.getByText('Upload file').click(); const fileChooser = await fileChooserPromise; await fileChooser.setFiles(path.join(__dirname, 'myfile.pdf')); ``` ## Java Example ```java FileChooser fileChooser = page.waitForFileChooser(() -> page.getByText("Upload file").click()); fileChooser.setFiles(Paths.get("myfile.pdf")); ``` ## Python Async Example ```python async async with page.expect_file_chooser() as fc_info: await page.get_by_text("Upload file").click() file_chooser = await fc_info.value await file_chooser.set_files("myfile.pdf") ``` ## Python Sync Example ```python sync with page.expect_file_chooser() as fc_info: page.get_by_text("Upload file").click() file_chooser = fc_info.value file_chooser.set_files("myfile.pdf") ``` ## C# Example ```csharp var fileChooser = await page.RunAndWaitForFileChooserAsync(async () => { await page.GetByText("Upload file").ClickAsync(); }); await fileChooser.SetFilesAsync("temp.txt"); ``` ``` -------------------------------- ### Locator for 'Get Started' Link and Attribute Assertion Source: https://github.com/cloudflare/playwright/blob/main/docs/src/writing-tests-java.md Finds the 'Get Started' link using `getByRole` and asserts its `href` attribute. Requires importing `AriaRole`. ```java import com.microsoft.playwright.options.AriaRole; import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; // create a locator Locator getStarted = page.getByRole(AriaRole.LINK, new Page.GetByRoleOptions().setName("Get Started")); // Expect an attribute "to be strictly equal" to the value. assertThat(getStarted).hasAttribute("href", "/docs/intro"); // Click the get started link. getStarted.click(); ``` -------------------------------- ### Setup Project for Authentication Source: https://github.com/cloudflare/playwright/blob/main/docs/src/auth.md This setup file authenticates a user and saves the browser state to a file. Replace placeholder credentials and actions with your actual login flow. ```typescript import { test as setup, expect } from '@playwright/test'; import path from 'path'; const authFile = path.join(__dirname, '../playwright/.auth/user.json'); setup('authenticate', 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('username'); 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: authFile }); }); ``` -------------------------------- ### Set up and tear down a repository for tests Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api-testing-js.md Use 'beforeAll' to create a repository before tests run and 'afterAll' to delete it afterwards. Asserts the success of these operations. ```js const REPO = 'test-repo-1'; const USER = 'github-username'; 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(); }); ``` -------------------------------- ### Build Project Source: https://github.com/cloudflare/playwright/blob/main/packages/playwright-cloudflare/examples/todomvc/README.md Execute this command to build the project for deployment. ```bash npm run build ``` -------------------------------- ### install Source: https://github.com/cloudflare/playwright/blob/main/docs/src/clock.md Initializes the clock and provides methods to pause, fast-forward, run for a duration, or resume time. ```APIDOC ## install ### Description Initializes the clock and allows for advanced time manipulation such as pausing, fast-forwarding, and running for specific durations. ### Method `page.clock.install()` ### Parameters None ### Sub-methods available after install: - `pauseAt(time)`: Pauses the time at a specific time. - `fastForward(duration)`: Fast forwards the time by a specified duration. - `runFor(duration)`: Runs the time for a specific duration. - `resume()`: Resumes the normal flow of time. ### Request Example ```javascript await page.clock.install(); await page.clock.pauseAt(new Date('2024-02-02T10:00:00')); ``` ### Response #### Success Response (200) - **void** - No explicit return value, operation is performed. ### Response Example ```json // No response body for this operation ``` ``` -------------------------------- ### Test with Pre-authenticated State Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-global-setup-teardown-js.md Tests automatically start authenticated when `storageState` is populated by the global setup. ```typescript import { test } from '@playwright/test'; test('test', async ({ page }) => { await page.goto('/'); // You are signed in! }); ``` -------------------------------- ### Basic TestConfig Example Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-testconfig.md Demonstrates setting top-level configuration options like timeout, globalTimeout, reporter, and testDir. ```APIDOC ## Basic TestConfig Configuration ### Description This example shows how to configure Playwright Test using the `defineConfig` function, setting essential options for test execution. ### Usage ```js title="playwright.config.ts" import { defineConfig } from '@playwright/test'; export default defineConfig({ timeout: 30000, globalTimeout: 600000, reporter: 'list', testDir: './tests', }); ``` ``` -------------------------------- ### globalSetup Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-testconfig.md Path to the global setup file. This file will be required and run before all the tests. It must export a single function that takes a [FullConfig] argument. Pass an array of paths to specify multiple global setup files. ```APIDOC ## property: TestConfig.globalSetup * since: v1.10 - type: ?<[string]|[Array]<[string]>> Path to the global setup file. This file will be required and run before all the tests. It must export a single function that takes a [FullConfig] argument. Pass an array of paths to specify multiple global setup files. Learn more about [global setup and teardown](../test-global-setup-teardown.md). **Usage** ```js title="playwright.config.ts" import { defineConfig } from '@playwright/test'; export default defineConfig({ globalSetup: './global-setup', }); ``` ``` -------------------------------- ### Azure Pipelines for Python Source: https://github.com/cloudflare/playwright/blob/main/docs/src/ci.md An Azure Pipelines setup for running Playwright tests using Python. It installs a specific Python version, installs project dependencies, downloads Playwright browsers, and executes tests with pytest. ```yml trigger: - main pool: vmImage: ubuntu-latest steps: - task: UsePythonVersion@0 inputs: versionSpec: '3.13' displayName: 'Use Python' - script: | python -m pip install --upgrade pip pip install -r requirements.txt displayName: 'Install dependencies' - script: playwright install --with-deps displayName: 'Install Playwright browsers' - script: pytest displayName: 'Run Playwright tests' ``` -------------------------------- ### Test Generation Context Example Source: https://github.com/cloudflare/playwright/blob/main/packages/playwright/src/agents/playwright-test-generator.agent.md Provides an example of the XML-like context used to guide the test generation process. It specifies the test suite, test name, file path, seed file, and the body content for the test case. ```xml Context: User wants to generate a test for the test plan item. ``` -------------------------------- ### Generate Trace with Playwright Source: https://github.com/cloudflare/playwright/blob/main/README.md Example of launching Playwright, starting tracing, performing actions, stopping tracing to a file, and returning the trace file. ```JavaScript import fs from "fs"; import { launch } from "@cloudflare/playwright"; export default { async fetch(request, env): Promise { const browser = await launch(env.MYBROWSER); const page = await browser.newPage(); await page.context().tracing.start({ screenshots: true, snapshots: true }); // ... do something, screenshot for example // For now, fs only supports writing into /tmp await page.context().tracing.stop({ path: "/tmp/trace.zip" }); await browser.close(); const file = await fs.promises.readFile("/tmp/trace.zip"); return new Response(file, { status: 200, headers: { "Content-Type": "application/zip", }, }); } } satisfies ExportedHandler; ``` -------------------------------- ### WebView2 Test Setup and Teardown Source: https://github.com/cloudflare/playwright/blob/main/docs/src/webview2.md Configures environment variables for WebView2, launches the process, and connects Playwright over CDP. Includes cleanup logic to kill the process and close the browser. ```csharp using Microsoft.Playwright; using Microsoft.Playwright.MSTest; using System.Diagnostics; namespace PlaywrightTests; [TestClass] public class WebView2Test : MSTest.PageTest { private Process? _webView2Process; private string _userDataDir = Path.Combine(Path.GetTempPath(), "Playwright", Guid.NewGuid().ToString()); [TestInitialize] public async Task BrowserTestInitialize() { var cdpPort = 9222; _webView2Process = new Process { StartInfo = new ProcessStartInfo { FileName = "msedge.exe", Arguments = $"--remote-debugging-port={cdpPort}", UseShellExecute = false, RedirectStandardOutput = true, EnvironmentVariables = { ["WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS"] = $"--remote-debugging-port={cdpPort}", ["WEBVIEW2_USER_DATA_FOLDER"] = _userDataDir, }, RedirectStandardOutput = true, } }; _webView2Process.Start(); 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]; } [TestCleanup] public async Task BrowserTestCleanup() { _webView2Process!.Kill(true); await Browser.CloseAsync(); } } ``` -------------------------------- ### Vue.js Component Test Setup with beforeMount Hook Source: https://github.com/cloudflare/playwright/blob/main/docs/src/release-notes-js.md Configure your Vue.js application for component tests using the `beforeMount` hook. This example shows setting up the App router. ```js import { test } from '@playwright/experimental-ct-vue'; import { Component } from './mycomponent'; test('should work', async ({ mount }) => { const component = await mount(Component, { hooksConfig: { /* anything to configure your app */ } }); }); ``` ```js import { router } from '../router'; import { beforeMount } from '@playwright/experimental-ct-vue/hooks'; beforeMount(async ({ app, hooksConfig }) => { app.use(router); }); ``` -------------------------------- ### Launch a Browser and Create a Page Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api/class-browser.md Demonstrates how to launch a browser instance (e.g., Firefox) and create a new page to navigate to a URL. Ensure to close the browser when done. ```javascript const { firefox } = require('playwright'); // Or 'chromium' or 'webkit'. (async () => { const browser = await firefox.launch(); const page = await browser.newPage(); await page.goto('https://example.com'); await browser.close(); })(); ``` ```java import com.microsoft.playwright.*; public class Example { public static void main(String[] args) { try (Playwright playwright = Playwright.create()) { BrowserType firefox = playwright.firefox(); Browser browser = firefox.launch(); Page page = browser.newPage(); page.navigate("https://example.com"); browser.close(); } } } ``` ```python import asyncio from playwright.async_api import async_playwright, Playwright async def run(playwright: Playwright): firefox = playwright.firefox browser = await firefox.launch() page = await browser.new_page() await page.goto("https://example.com") 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): firefox = playwright.firefox browser = firefox.launch() page = browser.new_page() page.goto("https://example.com") browser.close() with sync_playwright() as playwright: run(playwright) ``` ```csharp using Microsoft.Playwright; using var playwright = await Playwright.CreateAsync(); var firefox = playwright.Firefox; var browser = await firefox.LaunchAsync(new() { Headless = false }); var page = await browser.NewPageAsync(); await page.GotoAsync("https://www.bing.com"); await browser.CloseAsync(); ``` -------------------------------- ### Declare beforeEach hook with a title Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-test.md Declare a beforeEach hook with a specific title to perform setup actions before each test. This example logs the hook title and navigates to a URL. ```js test.beforeEach('Open start URL', async ({ page }) => { console.log(`Running ${test.info().title}`); await page.goto('https://my.start.url/'); }); ``` -------------------------------- ### Use `fixme` in `beforeEach` Hook Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-annotations-js.md Conditionally skip tests or hooks using `test.fixme` within a `beforeEach` hook. This example skips the setup and subsequent tests if the environment is mobile. ```typescript test.beforeEach(async ({ page, isMobile }) => { test.fixme(isMobile, 'Settings page does not work in mobile yet'); await page.goto('http://localhost:3000/settings'); }); test('user profile', async ({ page }) => { await page.getByText('My Profile').click(); // ... }); ``` -------------------------------- ### Jenkins: Python Pipeline Configuration Source: https://github.com/cloudflare/playwright/blob/main/docs/src/ci.md Configure a Jenkins pipeline for Python Playwright tests using a Docker agent. This example installs project dependencies and runs tests with pytest. ```groovy pipeline { agent { docker { image 'mcr.microsoft.com/playwright/python:v%%VERSION%%-noble' } } stages { stage('e2e-tests') { steps { sh 'pip install -r requirements.txt' sh 'pytest' } } } } ``` -------------------------------- ### Authenticate Once for All Tests (Setup Project) Source: https://github.com/cloudflare/playwright/blob/main/docs/src/auth.md Use this method in a setup project to authenticate once and save the state for all subsequent tests. It sends a POST request to the login endpoint and saves the storage state to a file. ```js import { test as setup } from '@playwright/test'; const authFile = 'playwright/.auth/user.json'; setup('authenticate', async ({ request }) => { // Send authentication request. Replace with your own. await request.post('https://github.com/login', { form: { 'user': 'user', 'password': 'password' } }); await request.storageState({ path: authFile }); }); ``` -------------------------------- ### Azure Pipelines for C# Source: https://github.com/cloudflare/playwright/blob/main/docs/src/ci.md An Azure Pipelines setup for running Playwright tests with C# and .NET. It configures the .NET SDK, builds the project, installs Playwright browsers, and executes tests. ```yml trigger: - main pool: vmImage: ubuntu-latest steps: - task: UseDotNet@2 inputs: packageType: sdk version: '8.0.x' displayName: 'Use .NET SDK' - script: dotnet build --configuration Release displayName: 'Build' - script: pwsh bin/Release/net8.0/playwright.ps1 install --with-deps displayName: 'Install Playwright browsers' - script: dotnet test --configuration Release displayName: 'Run tests' ``` -------------------------------- ### Next.js Component Test Setup with beforeMount Hook Source: https://github.com/cloudflare/playwright/blob/main/docs/src/release-notes-js.md Configure your Next.js application for component tests using the `beforeMount` hook. This example demonstrates redefining `useRouter` to return mock values. ```js import { test } from '@playwright/experimental-ct-react'; import { Component } from './mycomponent'; test('should work', async ({ mount }) => { const component = await mount(, { // Pass mock value from test into `beforeMount`. hooksConfig: { router: { query: { page: 1, per_page: 10 }, asPath: '/posts' } } }); }); ``` ```js import router from 'next/router'; import { beforeMount } from '@playwright/experimental-ct-react/hooks'; beforeMount(async ({ hooksConfig }) => { // Before mount, redefine useRouter to return mock value from test. router.useRouter = () => hooksConfig.router; }); ``` -------------------------------- ### Initial Test Run Example Source: https://github.com/cloudflare/playwright/blob/main/docs/src/release-notes-js.md Example output of a full test run, showing the number of tests executed and the failures. ```sh $ npx playwright test Running 103 tests using 5 workers ... 2 failed [chromium] › my-test.spec.ts:8:5 › two ───────────────────────────────────────────────────────── [chromium] › my-test.spec.ts:13:5 › three ────────────────────────────────────────────────────── 101 passed (30.0s) ``` -------------------------------- ### Basic Test Setup with MSTest Source: https://github.com/cloudflare/playwright/blob/main/docs/src/writing-tests-csharp.md Example of a basic test class using Playwright with the MSTest test runner. Ensures test isolation by providing a separate Page instance for each test. ```csharp using System.Threading.Tasks; using Microsoft.Playwright.MSTest; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace PlaywrightTests; [TestClass] public class ExampleTest : PageTest { [TestMethod] public async Task BasicTest() { await Page.GotoAsync("https://playwright.dev"); } } ``` -------------------------------- ### launch(endpoint, options?) Source: https://context7.com/cloudflare/playwright/llms.txt Starts a new browser session by acquiring a fresh Browser Run session and returning a connected `Browser` instance. It internally calls `acquire()` and then opens a WebSocket/CDP connection. The browser session is closed when `browser.close()` is called. ```APIDOC ## launch(endpoint, options?) ### Description Acquires a fresh Browser Run session and returns a connected `Browser` instance. Calls `acquire()` internally and then opens a WebSocket/CDP connection. The browser (and its underlying session) is closed when `browser.close()` is called. ### Method `launch(endpoint, options?)` ### Parameters #### Path Parameters - **endpoint** (Binding) - Required - The Cloudflare Browser Run binding. - **options** (object) - Optional - Configuration options for launching the browser. - **keep_alive** (number) - Optional - Duration in milliseconds to keep the session alive after inactivity. ### Request Example ```typescript import { launch } from '@cloudflare/playwright'; // Assuming env.MYBROWSER is a Browser Run binding const browser = await launch(env.MYBROWSER); // With keep_alive option // const browser = await launch(env.MYBROWSER, { keep_alive: 30_000 }); // ... use browser instance ... await browser.close(); ``` ### Response #### Success Response (Browser) - **browser** (Browser) - A connected `Browser` instance. ``` -------------------------------- ### Basic Test Setup with NUnit Source: https://github.com/cloudflare/playwright/blob/main/docs/src/writing-tests-csharp.md Example of a basic test class using Playwright with the NUnit test runner. Ensures test isolation by providing a separate Page instance for each test. ```csharp using System.Threading.Tasks; using Microsoft.Playwright.NUnit; using NUnit.Framework; namespace PlaywrightTests; [Parallelizable(ParallelScope.Self)] [TestFixture] public class ExampleTest : PageTest { [Test] public async Task BasicTest() { await Page.GotoAsync("https://playwright.dev"); } } ``` -------------------------------- ### Puppeteer Test Example with Jest Source: https://github.com/cloudflare/playwright/blob/main/docs/src/puppeteer-js.md Demonstrates a typical end-to-end test structure using Puppeteer with the Jest testing framework. It includes browser setup, navigation, element selection, and assertion. ```js import puppeteer from 'puppeteer'; describe('Playwright homepage', () => { let browser; let page; beforeAll(async () => { browser = await puppeteer.launch(); page = await browser.newPage(); }); it('contains hero title', async () => { await page.goto('https://playwright.dev/'); await page.waitForSelector('.hero__title'); const text = await page.$eval('.hero__title', e => e.textContent); expect(text).toContain('Playwright enables reliable end-to-end testing'); // 5 }); afterAll(() => browser.close()); }); ``` -------------------------------- ### Create New Project with xUnit Source: https://github.com/cloudflare/playwright/blob/main/docs/src/intro-csharp.md Use this command to create a new xUnit test project. Navigate into the created directory. ```bash dotnet new xunit -n PlaywrightTests cd PlaywrightTests ``` -------------------------------- ### End-to-End Test with Playwright Test (JavaScript/TypeScript) Source: https://github.com/cloudflare/playwright/blob/main/docs/src/library-js.md Example of achieving similar behavior using Playwright Test. This approach leverages the built-in test runner and assertions, simplifying setup and teardown. ```js-ts import { expect, test, devices } from '@playwright/test'; test.use(devices['iPhone 11']); test('should be titled', async ({ page, context }) => { await context.route('**.jpg', route => route.abort()); await page.goto('https://example.com/'); await expect(page).toHaveTitle('Example'); }); ``` ```js-js const { expect, test, devices } = require('@playwright/test'); test.use(devices['iPhone 11']); test('should be titled', async ({ page, context }) => { await context.route('**.jpg', route => route.abort()); await page.goto('https://example.com/'); await expect(page).toHaveTitle('Example'); }); ``` -------------------------------- ### Prepare Server State via API Calls in C# Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api-testing-csharp.md Use API calls to set up the server state before interacting with the UI. This example creates a GitHub issue via API and then verifies its presence in the UI. ```csharp class TestGitHubAPI : PageTest { [TestMethod] public async Task LastCreatedIssueShouldBeFirstInTheList() { var data = new Dictionary { { "title", "[Feature] request 1" }, { "body", "Feature description" } }; var newIssue = await Request.PostAsync("/repos/" + USER + "/" + REPO + "/issues", new() { DataObject = data }); await Expect(newIssue).ToBeOKAsync(); // When inheriting from 'PlaywrightTest' it only gives you a Playwright instance. To get a Page instance, either start // a browser, context, and page manually or inherit from 'PageTest' which will launch it for you. await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues"); var firstIssue = Page.Locator("a[data-hovercard-type='issue']").First; await Expect(firstIssue).ToHaveTextAsync("[Feature] request 1"); } } ``` -------------------------------- ### Locator for 'Get Started' Link using Text Source: https://github.com/cloudflare/playwright/blob/main/docs/src/writing-tests-java.md Demonstrates finding a link by its text content using `page.locator("text=...")`. This locator can then be used for actions or assertions. ```java import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat; Locator getStarted = page.locator("text=Get Started"); assertThat(getStarted).hasAttribute("href", "/docs/intro"); getStarted.click(); ``` -------------------------------- ### Start Tracing with Options Source: https://github.com/cloudflare/playwright/blob/main/docs/src/api/class-tracing.md Initiates trace recording, capturing screenshots and snapshots. This API is recommended for manual trace collection. ```js await context.tracing.start({ screenshots: true, snapshots: true }); const page = await context.newPage(); await page.goto('https://playwright.dev'); expect(page.url()).toBe('https://playwright.dev'); await context.tracing.stop({ path: 'trace.zip' }); ``` ```java context.tracing().start(new Tracing.StartOptions() .setScreenshots(true) .setSnapshots(true)); Page page = context.newPage(); page.navigate("https://playwright.dev"); context.tracing().stop(new Tracing.StopOptions() .setPath(Paths.get("trace.zip"))); ``` ```python await context.tracing.start(screenshots=True, snapshots=True) page = await context.new_page() await page.goto("https://playwright.dev") await context.tracing.stop(path = "trace.zip") ``` ```python context.tracing.start(screenshots=True, snapshots=True) page = context.new_page() page.goto("https://playwright.dev") context.tracing.stop(path = "trace.zip") ``` ```csharp using var playwright = await Playwright.CreateAsync(); var browser = await playwright.Chromium.LaunchAsync(); await using var context = await browser.NewContextAsync(); await context.Tracing.StartAsync(new() { Screenshots = true, Snapshots = true }); var page = await context.NewPageAsync(); await page.GotoAsync("https://playwright.dev"); await context.Tracing.StopAsync(new() { Path = "trace.zip" }); ``` -------------------------------- ### Configure Project Dependencies Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-projects-js.md Set up a 'setup' project that runs before 'chromium', 'firefox', and 'webkit' projects. Dependencies ensure that setup actions are completed before dependent tests run. ```typescript import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ projects: [ { name: 'setup', testMatch: '**/*.setup.ts', }, { name: 'chromium', use: { ...devices['Desktop Chrome'] }, dependencies: ['setup'], }, { name: 'firefox', use: { ...devices['Desktop Firefox'] }, dependencies: ['setup'], }, { name: 'webkit', use: { ...devices['Desktop Safari'] }, dependencies: ['setup'], }, ], }); ``` -------------------------------- ### Azure Pipelines: Java CI Configuration Source: https://github.com/cloudflare/playwright/blob/main/docs/src/ci.md Configure Azure Pipelines to execute Java Playwright tests. This setup installs a specific JDK version, builds the project with Maven, and runs tests. ```yml trigger: - main pool: vmImage: ubuntu-latest container: mcr.microsoft.com/playwright/java:v%%VERSION%%-noble steps: - task: JavaToolInstaller@1 inputs: versionSpec: '25' jdkArchitectureOption: 'x64' jdkSourceOption: AzureStorage - script: mvn -B install -D skipTests --no-transfer-progress displayName: 'Build and install' - script: mvn test displayName: 'Run tests' ``` -------------------------------- ### FullProject.use Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-fullproject.md Configuration for fixtures used in the project. ```APIDOC ## property: FullProject.use * since: v1.10 - type: <[Fixtures]> See [`property: TestProject.use`]. ``` -------------------------------- ### Configure Vite in Playwright Component Testing Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-components-js.md Example of how to integrate existing Vite configurations into Playwright's component testing setup using `ctViteConfig`. This is useful for reusing path mappings and other settings. ```js import { defineConfig } from '@playwright/experimental-ct-react'; export default defineConfig({ use: { ctViteConfig: { // … }, }, }); ``` -------------------------------- ### Configure Single Web Server Source: https://github.com/cloudflare/playwright/blob/main/docs/src/test-api/class-testconfig.md Sets up a single web server to be launched before tests. It specifies the command to start the server, the URL to check for readiness, a custom timeout, and reuses an existing server if not running in CI. ```typescript import { defineConfig } from '@playwright/test'; export default defineConfig({ webServer: { command: 'npm run start', url: 'http://localhost:3000', timeout: 120 * 1000, reuseExistingServer: !process.env.CI, }, use: { baseURL: 'http://localhost:3000/', }, }); ``` -------------------------------- ### Launch Browser with Playwright Library (JavaScript/TypeScript) Source: https://github.com/cloudflare/playwright/blob/main/docs/src/library-js.md Example of using the Playwright Library directly to launch Chromium, navigate to a page, and assert its title. This setup requires manual browser and context teardown. ```js-ts import { chromium, devices } from 'playwright'; import assert from 'node:assert'; (async () => { // Setup const browser = await chromium.launch(); const context = await browser.newContext(devices['iPhone 11']); const page = await context.newPage(); // The actual interesting bit await context.route('**.jpg', route => route.abort()); await page.goto('https://example.com/'); assert(await page.title() === 'Example Domain'); // 👎 not a Web First assertion // Teardown await context.close(); await browser.close(); })(); ``` ```js-js const assert = require('node:assert'); const { chromium, devices } = require('playwright'); (async () => { // Setup const browser = await chromium.launch(); const context = await browser.newContext(devices['iPhone 11']); const page = await context.newPage(); // The actual interesting bit await context.route('**.jpg', route => route.abort()); await page.goto('https://example.com/'); assert(await page.title() === 'Example Domain'); // 👎 not a Web First assertion // Teardown await context.close(); await browser.close(); })(); ```