diff --git a/docs/src/codegen.md b/docs/src/codegen.md index 74a125e98f..528a029463 100644 --- a/docs/src/codegen.md +++ b/docs/src/codegen.md @@ -3,14 +3,64 @@ id: codegen title: "Test generator" --- -Playwright comes with the ability to generate tests out of the box and is a great way to quickly get started with testing. It will open two windows, a browser window where you interact with the website you wish to test and the Playwright Inspector window where you can record your tests, copy the tests, clear your tests as well as change the language of your tests. +import LiteYouTube from '@site/src/components/LiteYouTube'; - -## Running Codegen +Playwright comes with the ability to generate tests for you as you perform actions in the browser and is a great way to quickly get started with testing. Playwright will look at your page and figure out the best locator, prioritizing [role, text and test id locators](./locators.md). If the generator finds multiple elements matching the locator, it will improve the locator to make it resilient that uniquely identify the target element. + +## Generate tests in VS Code +* langs: js + +Install the VS Code extension and generate tests directly from VS Code. The extension is available on the [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=ms-playwright.playwright). Check out our guide on [getting started with VS Code](./getting-started-vscode.md). + + + +### Record a New Test + +To record a test click on the **Record new** button from the Testing sidebar. This will create a `test-1.spec.ts` file as well as open up a browser window. + +record new in vs code + +In the browser go to the URL you wish to test and start clicking around to record your user actions. + +clicking delete button on todo app with locator highlighted + +Playwright will record your actions and generate the test code directly in VS Code. Once you are done recording click the **cancel** button or close the browser window. You can then inspect your `test-1.spec.ts` file and see your generated test and then manually improve the test by adding [ assertions](test-assertions). + +vs code showing recorded actions of test + +### Record at Cursor + +To record from a specific point in your test move your cursor to where you want to record more actions and then click the **Record at cursor** button from the Testing sidebar. If your browser window is not already open then first run the test with 'Show browser' checked and then click the **Record at cursor** button. + +record at cursor in vs code + +In the browser window start performing the actions you want to record. + +add feed the dog to todo app + + +In the test file in VS Code you will see your new generated actions added to your test at the cursor position. + +vs code showing test code generated + +### Generating locators + +You can generate locators with the test generator. +- Click on the **Pick locator** button form the testing sidebar and then hover over elements in the browser window to see the [locator](./locators.md) highlighted underneath each element. +- Click the element you require and it will now show up in the **Pick locator** box in VS Code. +- Press Enter on your keyboard to copy the locator into the clipboard and then paste anywhere in your code. Or press 'escape' if you want to cancel. + +Pick locators in VS code + +## Generate tests with the Playwright Inspector + +When running the `codegen` command two windows will be opened, a browser window where you interact with the website you wish to test and the Playwright Inspector window where you can record your tests and then copy them into your editor. + +### Running Codegen Use the `codegen` command to run the test generator followed by the URL of the website you want to generate tests for. The URL is optional and you can always run the command without it and then add the URL directly into the browser window instead. @@ -32,7 +82,7 @@ pwsh bin/Debug/netX/playwright.ps1 codegen demo.playwright.dev/todomvc ### Recording a test -Run `codegen` and perform actions in the browser. Playwright will generate the code for the user interactions. `Codegen` will look at the rendered page and figure out the recommended locator, prioritizing role, text and test id locators. If the generator identifies multiple elements matching the locator, it will improve the locator to make it resilient and uniquely identify the target element, therefore eliminating and reducing test(s) failing and flaking due to locators. +Run the `codegen` command and perform actions in the browser window. Playwright will generate the code for the user interactions which you can see in the Playwright Inspector window. Once you have finished recording your test stop the recording and press the **copy** button to copy your generated test into your editor. ###### * langs: js @@ -52,7 +102,7 @@ Run `codegen` and perform actions in the browser. Playwright will generate the c ###### * langs: csharp -Screenshot 2023-01-16 at 20 42 26 +Recording a test When you have finished interacting with the page, press the **record** button to stop the recording and use the **copy** button to copy the generated code to your editor. @@ -111,30 +161,66 @@ playwright codegen --viewport-size=800,600 playwright.dev ```bash csharp pwsh bin/Debug/netX/playwright.ps1 codegen --viewport-size=800,600 playwright.dev ``` +###### +* langs: js + +Codegen generating code for tests for playwright.dev website with a specific viewport js + +###### +* langs: java + +Codegen generating code for tests for playwright.dev website with a specific viewport java + +###### +* langs: python + +Codegen generating code for tests for playwright.dev website with a specific viewport python + +###### +* langs: csharp + +Codegen generating code for tests for playwright.dev website with a specific viewport dotnet -Codegen generating code for tests for playwright.dev website with a specific viewport ### Emulate devices Record scripts and tests while emulating a mobile device using the `--device` option which sets the viewport size and user agent among others. ```bash js -npx playwright codegen --device="iPhone 11" playwright.dev +npx playwright codegen --device="iPhone 13" playwright.dev ``` ```bash java -mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args='codegen --device="iPhone 11" playwright.dev' +mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args='codegen --device="iPhone 13" playwright.dev' ``` ```bash python -playwright codegen --device="iPhone 11" playwright.dev +playwright codegen --device="iPhone 13" playwright.dev ``` ```bash csharp -pwsh bin/Debug/netX/playwright.ps1 codegen --device="iPhone 11" playwright.dev +pwsh bin/Debug/netX/playwright.ps1 codegen --device="iPhone 13" playwright.dev ``` +###### +* langs: js + +Codegen generating code for tests for playwright.dev website emulated for iPhone 13 js + +###### +* langs: java + +Codegen generating code for tests for playwright.dev website emulated for iPhone 13 java + +###### +* langs: python + +Codegen generating code for tests for playwright.dev website emulated for iPhone 13 python + +###### +* langs: csharp + +Codegen generating code for tests for playwright.dev website emulated for iPhone 13 csharp -Codegen generating code for tests for playwright.dev website emulated for iPhone 11 ### Emulate color scheme @@ -156,55 +242,123 @@ playwright codegen --color-scheme=dark playwright.dev pwsh bin/Debug/netX/playwright.ps1 codegen --color-scheme=dark playwright.dev ``` -Codegen generating code for tests for playwright.dev website in dark mode +###### +* langs: js + +Codegen generating code for tests for playwright.dev website in dark mode js + +###### +* langs: java + +Codegen generating code for tests for playwright.dev website in dark mode java + +###### +* langs: python + +Codegen generating code for tests for playwright.dev website in dark mode python + +###### +* langs: csharp + +Codegen generating code for tests for playwright.dev website in dark mode csharp ### Emulate geolocation, language and timezone -Record scripts and tests while emulating timezone, language & location using the `--timezone`, `--geolocation` and `--lang` options. Once page opens, click the "show your location" icon at them bottom right corner of the map to see geolocation in action. +Record scripts and tests while emulating timezone, language & location using the `--timezone`, `--geolocation` and `--lang` options. Once the page opens: + +1. Accept the cookies +1. On the top right click on the locate me button to see geolocation in action. ```bash js -npx playwright codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" maps.google.com +npx playwright codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" bing.com/maps ``` ```bash java -mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args='codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" maps.google.com' +mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args='codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" bing.com/maps' ``` ```bash python -playwright codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" maps.google.com +playwright codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" bing.com/maps ``` ```bash csharp -pwsh bin/Debug/netX/playwright.ps1 codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" maps.google.com +pwsh bin/Debug/netX/playwright.ps1 codegen --timezone="Europe/Rome" --geolocation="41.890221,12.492348" --lang="it-IT" bing.com/maps ``` -Codegen generating code for tests for google maps showing timezone, geolocation as Rome, Italy and in Italian language +###### +* langs: js + +Codegen generating code for tests for bing maps showing timezone, geolocation as Rome, Italy and in Italian language + +###### +* langs: java + +Codegen generating code for tests for bing maps showing timezone, geolocation as Rome, Italy and in Italian language java + +###### +* langs: python + +Codegen generating code for tests for bing maps showing timezone, geolocation as Rome, Italy and in Italian language python + + +###### +* langs: csharp + +Codegen generating code for tests for bing maps showing timezone, geolocation as Rome, Italy and in Italian language csharp ### Preserve authenticated state -Run `codegen` with `--save-storage` to save [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) at the end of the session. This is useful to separately record an authentication step and reuse it later in the tests. - -After performing authentication and closing the browser, `auth.json` will contain the storage state. +Run `codegen` with `--save-storage` to save [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) at the end of the session. This is useful to separately record an authentication step and reuse it later when recording more tests. ```bash js -npx playwright codegen --save-storage=auth.json +npx playwright codegen github.com/microsoft/playwright --save-storage=auth.json ``` ```bash java -mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="codegen --save-storage=auth.json" +mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="codegen github.com/microsoft/playwright --save-storage=auth.json" ``` ```bash python -playwright codegen --save-storage=auth.json +playwright codegen github.com/microsoft/playwright --save-storage=auth.json ``` ```bash csharp -pwsh bin/Debug/netX/playwright.ps1 codegen --save-storage=auth.json +pwsh bin/Debug/netX/playwright.ps1 codegen github.com/microsoft/playwright --save-storage=auth.json ``` -Screenshot 2022-08-03 at 13 28 02 +###### +* langs: js -Run with `--load-storage` to consume previously loaded storage. This way, all [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) will be restored, bringing most web apps to the authenticated state without the need to login again. +github page before logging in js + + +###### +* langs: java + +github page before logging in java + + +###### +* langs: python + +github page before logging in python + +###### +* langs: csharp + +github page before logging in csharp + +#### Login + +After performing authentication and closing the browser, `auth.json` will contain the storage state which you can then reuse in your tests. + +login to Github screen + +Make sure you only use the `auth.json` locally as it contains sensative information. Add it to your `.gitignore` or delete it once you have finished generating your tests. + +#### Load authenticated state + +Run with `--load-storage` to consume the previously loaded storage from the `auth.json`. This way, all [cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies) and [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) will be restored, bringing most web apps to the authenticated state without the need to login again. This means you can can continue generating tests from the logged in state. ```bash js npx playwright codegen --load-storage=auth.json github.com/microsoft/playwright @@ -222,26 +376,26 @@ playwright codegen --load-storage=auth.json github.com/microsoft/playwright pwsh bin/Debug/netX/playwright.ps1 codegen --load-storage=auth.json github.com/microsoft/playwright ``` -Screenshot 2022-08-03 at 13 33 40 +###### +* langs: js -Use the `open` command with `--load-storage` to open the saved `auth.json`. +github signed in showing use of load storage js -```bash js -npx playwright open --load-storage=auth.json github.com/microsoft/playwright -``` -```bash java -mvn exec:java -e -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="open --load-storage=auth.json github.com/microsoft/playwright" -``` +###### +* langs: java -```bash python -playwright open --load-storage=auth.json github.com/microsoft/playwright -``` +github signed in showing use of load storage java -```bash csharp -pwsh bin/Debug/netX/playwright.ps1 open --load-storage=auth.json github.com/microsoft/playwright -``` +###### +* langs: python +github signed in showing use of load storage python + +###### +* langs: csharp + +github signed in showing use of load storage scharp ## Record using custom setup diff --git a/docs/src/emulation.md b/docs/src/emulation.md index 10b66e5c02..6956ba6228 100644 --- a/docs/src/emulation.md +++ b/docs/src/emulation.md @@ -25,7 +25,7 @@ export default defineConfig({ { name: 'Mobile Safari', use: { - ...devices['iPhone 12'], + ...devices['iPhone 13'], }, }, ], @@ -36,9 +36,9 @@ export default defineConfig({ const { chromium, devices } = require('playwright'); const browser = await chromium.launch(); -const iphone12 = devices['iPhone 12']; +const iphone13 = devices['iPhone 13']; const context = await browser.newContext({ - ...iphone12, + ...iphone13, }); ``` @@ -47,10 +47,10 @@ import asyncio from playwright.async_api import async_playwright async def run(playwright): - iphone_12 = playwright.devices['iPhone 12'] + iphone_13 = playwright.devices['iPhone 13'] browser = await playwright.webkit.launch(headless=False) context = await browser.new_context( - **iphone_12, + **iphone_13, ) async def main(): @@ -63,10 +63,10 @@ asyncio.run(main()) from playwright.sync_api import sync_playwright def run(playwright): - iphone_12 = playwright.devices['iPhone 12'] + iphone_13 = playwright.devices['iPhone 13'] browser = playwright.webkit.launch(headless=False) context = browser.new_context( - **iphone_12, + **iphone_13, ) with sync_playwright() as playwright: @@ -86,16 +86,19 @@ class Program { Headless: False }); - var iphone12 = playwright.Devices["iPhone 12"]; - await using var context = await browser.NewContextAsync(iphone12); + var iphone13 = playwright.Devices["iPhone 13"]; + await using var context = await browser.NewContextAsync(iphone13); } } ``` +playwright.dev website emulated for iPhone 13 + ## Viewport The viewport is included in the device but you can override it for some tests with [`method: Page.setViewportSize`]. + ```js // playwright.config.ts/js import { defineConfig } from '@playwright/test'; @@ -105,6 +108,7 @@ export default defineConfig({ // Viewport used for all pages in the context. viewport: { width: 1280, height: 720 }, }, + }); ``` @@ -112,12 +116,11 @@ export default defineConfig({ // example.spec.ts/js import { test, expect } from '@playwright/test'; -// Run tests in this file with portrait-like viewport. -test.use({ - viewport: { width: 600, height: 900 }, +test.use({ + viewport: { width: 1600, height: 1200 }, }); -test('my portrait test', async ({ page }) => { +test('my test', async ({ page }) => { // ... }); ``` @@ -143,11 +146,10 @@ The same works inside a describe block. // example.spec.ts/js import { test, expect } from '@playwright/test'; -test.describe('locale block', () => { - // Run tests in this describe block with portrait-like viewport. - test.use({ viewport: { width: 600, height: 900 } }); +test.describe('specific viewport block', () => { + test.use({ viewport: { width: 1600, height: 1200 } }); - test('my portrait test', async ({ page }) => { + test('my test', async ({ page }) => { // ... }); }); @@ -215,6 +217,9 @@ await using var context = await browser.NewContextAsync(new() DeviceScaleFactor = 2 }); ``` + +website with set viewport + ## Locale & Timezone Emulate the user Locale and Timezone which can be set globally for all tests in the config and then overridden for particular tests. @@ -227,7 +232,7 @@ export default defineConfig({ use: { // Emulates the user locale. locale: 'en-GB', - + // Emulates the user timezone. timezoneId: 'Europe/Paris', }, @@ -244,12 +249,12 @@ test.use({ }); test('my test for de lang in Berlin timezone', async ({ page }) => { + await page.goto('https://www.bing.com'); // ... }); ``` ```js tab=js-library -// Emulate locale and time const context = await browser.newContext({ locale: 'de-DE', timezoneId: 'Europe/Berlin', @@ -257,14 +262,12 @@ const context = await browser.newContext({ ``` ```java -// Emulate locale and time BrowserContext context = browser.newContext(new Browser.NewContextOptions() .setLocale("de-DE") .setTimezoneId("Europe/Berlin")); ``` ```python async -# Emulate locale and time context = await browser.new_context( locale='de-DE', timezone_id='Europe/Berlin', @@ -272,7 +275,6 @@ context = await browser.new_context( ``` ```python sync -# Emulate locale and time context = browser.new_context( locale='de-DE', timezone_id='Europe/Berlin', @@ -286,6 +288,8 @@ await using var context = await browser.NewContextAsync(new() TimezoneId = "Europe/Berlin" }); ``` + +Bing in german lang and timezone ## Permissions Allow app to show system notifications. @@ -406,7 +410,7 @@ export default defineConfig({ import { test, expect } from '@playwright/test'; test.use({ - geolocation: { longitude: 48.858455, latitude: 2.294474 }, + geolocation: { longitude: 41.890221, latitude: 12.492348 }, permissions: ['geolocation'], }); @@ -417,7 +421,7 @@ test('my test with geolocation', async ({ page }) => { ```js tab=js-library const context = await browser.newContext({ - geolocation: { longitude: 48.858455, latitude: 2.294474 }, + geolocation: { longitude: 41.890221, latitude: 12.492348 }, permissions: ['geolocation'] }); @@ -425,20 +429,20 @@ const context = await browser.newContext({ ```java BrowserContext context = browser.newContext(new Browser.NewContextOptions() - .setGeolocation(48.858455, 2.294474) + .setGeolocation(41.890221, 12.492348) .setPermissions(Arrays.asList("geolocation"))); ``` ```python async context = await browser.new_context( - geolocation={"longitude": 48.858455, "latitude": 2.294474}, + geolocation={"longitude": 41.890221, "latitude": 12.492348}, permissions=["geolocation"] ) ``` ```python sync context = browser.new_context( - geolocation={"longitude": 48.858455, "latitude": 2.294474}, + geolocation={"longitude": 41.890221, "latitude": 12.492348}, permissions=["geolocation"] ) ``` @@ -447,10 +451,12 @@ context = browser.new_context( await using var context = await browser.NewContextAsync(new() { Permissions = new[] { "geolocation" }, - Geolocation = new Geolocation() { Longitude = 48.858455f, Latitude = 2.294474f } + Geolocation = new Geolocation() { Longitude = 41.890221, Latitude = 12.492348 } }); ``` +geolocation for italy on bing maps + Change the location later: ```js tab=js-js @@ -458,34 +464,34 @@ Change the location later: import { test, expect } from '@playwright/test'; test.use({ - geolocation: { longitude: 48.858455, latitude: 2.294474 }, + geolocation: { longitude: 41.890221, latitude: 12.492348}, permissions: ['geolocation'], }); test('my test with geolocation', async ({ page, context }) => { // overwrite the location for this test - await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 }); + await context.setGeolocation({ longitude: 48.858455, latitude: 2.294474 }); }); ``` ```js tab=js-library -await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 }); +await context.setGeolocation({ longitude: 48.858455, latitude: 2.294474 }); ``` ```java -context.setGeolocation(new Geolocation(29.979097, 31.134256)); +context.setGeolocation(new Geolocation(48.858455, 2.294474)); ``` ```python async -await context.set_geolocation({"longitude": 29.979097, "latitude": 31.134256}) +await context.set_geolocation({"longitude": 48.858455, "latitude": 2.294474}) ``` ```python sync -context.set_geolocation({"longitude": 29.979097, "latitude": 31.134256}) +context.set_geolocation({"longitude": 48.858455, "latitude": 2.294474}) ``` ```csharp -await context.SetGeolocationAsync(new Geolocation() { Longitude = 48.858455f, Latitude = 2.294474f }); +await context.SetGeolocationAsync(new Geolocation() { Longitude = 48.858455, Latitude = 2.294474 }); ``` **Note** you can only change geolocation for all pages in the context. @@ -611,6 +617,8 @@ await page.EmulateMediaAsync(new() Media = Media.Print }); ``` + +playwright web in dark mode ## User Agent The User Agent is included in the device and therefore you will rarely need to change it however if you do need to test a different user agent you can override it with the `userAgent` property.