docs: use getBy... in documentation (#17795)

This commit is contained in:
Dmitry Gozman 2022-10-03 17:02:46 -07:00 committed by GitHub
parent f14f69624f
commit b07690f408
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 580 additions and 624 deletions

View file

@ -74,7 +74,7 @@ For example, you can use [`AxeBuilder.include()`](https://github.com/dequelabs/a
test('navigation menu flyout should not have automatically detectable accessibility violations', async ({ page }) => { test('navigation menu flyout should not have automatically detectable accessibility violations', async ({ page }) => {
await page.goto('https://your-site.com/'); await page.goto('https://your-site.com/');
await page.locator('button[aria-label="Navigation Menu"]').click(); await page.getByRole('button', { name: 'Navigation Menu' }).click();
// It is important to waitFor() the page to be in the desired // It is important to waitFor() the page to be in the desired
// state *before* running analyze(). Otherwise, axe might not // state *before* running analyze(). Otherwise, axe might not

View file

@ -435,7 +435,7 @@ const { webkit } = require('playwright'); // Or 'chromium' or 'firefox'.
<button onclick="onClick()">Click me</button> <button onclick="onClick()">Click me</button>
<div></div> <div></div>
`); `);
await page.locator('button').click(); await page.getByRole('button').click();
})(); })();
``` ```
@ -457,7 +457,7 @@ public class Example {
"</script>\n" + "</script>\n" +
"<button onclick=\"onClick()\">Click me</button>\n" + "<button onclick=\"onClick()\">Click me</button>\n" +
"<div></div>"); "<div></div>");
page.locator("button").click(); page.getByRole("button").click();
} }
} }
} }
@ -482,7 +482,7 @@ async def run(playwright):
<button onclick="onClick()">Click me</button> <button onclick="onClick()">Click me</button>
<div></div> <div></div>
""") """)
await page.locator("button").click() await page.get_by_role("button").click()
async def main(): async def main():
async with async_playwright() as playwright: async with async_playwright() as playwright:
@ -508,7 +508,7 @@ def run(playwright):
<button onclick="onClick()">Click me</button> <button onclick="onClick()">Click me</button>
<div></div> <div></div>
""") """)
page.locator("button").click() page.get_by_role("button").click()
with sync_playwright() as playwright: with sync_playwright() as playwright:
run(playwright) run(playwright)
@ -530,7 +530,7 @@ await page.SetContentAsync("<script>\n" +
"</script>\n" + "</script>\n" +
"<button onclick=\"onClick()\">Click me</button>\n" + "<button onclick=\"onClick()\">Click me</button>\n" +
"<div></div>"); "<div></div>");
await page.Locator("button").ClickAsync(); await page.GetByRole("button").ClickAsync();
``` ```
An example of passing an element handle: An example of passing an element handle:
@ -660,7 +660,7 @@ const crypto = require('crypto');
<button onclick="onClick()">Click me</button> <button onclick="onClick()">Click me</button>
<div></div> <div></div>
`); `);
await page.locator('button').click(); await page.getByRole('button').click();
})(); })();
``` ```
@ -696,7 +696,7 @@ public class Example {
"</script>\n" + "</script>\n" +
"<button onclick=\"onClick()\">Click me</button>\n" + "<button onclick=\"onClick()\">Click me</button>\n" +
"<div></div>\n"); "<div></div>\n");
page.locator("button").click(); page.getByRole("button").click();
} }
} }
} }
@ -728,7 +728,7 @@ async def run(playwright):
<button onclick="onClick()">Click me</button> <button onclick="onClick()">Click me</button>
<div></div> <div></div>
""") """)
await page.locator("button").click() await page.get_by_role("button").click()
async def main(): async def main():
async with async_playwright() as playwright: async with async_playwright() as playwright:
@ -761,7 +761,7 @@ def run(playwright):
<button onclick="onClick()">Click me</button> <button onclick="onClick()">Click me</button>
<div></div> <div></div>
""") """)
page.locator("button").click() page.get_by_role("button").click()
with sync_playwright() as playwright: with sync_playwright() as playwright:
run(playwright) run(playwright)
@ -796,7 +796,7 @@ class BrowserContextExamples
"<button onclick=\"onClick()\">Click me</button>\n" + "<button onclick=\"onClick()\">Click me</button>\n" +
"<div></div>"); "<div></div>");
await page.Locator("button").ClickAsync(); await page.GetByRole("button").ClickAsync();
Console.WriteLine(await page.TextContentAsync("div")); Console.WriteLine(await page.TextContentAsync("div"));
} }
} }
@ -1300,30 +1300,30 @@ value. Will throw an error if the context closes before the event is fired. Retu
```js ```js
const [page, _] = await Promise.all([ const [page, _] = await Promise.all([
context.waitForEvent('page'), context.waitForEvent('page'),
page.locator('button').click() page.getByRole('button').click()
]); ]);
``` ```
```java ```java
Page newPage = context.waitForPage(() -> page.locator("button").click()); Page newPage = context.waitForPage(() -> page.getByRole("button").click());
``` ```
```python async ```python async
async with context.expect_event("page") as event_info: async with context.expect_event("page") as event_info:
await page.locator("button").click() await page.get_by_role("button").click()
page = await event_info.value page = await event_info.value
``` ```
```python sync ```python sync
with context.expect_event("page") as event_info: with context.expect_event("page") as event_info:
page.locator("button").click() page.get_by_role("button").click()
page = event_info.value page = event_info.value
``` ```
```csharp ```csharp
var page = await context.RunAndWaitForPageAsync(async () => var page = await context.RunAndWaitForPageAsync(async () =>
{ {
await page.Locator("button").ClickAsync(); await page.GetByRole("button").ClickAsync();
}); });
``` ```

View file

@ -15,23 +15,16 @@ const [ download ] = await Promise.all([
// It is important to call waitForEvent before click to set up waiting. // It is important to call waitForEvent before click to set up waiting.
page.waitForEvent('download'), page.waitForEvent('download'),
// Triggers the download. // Triggers the download.
page.locator('text=Download file').click(), page.getByText('Download file').click(),
]); ]);
// wait for download to complete // wait for download to complete
const path = await download.path(); const path = await download.path();
``` ```
```java
// wait for download to start
Download download = page.waitForDownload(() -> page.locator("a").click());
// wait for download to complete
Path path = download.path();
```
```java ```java
// wait for download to start // wait for download to start
Download download = page.waitForDownload(() -> { Download download = page.waitForDownload(() -> {
page.locator("a").click(); page.getByText("Download file").click();
}); });
// wait for download to complete // wait for download to complete
Path path = download.path(); Path path = download.path();
@ -39,7 +32,7 @@ Path path = download.path();
```python async ```python async
async with page.expect_download() as download_info: async with page.expect_download() as download_info:
await page.locator("a").click() await page.get_by_text("Download file").click()
download = await download_info.value download = await download_info.value
# waits for download to complete # waits for download to complete
path = await download.path() path = await download.path()
@ -47,7 +40,7 @@ path = await download.path()
```python sync ```python sync
with page.expect_download() as download_info: with page.expect_download() as download_info:
page.locator("a").click() page.get_by_text("Download file").click()
download = download_info.value download = download_info.value
# wait for download to complete # wait for download to complete
path = download.path() path = download.path()
@ -56,7 +49,7 @@ path = download.path()
```csharp ```csharp
var download = await page.RunAndWaitForDownloadAsync(async () => var download = await page.RunAndWaitForDownloadAsync(async () =>
{ {
await page.Locator("#downloadButton").ClickAsync(); await page.GetByText("Download file").ClickAsync();
}); });
Console.WriteLine(await download.PathAsync()); Console.WriteLine(await download.PathAsync());
``` ```

View file

@ -76,32 +76,32 @@ await handle.ClickAsync();
With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So in the snippet below, underlying DOM element is going to be located twice. With the locator, every time the `element` is used, up-to-date DOM element is located in the page using the selector. So in the snippet below, underlying DOM element is going to be located twice.
```js ```js
const locator = page.locator('text=Submit'); const locator = page.getByText('Submit');
// ... // ...
await locator.hover(); await locator.hover();
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = page.locator("text=Submit"); Locator locator = page.getByText("Submit");
locator.hover(); locator.hover();
locator.click(); locator.click();
``` ```
```python async ```python async
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
await locator.hover() await locator.hover()
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
locator.hover() locator.hover()
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = page.Locator("text=Submit"); var locator = page.GetByText("Submit");
await locator.HoverAsync(); await locator.HoverAsync();
await locator.ClickAsync(); await locator.ClickAsync();
``` ```

View file

@ -10,26 +10,26 @@ const [fileChooser] = await Promise.all([
// It is important to call waitForEvent before click to set up waiting. // It is important to call waitForEvent before click to set up waiting.
page.waitForEvent('filechooser'), page.waitForEvent('filechooser'),
// Opens the file chooser. // Opens the file chooser.
page.locator('text=Upload').click(), page.getByText('Upload').click(),
]); ]);
await fileChooser.setFiles('myfile.pdf'); await fileChooser.setFiles('myfile.pdf');
``` ```
```java ```java
FileChooser fileChooser = page.waitForFileChooser(() -> page.locator("upload").click()); FileChooser fileChooser = page.waitForFileChooser(() -> page.getByText("Upload").click());
fileChooser.setFiles(Paths.get("myfile.pdf")); fileChooser.setFiles(Paths.get("myfile.pdf"));
``` ```
```python async ```python async
async with page.expect_file_chooser() as fc_info: async with page.expect_file_chooser() as fc_info:
await page.locator("upload").click() await page.get_by_text("Upload").click()
file_chooser = await fc_info.value file_chooser = await fc_info.value
await file_chooser.set_files("myfile.pdf") await file_chooser.set_files("myfile.pdf")
``` ```
```python sync ```python sync
with page.expect_file_chooser() as fc_info: with page.expect_file_chooser() as fc_info:
page.locator("upload").click() page.get_by_text("Upload").click()
file_chooser = fc_info.value file_chooser = fc_info.value
file_chooser.set_files("myfile.pdf") file_chooser.set_files("myfile.pdf")
``` ```
@ -37,7 +37,7 @@ file_chooser.set_files("myfile.pdf")
```csharp ```csharp
var fileChooser = await page.RunAndWaitForFileChooserAsync(async () => var fileChooser = await page.RunAndWaitForFileChooserAsync(async () =>
{ {
await page.Locator("upload").ClickAsync(); await page.GetByText("Upload").ClickAsync();
}); });
await fileChooser.SetFilesAsync("temp.txt"); await fileChooser.SetFilesAsync("temp.txt");
``` ```

View file

@ -859,27 +859,27 @@ in that iframe. Following snippet locates element with text "Submit" in the ifra
like `<iframe id="my-frame">`: like `<iframe id="my-frame">`:
```js ```js
const locator = frame.frameLocator('#my-iframe').locator('text=Submit'); const locator = frame.frameLocator('#my-iframe').getByText('Submit');
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = frame.frameLocator("#my-iframe").locator("text=Submit"); Locator locator = frame.frameLocator("#my-iframe").getByText("Submit");
locator.click(); locator.click();
``` ```
```python async ```python async
locator = frame.frame_locator("#my-iframe").locator("text=Submit") locator = frame.frame_locator("#my-iframe").get_by_text("Submit")
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = frame.frame_locator("#my-iframe").locator("text=Submit") locator = frame.frame_locator("#my-iframe").get_by_text("Submit")
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = frame.FrameLocator("#my-iframe").Locator("text=Submit"); var locator = frame.FrameLocator("#my-iframe").GetByText("Submit");
await locator.ClickAsync(); await locator.ClickAsync();
``` ```

View file

@ -4,7 +4,7 @@
FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe` and locate elements in that iframe. FrameLocator can be created with either [`method: Page.frameLocator`] or [`method: Locator.frameLocator`] method. FrameLocator represents a view to the `iframe` on the page. It captures the logic sufficient to retrieve the `iframe` and locate elements in that iframe. FrameLocator can be created with either [`method: Page.frameLocator`] or [`method: Locator.frameLocator`] method.
```js ```js
const locator = page.frameLocator('#my-frame').locator('text=Submit'); const locator = page.frameLocator('#my-frame').getByText('Submit');
await locator.click(); await locator.click();
``` ```
@ -34,42 +34,42 @@ Frame locators are strict. This means that all operations on frame locators will
```js ```js
// Throws if there are several frames in DOM: // Throws if there are several frames in DOM:
await page.frameLocator('.result-frame').locator('button').click(); await page.frameLocator('.result-frame').getByRole('button').click();
// Works because we explicitly tell locator to pick the first frame: // Works because we explicitly tell locator to pick the first frame:
await page.frameLocator('.result-frame').first().locator('button').click(); await page.frameLocator('.result-frame').first().getByRole('button').click();
``` ```
```python async ```python async
# Throws if there are several frames in DOM: # Throws if there are several frames in DOM:
await page.frame_locator('.result-frame').locator('button').click() await page.frame_locator('.result-frame').get_by_role('button').click()
# Works because we explicitly tell locator to pick the first frame: # Works because we explicitly tell locator to pick the first frame:
await page.frame_locator('.result-frame').first.locator('button').click() await page.frame_locator('.result-frame').first.get_by_role('button').click()
``` ```
```python sync ```python sync
# Throws if there are several frames in DOM: # Throws if there are several frames in DOM:
page.frame_locator('.result-frame').locator('button').click() page.frame_locator('.result-frame').get_by_role('button').click()
# Works because we explicitly tell locator to pick the first frame: # Works because we explicitly tell locator to pick the first frame:
page.frame_locator('.result-frame').first.locator('button').click() page.frame_locator('.result-frame').first.get_by_role('button').click()
``` ```
```java ```java
// Throws if there are several frames in DOM: // Throws if there are several frames in DOM:
page.frame_locator(".result-frame").locator("button").click(); page.frame_locator(".result-frame").getByRole("button").click();
// Works because we explicitly tell locator to pick the first frame: // Works because we explicitly tell locator to pick the first frame:
page.frame_locator(".result-frame").first().locator("button").click(); page.frame_locator(".result-frame").first().getByRole("button").click();
``` ```
```csharp ```csharp
// Throws if there are several frames in DOM: // Throws if there are several frames in DOM:
await page.FrameLocator(".result-frame").Locator("button").ClickAsync(); await page.FrameLocator(".result-frame").GetByRole("button").ClickAsync();
// Works because we explicitly tell locator to pick the first frame: // Works because we explicitly tell locator to pick the first frame:
await page.FrameLocator(".result-frame").First.Locator("button").ClickAsync(); await page.FrameLocator(".result-frame").First.getByRole("button").ClickAsync();
``` ```
**Converting Locator to FrameLocator** **Converting Locator to FrameLocator**

View file

@ -524,7 +524,7 @@ const rowLocator = page.locator('tr');
// ... // ...
await rowLocator await rowLocator
.filter({ hasText: 'text in column 1' }) .filter({ hasText: 'text in column 1' })
.filter({ has: page.locator('button', { hasText: 'column 2 button' }) }) .filter({ has: page.getByRole('button', { name: 'column 2 button' }) })
.screenshot(); .screenshot();
``` ```
```java ```java
@ -533,7 +533,7 @@ Locator rowLocator = page.locator("tr");
rowLocator rowLocator
.filter(new Locator.FilterOptions().setHasText("text in column 1")) .filter(new Locator.FilterOptions().setHasText("text in column 1"))
.filter(new Locator.FilterOptions().setHas( .filter(new Locator.FilterOptions().setHas(
page.locator("button", new Page.LocatorOptions().setHasText("column 2 button")) page.getByRole("button", new Page.GetByRoleOptions().setName("column 2 button"))
)) ))
.screenshot(); .screenshot();
``` ```
@ -542,7 +542,7 @@ row_locator = page.locator("tr")
# ... # ...
await row_locator await row_locator
.filter(has_text="text in column 1") .filter(has_text="text in column 1")
.filter(has=page.locator("tr", has_text="column 2 button")) .filter(has=page.get_by_role("button", name="column 2 button"))
.screenshot() .screenshot()
``` ```
```python sync ```python sync
@ -550,7 +550,7 @@ row_locator = page.locator("tr")
# ... # ...
row_locator row_locator
.filter(has_text="text in column 1") .filter(has_text="text in column 1")
.filter(has=page.locator("tr", has_text="column 2 button")) .filter(has=page.get_by_role("button", name="column 2 button"))
.screenshot() .screenshot()
``` ```
```csharp ```csharp
@ -559,7 +559,7 @@ var rowLocator = page.Locator("tr");
await rowLocator await rowLocator
.Filter(new LocatorFilterOptions { HasText = "text in column 1" }) .Filter(new LocatorFilterOptions { HasText = "text in column 1" })
.Filter(new LocatorFilterOptions { .Filter(new LocatorFilterOptions {
Has = page.Locator("tr", new PageLocatorOptions { HasText = "column 2 button" } ) Has = page.GetByRole("button", new() { Name = "column 2 button" } )
}) })
.ScreenshotAsync(); .ScreenshotAsync();
``` ```
@ -590,27 +590,27 @@ When working with iframes, you can create a frame locator that will enter the if
in that iframe: in that iframe:
```js ```js
const locator = page.frameLocator('iframe').locator('text=Submit'); const locator = page.frameLocator('iframe').getByText('Submit');
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = page.frameLocator("iframe").locator("text=Submit"); Locator locator = page.frameLocator("iframe").getByText("Submit");
locator.click(); locator.click();
``` ```
```python async ```python async
locator = page.frame_locator("iframe").locator("text=Submit") locator = page.frame_locator("iframe").get_by_text("Submit")
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = page.frame_locator("iframe").locator("text=Submit") locator = page.frame_locator("iframe").get_by_text("Submit")
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = page.FrameLocator("iframe").Locator("text=Submit"); var locator = page.FrameLocator("iframe").GetByText("Submit");
await locator.ClickAsync(); await locator.ClickAsync();
``` ```
@ -1128,32 +1128,32 @@ await element.TypeAsync("World", new() { Delay = 100 }); // Types slower, like a
An example of typing into a text field and then submitting the form: An example of typing into a text field and then submitting the form:
```js ```js
const element = page.locator('input'); const element = page.getByLabelText('Password');
await element.type('some text'); await element.type('my password');
await element.press('Enter'); await element.press('Enter');
``` ```
```java ```java
Locator element = page.locator("input"); Locator element = page.getByLabelText("Password");
element.type("some text"); element.type("my password");
element.press("Enter"); element.press("Enter");
``` ```
```python async ```python async
element = page.locator("input") element = page.get_by_label_text("Password")
await element.type("some text") await element.type("my password")
await element.press("Enter") await element.press("Enter")
``` ```
```python sync ```python sync
element = page.locator("input") element = page.get_by_label_text("Password")
element.type("some text") element.type("my password")
element.press("Enter") element.press("Enter")
``` ```
```csharp ```csharp
var element = page.Locator("input"); var element = page.GetByLabelText("Password");
await element.TypeAsync("some text"); await element.TypeAsync("my password");
await element.PressAsync("Enter"); await element.PressAsync("Enter");
``` ```

View file

@ -8,7 +8,7 @@ import { test, expect } from '@playwright/test';
test('status becomes submitted', async ({ page }) => { test('status becomes submitted', async ({ page }) => {
// ... // ...
await page.locator('#submit-button').click(); await page.getByRole('button').click();
await expect(page.locator('.status')).toHaveText('Submitted'); await expect(page.locator('.status')).toHaveText('Submitted');
}); });
``` ```
@ -22,7 +22,7 @@ public class TestLocator {
@Test @Test
void statusBecomesSubmitted() { void statusBecomesSubmitted() {
... ...
page.locator("#submit-button").click(); page.getByRole("button").click();
assertThat(page.locator(".status")).hasText("Submitted"); assertThat(page.locator(".status")).hasText("Submitted");
} }
} }
@ -33,7 +33,7 @@ from playwright.async_api import Page, expect
async def test_status_becomes_submitted(page: Page) -> None: async def test_status_becomes_submitted(page: Page) -> None:
# .. # ..
await page.locator("#submit-button").click() await page.get_by_role("button").click()
await expect(page.locator(".status")).to_have_text("Submitted") await expect(page.locator(".status")).to_have_text("Submitted")
``` ```
@ -42,7 +42,7 @@ from playwright.sync_api import Page, expect
def test_status_becomes_submitted(page: Page) -> None: def test_status_becomes_submitted(page: Page) -> None:
# .. # ..
page.locator("#submit-button").click() page.get_by_role("button").click()
expect(page.locator(".status")).to_have_text("Submitted") expect(page.locator(".status")).to_have_text("Submitted")
``` ```
@ -61,7 +61,7 @@ public class ExampleTests : PageTest
public async Task StatusBecomesSubmitted() public async Task StatusBecomesSubmitted()
{ {
// .. // ..
await Page.Locator("#submit-button").ClickAsync(); await Page.GetByRole("button").ClickAsync();
await Expect(Page.Locator(".status")).ToHaveTextAsync("Submitted"); await Expect(Page.Locator(".status")).ToHaveTextAsync("Submitted");
} }
} }
@ -404,30 +404,30 @@ Expected options currently selected.
Ensures the [Locator] points to a checked input. Ensures the [Locator] points to a checked input.
```js ```js
const locator = page.locator('.subscribe'); const locator = page.getByLabelText('Subscribe to newsletter');
await expect(locator).toBeChecked(); await expect(locator).toBeChecked();
``` ```
```java ```java
assertThat(page.locator(".subscribe")).isChecked(); assertThat(page.getByLabelText("Subscribe to newsletter")).isChecked();
``` ```
```python async ```python async
from playwright.async_api import expect from playwright.async_api import expect
locator = page.locator(".subscribe") locator = page.get_by_label_text("Subscribe to newsletter")
await expect(locator).to_be_checked() await expect(locator).to_be_checked()
``` ```
```python sync ```python sync
from playwright.sync_api import expect from playwright.sync_api import expect
locator = page.locator(".subscribe") locator = page.get_by_label_text("Subscribe to newsletter")
expect(locator).to_be_checked() expect(locator).to_be_checked()
``` ```
```csharp ```csharp
var locator = Page.Locator(".subscribe"); var locator = Page.GetByLabelText("Subscribe to newsletter");
await Expect(locator).ToBeCheckedAsync(); await Expect(locator).ToBeCheckedAsync();
``` ```
@ -494,30 +494,30 @@ await Expect(locator).ToBeDisabledAsync();
Ensures the [Locator] points to an editable element. Ensures the [Locator] points to an editable element.
```js ```js
const locator = page.locator('input'); const locator = page.getByRole('textbox');
await expect(locator).toBeEditable(); await expect(locator).toBeEditable();
``` ```
```java ```java
assertThat(page.locator("input")).isEditable(); assertThat(page.getByRole("textbox")).isEditable();
``` ```
```python async ```python async
from playwright.async_api import expect from playwright.async_api import expect
locator = page.locator(".input") locator = page.get_by_role("textbox")
await expect(locator).to_be_editable() await expect(locator).to_be_editable()
``` ```
```python sync ```python sync
from playwright.sync_api import expect from playwright.sync_api import expect
locator = page.locator(".input") locator = page.get_by_role("textbox")
expect(locator).to_be_editable() expect(locator).to_be_editable()
``` ```
```csharp ```csharp
var locator = Page.Locator("input"); var locator = Page.GetByRole("textbox");
await Expect(locator).ToBeEditableAsync(); await Expect(locator).ToBeEditableAsync();
``` ```
@ -623,30 +623,30 @@ await Expect(locator).toBeEnabledAsync();
Ensures the [Locator] points to a focused DOM node. Ensures the [Locator] points to a focused DOM node.
```js ```js
const locator = page.locator('input'); const locator = page.getByRole('textbox');
await expect(locator).toBeFocused(); await expect(locator).toBeFocused();
``` ```
```java ```java
assertThat(page.locator("input")).isFocused(); assertThat(page.getByRole("textbox")).isFocused();
``` ```
```python async ```python async
from playwright.async_api import expect from playwright.async_api import expect
locator = page.locator('input') locator = page.get_by_role("textbox")
await expect(locator).to_be_focused() await expect(locator).to_be_focused()
``` ```
```python sync ```python sync
from playwright.sync_api import expect from playwright.sync_api import expect
locator = page.locator('input') locator = page.get_by_role("textbox")
expect(locator).to_be_focused() expect(locator).to_be_focused()
``` ```
```csharp ```csharp
var locator = Page.Locator("input"); var locator = Page.GetByRole("textbox");
await Expect(locator).ToBeFocusedAsync(); await Expect(locator).ToBeFocusedAsync();
``` ```
@ -1105,30 +1105,30 @@ Expected count.
Ensures the [Locator] resolves to an element with the given computed CSS style. Ensures the [Locator] resolves to an element with the given computed CSS style.
```js ```js
const locator = page.locator('button'); const locator = page.getByRole('button');
await expect(locator).toHaveCSS('display', 'flex'); await expect(locator).toHaveCSS('display', 'flex');
``` ```
```java ```java
assertThat(page.locator("button")).hasCSS("display", "flex"); assertThat(page.getByRole("button")).hasCSS("display", "flex");
``` ```
```python async ```python async
from playwright.async_api import expect from playwright.async_api import expect
locator = page.locator("button") locator = page.get_by_role("button")
await expect(locator).to_have_css("display", "flex") await expect(locator).to_have_css("display", "flex")
``` ```
```python sync ```python sync
from playwright.sync_api import expect from playwright.sync_api import expect
locator = page.locator("button") locator = page.get_by_role("button")
expect(locator).to_have_css("display", "flex") expect(locator).to_have_css("display", "flex")
``` ```
```csharp ```csharp
var locator = Page.Locator("button"); var locator = Page.GetByRole("button");
await Expect(locator).ToHaveCSSAsync("display", "flex"); await Expect(locator).ToHaveCSSAsync("display", "flex");
``` ```
@ -1157,30 +1157,30 @@ CSS property value.
Ensures the [Locator] points to an element with the given DOM Node ID. Ensures the [Locator] points to an element with the given DOM Node ID.
```js ```js
const locator = page.locator('input'); const locator = page.getByRole('textbox');
await expect(locator).toHaveId('lastname'); await expect(locator).toHaveId('lastname');
``` ```
```java ```java
assertThat(page.locator("input")).hasId("lastname"); assertThat(page.getByRole("textbox")).hasId("lastname");
``` ```
```python async ```python async
from playwright.async_api import expect from playwright.async_api import expect
locator = page.locator("input") locator = page.get_by_role("textbox")
await expect(locator).to_have_id("lastname") await expect(locator).to_have_id("lastname")
``` ```
```python sync ```python sync
from playwright.sync_api import expect from playwright.sync_api import expect
locator = page.locator("input") locator = page.get_by_role("textbox")
expect(locator).to_have_id("lastname") expect(locator).to_have_id("lastname")
``` ```
```csharp ```csharp
var locator = Page.Locator("input"); var locator = Page.GetByRole("textbox");
await Expect(locator).ToHaveIdAsync("lastname"); await Expect(locator).ToHaveIdAsync("lastname");
``` ```
@ -1258,7 +1258,7 @@ This function will wait until two consecutive locator screenshots
yield the same result, and then compare the last screenshot with the expectation. yield the same result, and then compare the last screenshot with the expectation.
```js ```js
const locator = page.locator('button'); const locator = page.getByRole('button');
await expect(locator).toHaveScreenshot('image.png'); await expect(locator).toHaveScreenshot('image.png');
``` ```
@ -1296,7 +1296,7 @@ This function will wait until two consecutive locator screenshots
yield the same result, and then compare the last screenshot with the expectation. yield the same result, and then compare the last screenshot with the expectation.
```js ```js
const locator = page.locator('button'); const locator = page.getByRole('button');
await expect(locator).toHaveScreenshot(); await expect(locator).toHaveScreenshot();
``` ```

View file

@ -2128,27 +2128,27 @@ in that iframe. Following snippet locates element with text "Submit" in the ifra
like `<iframe id="my-frame">`: like `<iframe id="my-frame">`:
```js ```js
const locator = page.frameLocator('#my-iframe').locator('text=Submit'); const locator = page.frameLocator('#my-iframe').getByText('Submit');
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = page.frameLocator("#my-iframe").locator("text=Submit"); Locator locator = page.frameLocator("#my-iframe").getByText("Submit");
locator.click(); locator.click();
``` ```
```python async ```python async
locator = page.frame_locator("#my-iframe").locator("text=Submit") locator = page.frame_locator("#my-iframe").get_by_text("Submit")
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = page.frame_locator("#my-iframe").locator("text=Submit") locator = page.frame_locator("#my-iframe").get_by_text("Submit")
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = page.FrameLocator("#my-iframe").Locator("text=Submit"); var locator = page.FrameLocator("#my-iframe").GetByText("Submit");
await locator.ClickAsync(); await locator.ClickAsync();
``` ```
@ -3672,19 +3672,19 @@ const [frame, _] = await Promise.all([
// It is important to call waitForEvent before click to set up waiting. // It is important to call waitForEvent before click to set up waiting.
page.waitForEvent('framenavigated'), page.waitForEvent('framenavigated'),
// Triggers the navigation. // Triggers the navigation.
page.locator('button').click(), page.getByRole('button').click(),
]); ]);
``` ```
```python async ```python async
async with page.expect_event("framenavigated") as event_info: async with page.expect_event("framenavigated") as event_info:
await page.click("button") await page.get_by_role("button")
frame = await event_info.value frame = await event_info.value
``` ```
```python sync ```python sync
with page.expect_event("framenavigated") as event_info: with page.expect_event("framenavigated") as event_info:
page.click("button") page.get_by_role("button")
frame = event_info.value frame = event_info.value
``` ```
@ -3865,27 +3865,27 @@ This resolves when the page reaches a required load state, `load` by default. Th
when this method is called. If current document has already reached the required state, resolves immediately. when this method is called. If current document has already reached the required state, resolves immediately.
```js ```js
await page.click('button'); // Click triggers navigation. await page.getByRole('button').click(); // Click triggers navigation.
await page.waitForLoadState(); // The promise resolves after 'load' event. await page.waitForLoadState(); // The promise resolves after 'load' event.
``` ```
```java ```java
page.click("button"); // Click triggers navigation. page.getByRole("button").click(); // Click triggers navigation.
page.waitForLoadState(); // The promise resolves after "load" event. page.waitForLoadState(); // The promise resolves after "load" event.
``` ```
```python async ```python async
await page.click("button") # click triggers navigation. await page.get_by_role("button").click() # click triggers navigation.
await page.wait_for_load_state() # the promise resolves after "load" event. await page.wait_for_load_state() # the promise resolves after "load" event.
``` ```
```python sync ```python sync
page.click("button") # click triggers navigation. page.get_by_role("button").click() # click triggers navigation.
page.wait_for_load_state() # the promise resolves after "load" event. page.wait_for_load_state() # the promise resolves after "load" event.
``` ```
```csharp ```csharp
await page.ClickAsync("button"); // Click triggers navigation. await page.GetByRole("button").ClickAsync(); // Click triggers navigation.
await page.WaitForLoadStateAsync(); // The promise resolves after 'load' event. await page.WaitForLoadStateAsync(); // The promise resolves after 'load' event.
``` ```
@ -3894,7 +3894,7 @@ const [popup] = await Promise.all([
// It is important to call waitForEvent before click to set up waiting. // It is important to call waitForEvent before click to set up waiting.
page.waitForEvent('popup'), page.waitForEvent('popup'),
// Click triggers a popup. // Click triggers a popup.
page.locator('button').click(), page.getByRole('button').click(),
]) ])
await popup.waitForLoadState('domcontentloaded'); // The promise resolves after 'domcontentloaded' event. await popup.waitForLoadState('domcontentloaded'); // The promise resolves after 'domcontentloaded' event.
console.log(await popup.title()); // Popup is ready to use. console.log(await popup.title()); // Popup is ready to use.
@ -3902,7 +3902,7 @@ console.log(await popup.title()); // Popup is ready to use.
```java ```java
Page popup = page.waitForPopup(() -> { Page popup = page.waitForPopup(() -> {
page.click("button"); // Click triggers a popup. page.getByRole("button").click(); // Click triggers a popup.
}); });
popup.waitForLoadState(LoadState.DOMCONTENTLOADED); popup.waitForLoadState(LoadState.DOMCONTENTLOADED);
System.out.println(popup.title()); // Popup is ready to use. System.out.println(popup.title()); // Popup is ready to use.
@ -3910,7 +3910,7 @@ System.out.println(popup.title()); // Popup is ready to use.
```python async ```python async
async with page.expect_popup() as page_info: async with page.expect_popup() as page_info:
await page.click("button") # click triggers a popup. await page.get_by_role("button").click() # click triggers a popup.
popup = await page_info.value popup = await page_info.value
# Following resolves after "domcontentloaded" event. # Following resolves after "domcontentloaded" event.
await popup.wait_for_load_state("domcontentloaded") await popup.wait_for_load_state("domcontentloaded")
@ -3919,7 +3919,7 @@ print(await popup.title()) # popup is ready to use.
```python sync ```python sync
with page.expect_popup() as page_info: with page.expect_popup() as page_info:
page.click("button") # click triggers a popup. page.get_by_role("button").click() # click triggers a popup.
popup = page_info.value popup = page_info.value
# Following resolves after "domcontentloaded" event. # Following resolves after "domcontentloaded" event.
popup.wait_for_load_state("domcontentloaded") popup.wait_for_load_state("domcontentloaded")
@ -3929,7 +3929,7 @@ print(popup.title()) # popup is ready to use.
```csharp ```csharp
var popup = await page.RunAndWaitForPopupAsync(async () => var popup = await page.RunAndWaitForPopupAsync(async () =>
{ {
await page.ClickAsync("button"); // click triggers the popup/ await page.GetByRole("button").ClickAsync(); // click triggers the popup/
}); });
await popup.WaitForLoadStateAsync(LoadState.DOMContentLoaded); await popup.WaitForLoadStateAsync(LoadState.DOMContentLoaded);
Console.WriteLine(await popup.TitleAsync()); // popup is ready to use. Console.WriteLine(await popup.TitleAsync()); // popup is ready to use.

View file

@ -8,7 +8,7 @@ import { test, expect } from '@playwright/test';
test('navigates to login', async ({ page }) => { test('navigates to login', async ({ page }) => {
// ... // ...
await page.locator('#login').click(); await page.getByText('Sign in').click();
await expect(page).toHaveURL(/.*\/login/); await expect(page).toHaveURL(/.*\/login/);
}); });
``` ```
@ -22,7 +22,7 @@ public class TestPage {
@Test @Test
void navigatesToLoginPage() { void navigatesToLoginPage() {
... ...
page.locator("#login").click(); page.getByText("Sign in").click();
assertThat(page).hasURL(Pattern.compile(".*/login")); assertThat(page).hasURL(Pattern.compile(".*/login"));
} }
} }
@ -34,7 +34,7 @@ from playwright.async_api import Page, expect
async def test_navigates_to_login_page(page: Page) -> None: async def test_navigates_to_login_page(page: Page) -> None:
# .. # ..
await page.locator("#login").click() await page.get_by_text("Sign in").click()
await expect(page).to_have_url(re.compile(r".*/login")) await expect(page).to_have_url(re.compile(r".*/login"))
``` ```
@ -44,7 +44,7 @@ from playwright.sync_api import Page, expect
def test_navigates_to_login_page(page: Page) -> None: def test_navigates_to_login_page(page: Page) -> None:
# .. # ..
page.locator("#login").click() page.get_by_text("Sign in").click()
expect(page).to_have_url(re.compile(r".*/login")) expect(page).to_have_url(re.compile(r".*/login"))
``` ```
@ -63,7 +63,7 @@ public class ExampleTests : PageTest
public async Task NavigatetoLoginPage() public async Task NavigatetoLoginPage()
{ {
// .. // ..
await Page.Locator("#login").ClickAsync(); await Page.GetByText("Sing in").ClickAsync();
await Expect(Page.Locator("div#foobar")).ToHaveURL(new Regex(".*/login")); await Expect(Page.Locator("div#foobar")).ToHaveURL(new Regex(".*/login"));
} }
} }

View file

@ -167,7 +167,7 @@ const page = await context.newPage();
await page.goto('https://playwright.dev'); await page.goto('https://playwright.dev');
await context.tracing.startChunk(); await context.tracing.startChunk();
await page.locator('text=Get Started').click(); await page.getByText('Get Started').click();
// Everything between startChunk and stopChunk will be recorded in the trace. // Everything between startChunk and stopChunk will be recorded in the trace.
await context.tracing.stopChunk({ path: 'trace1.zip' }); await context.tracing.stopChunk({ path: 'trace1.zip' });
@ -185,7 +185,7 @@ Page page = context.newPage();
page.navigate("https://playwright.dev"); page.navigate("https://playwright.dev");
context.tracing().startChunk(); context.tracing().startChunk();
page.locator("text=Get Started").click(); page.getByText("Get Started").click();
// Everything between startChunk and stopChunk will be recorded in the trace. // Everything between startChunk and stopChunk will be recorded in the trace.
context.tracing().stopChunk(new Tracing.StopChunkOptions() context.tracing().stopChunk(new Tracing.StopChunkOptions()
.setPath(Paths.get("trace1.zip"))); .setPath(Paths.get("trace1.zip")));
@ -203,7 +203,7 @@ page = await context.new_page()
await page.goto("https://playwright.dev") await page.goto("https://playwright.dev")
await context.tracing.start_chunk() await context.tracing.start_chunk()
await page.locator("text=Get Started").click() await page.get_by_text("Get Started").click()
# Everything between start_chunk and stop_chunk will be recorded in the trace. # Everything between start_chunk and stop_chunk will be recorded in the trace.
await context.tracing.stop_chunk(path = "trace1.zip") await context.tracing.stop_chunk(path = "trace1.zip")
@ -219,7 +219,7 @@ page = context.new_page()
page.goto("https://playwright.dev") page.goto("https://playwright.dev")
context.tracing.start_chunk() context.tracing.start_chunk()
page.locator("text=Get Started").click() page.get_by_text("Get Started").click()
# Everything between start_chunk and stop_chunk will be recorded in the trace. # Everything between start_chunk and stop_chunk will be recorded in the trace.
context.tracing.stop_chunk(path = "trace1.zip") context.tracing.stop_chunk(path = "trace1.zip")
@ -241,7 +241,7 @@ var page = context.NewPageAsync();
await page.GotoAsync("https://playwright.dev"); await page.GotoAsync("https://playwright.dev");
await context.Tracing.StartChunkAsync(); await context.Tracing.StartChunkAsync();
await page.ClickAsync("text=Get Started"); await page.GetByText("Get Started").ClickAsync();
// Everything between StartChunkAsync and StopChunkAsync will be recorded in the trace. // Everything between StartChunkAsync and StopChunkAsync will be recorded in the trace.
await context.Tracing.StopChunkAsync(new() await context.Tracing.StopChunkAsync(new()
{ {

View file

@ -22,10 +22,10 @@ import { test } from '@playwright/test';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
// Runs before each test and signs in each page. // Runs before each test and signs in each page.
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('text=Login').click(); await page.getByText('Login').click();
await page.locator('input[name="login"]').fill('username'); await page.getByLabelText('User Name').fill('username');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Submit').click(); await page.getByText('Submit').click();
}); });
test('first', async ({ page }) => { test('first', async ({ page }) => {
@ -43,10 +43,10 @@ const { test } = require('@playwright/test');
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
// Runs before each test and signs in each page. // Runs before each test and signs in each page.
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('text=Login').click(); await page.getByText('Login').click();
await page.locator('input[name="login"]').fill('username'); await page.getByLabelText('User name').fill('username');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Submit').click(); await page.getByText('Submit').click();
}); });
test('first', async ({ page }) => { test('first', async ({ page }) => {
@ -63,10 +63,10 @@ const page = await context.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
// Interact with login form // Interact with login form
await page.locator('text=Login').click(); await page.getByText('Login').click();
await page.locator('input[name="login"]').fill(USERNAME); await page.getByLabelText('User Name').fill(USERNAME);
await page.locator('input[name="password"]').fill(PASSWORD); await page.getByLabelText('Password').fill(PASSWORD);
await page.locator('text=Submit').click(); await page.getByText('Submit').click();
// Continue with the test // Continue with the test
``` ```
@ -74,9 +74,9 @@ await page.locator('text=Submit').click();
Page page = context.newPage(); Page page = context.newPage();
page.navigate("https://github.com/login"); page.navigate("https://github.com/login");
// Interact with login form // Interact with login form
page.locator("text=Login").click(); page.getByText("Login").click();
page.locator("input[name='login']").fill(USERNAME); page.getByLabelText("User Name").fill(USERNAME);
page.locator("input[name='password']").fill(PASSWORD); page.getByLabelText("Password").fill(PASSWORD);
page.locator("text=Submit").click(); page.locator("text=Submit").click();
// Continue with the test // Continue with the test
``` ```
@ -86,10 +86,10 @@ page = await context.new_page()
await page.goto('https://github.com/login') await page.goto('https://github.com/login')
# Interact with login form # Interact with login form
await page.locator('text=Login').click() await page.get_by_text("Login").click()
await page.locator('input[name="login"]').fill(USERNAME) await page.get_by_label_text("User Name").fill(USERNAME)
await page.locator('input[name="password"]').fill(PASSWORD) await page.get_by_label_text("Password").fill(PASSWORD)
await page.locator('text=Submit').click() await page.get_by_text('Submit').click()
# Continue with the test # Continue with the test
``` ```
@ -98,10 +98,10 @@ page = context.new_page()
page.goto('https://github.com/login') page.goto('https://github.com/login')
# Interact with login form # Interact with login form
page.locator('text=Login').click() page.get_by_text("Login").click()
page.locator('input[name="login"]').fill(USERNAME) page.get_by_label_text("User Name").fill(USERNAME)
page.locator('input[name="password"]').fill(PASSWORD) page.get_by_label_text("Password").fill(PASSWORD)
page.locator('text=Submit').click() page.get_by_text('Submit').click()
# Continue with the test # Continue with the test
``` ```
@ -109,10 +109,10 @@ page.locator('text=Submit').click()
var page = await context.NewPageAsync(); var page = await context.NewPageAsync();
await page.GotoAsync("https://github.com/login"); await page.GotoAsync("https://github.com/login");
// Interact with login form // Interact with login form
await page.Locator("text=Login").ClickAsync(); await page.GetByText("Login").ClickAsync();
await page.Locator("input[name='login']").FillAsync(USERNAME); await page.GetByLabelText("User Name").FillAsync(USERNAME);
await page.Locator("input[name='password']").FillAsync(PASSWORD); await page.GetByLabelText("Password").FillAsync(PASSWORD);
await page.Locator("text=Submit").ClickAsync(); await page.GetByText("Submit").ClickAsync();
// Continue with the test // Continue with the test
``` ```
@ -189,9 +189,9 @@ module.exports = async config => {
const browser = await chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="login"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
// Save signed-in state to 'storageState.json'. // Save signed-in state to 'storageState.json'.
await page.context().storageState({ path: 'storageState.json' }); await page.context().storageState({ path: 'storageState.json' });
await browser.close(); await browser.close();
@ -206,9 +206,9 @@ async function globalSetup(config: FullConfig) {
const browser = await chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="login"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
// Save signed-in state to 'storageState.json'. // Save signed-in state to 'storageState.json'.
await page.context().storageState({ path: 'storageState.json' }); await page.context().storageState({ path: 'storageState.json' });
await browser.close(); await browser.close();
@ -339,9 +339,9 @@ exports.test = base.extend({
// Make sure we are not using any other storage state. // Make sure we are not using any other storage state.
const page = await browser.newPage({ storageState: undefined }); const page = await browser.newPage({ storageState: undefined });
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="login"]').fill(users[testInfo.workerIndex].username); await page.getByLabelText('User Name').fill(users[testInfo.workerIndex].username);
await page.locator('input[name="password"]').fill(users[testInfo.workerIndex].password); await page.getByLabelText('Password').fill(users[testInfo.workerIndex].password);
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await page.context().storageState({ path: fileName }); await page.context().storageState({ path: fileName });
await page.close(); await page.close();
} }
@ -378,9 +378,9 @@ export const test = baseTest.extend({
const page = await browser.newPage({ storageState: undefined }); const page = await browser.newPage({ storageState: undefined });
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
// Create a unique username for each worker. // Create a unique username for each worker.
await page.locator('input[name="login"]').fill(users[testInfo.workerIndex].username); await page.getByLabelText('User Name').fill(users[testInfo.workerIndex].username);
await page.locator('input[name="password"]').fill(users[testInfo.workerIndex].password); await page.getByLabelText('Password').fill(users[testInfo.workerIndex].password);
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await page.context().storageState({ path: fileName }); await page.context().storageState({ path: fileName });
await page.close(); await page.close();
} }
@ -675,9 +675,9 @@ test.beforeAll(async ({ browser }) => {
// Create page yourself and sign in. // Create page yourself and sign in.
page = await browser.newPage(); page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
}); });
test.afterAll(async () => { test.afterAll(async () => {
@ -706,9 +706,9 @@ test.beforeAll(async ({ browser }) => {
// Create page once and sign in. // Create page once and sign in.
page = await browser.newPage(); page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
}); });
test.afterAll(async () => { test.afterAll(async () => {
@ -909,7 +909,7 @@ class Program
The following code snippet retrieves state from an authenticated context and creates a new context with that state. The following code snippet retrieves state from an authenticated context and creates a new context with that state.
```js ```js
// Save storage state into the file. // Save storage state into the file.
await context.storageState({ path: 'state.json' }); await context.storageState({ path: 'state.json' });

View file

@ -11,27 +11,27 @@ By default, dialogs are auto-dismissed by Playwright, so you don't have to handl
```js ```js
page.on('dialog', dialog => dialog.accept()); page.on('dialog', dialog => dialog.accept());
await page.locator('button').click(); await page.getByRole('button').click();
``` ```
```java ```java
page.onDialog(dialog -> dialog.accept()); page.onDialog(dialog -> dialog.accept());
page.locator("button").click(); page.getByRole("button").click();
``` ```
```python async ```python async
page.on("dialog", lambda dialog: dialog.accept()) page.on("dialog", lambda dialog: dialog.accept())
await page.locator("button".click()) await page.get_by_role("button".click())
``` ```
```python sync ```python sync
page.on("dialog", lambda dialog: dialog.accept()) page.on("dialog", lambda dialog: dialog.accept())
page.locator("button").click() page.get_by_role("button").click()
``` ```
```csharp ```csharp
page.Dialog += (_, dialog) => dialog.AcceptAsync(); page.Dialog += (_, dialog) => dialog.AcceptAsync();
await page.Locator("button").ClickAsync(); await page.GetByRole("button").ClickAsync();
``` ```
:::note :::note
@ -46,27 +46,27 @@ WRONG!
```js ```js
page.on('dialog', dialog => console.log(dialog.message())); page.on('dialog', dialog => console.log(dialog.message()));
await page.locator('button').click(); // Will hang here await page.getByRole('button').click(); // Will hang here
``` ```
```java ```java
page.onDialog(dialog -> System.out.println(dialog.message())); page.onDialog(dialog -> System.out.println(dialog.message()));
page.locator("button").click(); // Will hang here page.getByRole("button").click(); // Will hang here
``` ```
```python async ```python async
page.on("dialog", lambda dialog: print(dialog.message)) page.on("dialog", lambda dialog: print(dialog.message))
await page.locator("button").click() # Will hang here await page.get_by_role("button").click() # Will hang here
``` ```
```python sync ```python sync
page.on("dialog", lambda dialog: print(dialog.message)) page.on("dialog", lambda dialog: print(dialog.message))
page.locator("button").click() # Will hang here page.get_by_role("button").click() # Will hang here
``` ```
```csharp ```csharp
page.Dialog += (_, dialog) => Console.WriteLine(dialog.Message); page.Dialog += (_, dialog) => Console.WriteLine(dialog.Message);
await page.Locator("button").ClickAsync(); // Will hang here await page.GetByRole("button").ClickAsync(); // Will hang here
``` ```
:::note :::note

View file

@ -11,32 +11,32 @@ inside the frame.
```js ```js
// Locate element inside frame // Locate element inside frame
const username = await page.frameLocator('.frame-class').locator('#username-input'); const username = await page.frameLocator('.frame-class').getByLabelText('User Name');
await username.fill('John'); await username.fill('John');
``` ```
```java ```java
// Locate element inside frame // Locate element inside frame
Locator username = page.frameLocator(".frame-class").locator("#username-input"); Locator username = page.frameLocator(".frame-class").getByLabelText("User Name");
username.fill("John"); username.fill("John");
``` ```
```python async ```python async
# Locate element inside frame # Locate element inside frame
username = await page.frame_locator('.frame-class').locator('#username-input') username = await page.frame_locator('.frame-class').get_by_label_text('User Name')
await username.fill('John') await username.fill('John')
``` ```
```python sync ```python sync
# Locate element inside frame # Locate element inside frame
# Get frame using any other selector # Get frame using any other selector
username = page.frame_locator('.frame-class').locator('#username-input') username = page.frame_locator('.frame-class').get_by_label_text('User Name')
username.fill('John') username.fill('John')
``` ```
```csharp ```csharp
// Locate element inside frame // Locate element inside frame
var username = await page.FrameLocator(".frame-class").Locator("#username-input"); var username = await page.FrameLocator(".frame-class").GetByLabelText("User Name");
await username.FillAsync("John"); await username.FillAsync("John");
``` ```

View file

@ -7,165 +7,135 @@ Playwright can interact with HTML Input elements such as text inputs, checkboxes
## Text input ## Text input
Using [`method: Locator.fill`] is the easiest way to fill out the form fields. It focuses the element and triggers an `input` event with the entered text. It works for `<input>`, `<textarea>`, `[contenteditable]` and `<label>` associated with an input or textarea. Using [`method: Locator.fill`] is the easiest way to fill out the form fields. It focuses the element and triggers an `input` event with the entered text. It works for `<input>`, `<textarea>` and `[contenteditable]` elements.
```js ```js
// Text input // Text input
await page.locator('#name').fill('Peter'); await page.getByRole('textbox').fill('Peter');
// Date input // Date input
await page.locator('#date').fill('2020-02-02'); await page.getByLabelText('Birth date').fill('2020-02-02');
// Time input // Time input
await page.locator('#time').fill('13:15'); await page.getByLabelText('Appointment time').fill('13:15');
// Local datetime input // Local datetime input
await page.locator('#local').fill('2020-03-02T05:15'); await page.getByLabelText('Local time').fill('2020-03-02T05:15');
// Input through label
await page.locator('text=First Name').fill('Peter');
``` ```
```java ```java
// Text input // Text input
page.locator("#name").fill("Peter"); page.getByRole("textbox").fill("Peter");
// Date input // Date input
page.locator("#date").fill("2020-02-02"); page.getByLabelText("Birth date").fill("2020-02-02");
// Time input // Time input
page.locator("#time").fill("13-15"); page.getByLabelText("Appointment time").fill("13-15");
// Local datetime input // Local datetime input
page.locator("#local").fill("2020-03-02T05:15"); page.getByLabelText("Local time").fill("2020-03-02T05:15");
// Input through label
page.locator("text=First Name").fill("Peter");
``` ```
```python async ```python async
# Text input # Text input
await page.locator('#name').fill('Peter') await page.get_by_role("textbox").fill("Peter")
# Date input # Date input
await page.locator('#date').fill('2020-02-02') await page.get_by_label_text("Birth date").fill("2020-02-02")
# Time input # Time input
await page.locator('#time').fill('13:15') await page.get_by_label_text("Appointment time").fill("13:15")
# Local datetime input # Local datetime input
await page.locator('#local').fill('2020-03-02T05:15') await page.get_by_label_text("Local time").fill("2020-03-02T05:15")
# Input through label
await page.locator('text=First Name').fill('Peter')
``` ```
```python sync ```python sync
# Text input # Text input
page.locator('#name').fill('Peter') page.get_by_role("textbox").fill("Peter")
# Date input # Date input
page.locator('#date').fill('2020-02-02') page.get_by_label_text("Birth date").fill("2020-02-02")
# Time input # Time input
page.locator('#time').fill('13:15') page.get_by_label_text("Appointment time").fill("13:15")
# Local datetime input # Local datetime input
page.locator('#local').fill('2020-03-02T05:15') page.get_by_label_text("Local time").fill("2020-03-02T05:15")
# Input through label
page.locator('text=First Name').fill('Peter')
``` ```
```csharp ```csharp
// Text input // Text input
await page.Locator("#name").FillAsync("Peter"); await page.GetByRole("textbox").FillAsync("Peter");
// Date input // Date input
await page.Locator("#date").FillAsync("2020-02-02"); await page.GetByLabelText("Birth date").FillAsync("2020-02-02");
// Time input // Time input
await page.Locator("#time").FillAsync("13-15"); await page.GetByLabelText("Appointment time").FillAsync("13-15");
// Local datetime input // Local datetime input
await page.Locator("#local").FillAsync("2020-03-02T05:15"); await page.GetByLabelText("Local time").FillAsync("2020-03-02T05:15");
// Input through label
await page.Locator("text=First Name").FillAsync("Peter");
``` ```
## Checkboxes and radio buttons ## Checkboxes and radio buttons
Using [`method: Locator.setChecked`] is the easiest way to check and uncheck a checkbox or a radio button. This method can be used with `input[type=checkbox]`, `input[type=radio]`, `[role=checkbox]` or `label` associated with checkbox or radio button. Using [`method: Locator.setChecked`] is the easiest way to check and uncheck a checkbox or a radio button. This method can be used with `input[type=checkbox]`, `input[type=radio]` and `[role=checkbox]` elements.
```js ```js
// Check the checkbox // Check the checkbox
await page.locator('#agree').check(); await page.getByLabelText('I agree to the terms above').check();
// Assert the checked state // Assert the checked state
expect(await page.locator('#agree').isChecked()).toBeTruthy() expect(await page.getByLabelText('Subscribe to newsletter').isChecked()).toBeTruthy()
// Uncheck by input <label>.
await page.locator('#subscribe-label').uncheck();
// Select the radio button // Select the radio button
await page.locator('text=XL').check(); await page.getByLabelText('XL').check();
``` ```
```java ```java
// Check the checkbox // Check the checkbox
page.locator("#agree").check(); page.getByLabelText("I agree to the terms above").check();
// Assert the checked state // Assert the checked state
assertTrue(page.locator("#agree").isChecked()); assertTrue(page.getByLabelText("Subscribe to newsletter").isChecked());
// Uncheck by input <label>.
page.locator("#subscribe-label").uncheck();
// Select the radio button // Select the radio button
page.locator("text=XL").check(); page.getByLabelText("XL").check();
``` ```
```python async ```python async
# Check the checkbox # Check the checkbox
await page.locator('#agree').check() await page.get_by_label_text('I agree to the terms above').check()
# Assert the checked state # Assert the checked state
assert await page.locator('#agree').is_checked() is True assert await page.get_by_label_text('Subscribe to newsletter').is_checked() is True
# Uncheck by input <label>.
await page.locator('#subscribe-label').uncheck()
# Select the radio button # Select the radio button
await page.locator('text=XL').check() await page.get_by_label_text('XL').check()
``` ```
```python sync ```python sync
# Check the checkbox # Check the checkbox
page.locator('#agree').check() page.get_by_label_text('I agree to the terms above').check()
# Assert the checked state # Assert the checked state
assert page.locator('#agree').is_checked() is True assert page.get_by_label_text('Subscribe to newsletter').is_checked() is True
# Uncheck by input <label>.
page.locator('#subscribe-label').uncheck()
# Select the radio button # Select the radio button
page.locator('text=XL').check() page.get_by_label_text('XL').check()
``` ```
```csharp ```csharp
// Check the checkbox // Check the checkbox
await page.Locator("#agree").CheckAsync(); await page.GetByLabelText("I agree to the terms above").CheckAsync();
// Assert the checked state // Assert the checked state
Assert.True(await page.Locator("#agree").IsCheckedAsync()); Assert.True(await page.GetByLabelText("Subscribe to newsletter").IsCheckedAsync());
// Uncheck by input <label>.
await page.Locator("#subscribe-label").UncheckAsync();
// Select the radio button // Select the radio button
await page.Locator("text=XL").CheckAsync(); await page.GetByLabelText("XL").CheckAsync();
``` ```
## Select options ## Select options
@ -175,57 +145,57 @@ You can specify option `value`, or `label` to select. Multiple options can be se
```js ```js
// Single selection matching the value // Single selection matching the value
await page.locator('select#colors').selectOption('blue'); await page.getByLabelText('Choose a color').selectOption('blue');
// Single selection matching the label // Single selection matching the label
await page.locator('select#colors').selectOption({ label: 'Blue' }); await page.getByLabelText('Choose a color').selectOption({ label: 'Blue' });
// Multiple selected items // Multiple selected items
await page.locator('select#colors').selectOption(['red', 'green', 'blue']); await page.getByLabelText('Choose multiple colors').selectOption(['red', 'green', 'blue']);
``` ```
```java ```java
// Single selection matching the value // Single selection matching the value
page.locator("select#colors").selectOption("blue"); page.getByLabelText("Choose a color").selectOption("blue");
// Single selection matching the label // Single selection matching the label
page.locator("select#colors").selectOption(new SelectOption().setLabel("Blue")); page.getByLabelText("Choose a color").selectOption(new SelectOption().setLabel("Blue"));
// Multiple selected items // Multiple selected items
page.locator("select#colors").selectOption(new String[] {"red", "green", "blue"}); page.getByLabelText("Choose multiple colors").selectOption(new String[] {"red", "green", "blue"});
``` ```
```python async ```python async
# Single selection matching the value # Single selection matching the value
await page.locator('select#colors').select_option('blue') await page.get_by_label_text('Choose a color').select_option('blue')
# Single selection matching the label # Single selection matching the label
await page.locator('select#colors').select_option(label='Blue') await page.get_by_label_text('Choose a color').select_option(label='Blue')
# Multiple selected items # Multiple selected items
await page.locator('select#colors').select_option(['red', 'green', 'blue']) await page.get_by_label_text('Choose multiple colors').select_option(['red', 'green', 'blue'])
``` ```
```python sync ```python sync
# Single selection matching the value # Single selection matching the value
page.locator('select#colors').select_option('blue') page.get_by_label_text('Choose a color').select_option('blue')
# Single selection matching the label # Single selection matching the label
page.locator('select#colors').select_option(label='Blue') page.get_by_label_text('Choose a color').select_option(label='Blue')
# Multiple selected items # Multiple selected items
page.locator('select#colors').select_option(['red', 'green', 'blue']) page.get_by_label_text('Choose multiple colors').select_option(['red', 'green', 'blue'])
``` ```
```csharp ```csharp
// Single selection matching the value // Single selection matching the value
await page.Locator("select#colors").SelectOptionAsync("blue"); await page.GetByLabelText("Choose a color").SelectOptionAsync("blue");
// Single selection matching the label // Single selection matching the label
await page.Locator("select#colors").SelectOptionAsync(new SelectOptionValue { Label = "blue" })); await page.GetByLabelText("Choose a color").SelectOptionAsync(new SelectOptionValue { Label = "blue" }));
// Multiple selected items // Multiple selected items
await page.Locator("select#colors").SelectOptionAsync(new[] { "blue", "green", "red" }); await page.GetByLabelText("Choose multiple colors").SelectOptionAsync(new[] { "blue", "green", "red" });
``` ```
## Mouse click ## Mouse click
@ -234,102 +204,102 @@ Performs a simple human click.
```js ```js
// Generic click // Generic click
await page.locator('button#submit').click(); await page.getByRole('button').click();
// Double click // Double click
await page.locator('#item').dblclick(); await page.getByText('Item').dblclick();
// Right click // Right click
await page.locator('#item').click({ button: 'right' }); await page.getByText('Item').click({ button: 'right' });
// Shift + click // Shift + click
await page.locator('#item').click({ modifiers: ['Shift'] }); await page.getByText('Item').click({ modifiers: ['Shift'] });
// Hover over element // Hover over element
await page.locator('#item').hover(); await page.getByText('Item').hover();
// Click the top left corner // Click the top left corner
await page.locator('#item').click({ position: { x: 0, y: 0} }); await page.getByText('Item').click({ position: { x: 0, y: 0} });
``` ```
```java ```java
// Generic click // Generic click
page.locator("button#submit").click(); page.getByRole("button").click();
// Double click // Double click
page.locator("#item").dblclick(); page.getByText("Item").dblclick();
// Right click // Right click
page.locator("#item").click(new Locator.ClickOptions().setButton(MouseButton.RIGHT)); page.getByText("Item").click(new Locator.ClickOptions().setButton(MouseButton.RIGHT));
// Shift + click // Shift + click
page.locator("#item").click(new Locator.ClickOptions().setModifiers(Arrays.asList(KeyboardModifier.SHIFT))); page.getByText("Item").click(new Locator.ClickOptions().setModifiers(Arrays.asList(KeyboardModifier.SHIFT)));
// Hover over element // Hover over element
page.locator("#item").hover(); page.getByText("Item").hover();
// Click the top left corner // Click the top left corner
page.locator("#item").click(new Locator.ClickOptions().setPosition(0, 0)); page.getByText("Item").click(new Locator.ClickOptions().setPosition(0, 0));
``` ```
```python async ```python async
# Generic click # Generic click
await page.locator('button#submit').click() await page.get_by_role("button").click()
# Double click # Double click
await page.locator('#item').dblclick() await page.get_by_text("Item").dblclick()
# Right click # Right click
await page.locator('#item').click(button='right') await page.get_by_text("Item").click(button="right")
# Shift + click # Shift + click
await page.locator('#item').click(modifiers=['Shift']) await page.get_by_text("Item").click(modifiers=["Shift"])
# Hover over element # Hover over element
await page.locator('#item').hover() await page.get_by_text("Item").hover()
# Click the top left corner # Click the top left corner
await page.locator('#item').click(position={ 'x': 0, 'y': 0}) await page.get_by_text("Item").click(position={ "x": 0, "y": 0})
``` ```
```python sync ```python sync
# Generic click # Generic click
page.locator('button#submit').click() page.get_by_role("button").click()
# Double click # Double click
page.locator('#item').dblclick() page.get_by_text("Item").dblclick()
# Right click # Right click
page.locator('#item').click(button='right') page.get_by_text("Item").click(button="right")
# Shift + click # Shift + click
page.locator('#item').click(modifiers=['Shift']) page.get_by_text("Item").click(modifiers=["Shift"])
# Hover over element # Hover over element
page.locator('#item').hover() page.get_by_text("Item").hover()
# Click the top left corner # Click the top left corner
page.locator('#item').click(position={ 'x': 0, 'y': 0}) page.get_by_text("Item").click(position={ "x": 0, "y": 0})
``` ```
```csharp ```csharp
// Generic click // Generic click
await page.Locator("button#submit").ClickAsync(); await page.GetByRole("button").ClickAsync();
// Double click // Double click
await page.Locator("#item").DblClickAsync(); await page.GetByText("Item").DblClickAsync();
// Right click // Right click
await page.Locator("#item").ClickAsync(new() { Button = MouseButton.Right }); await page.GetByText("Item").ClickAsync(new() { Button = MouseButton.Right });
// Shift + click // Shift + click
await page.Locator("#item").ClickAsync(new() { Modifiers = new[] { KeyboardModifier.Shift } }); await page.GetByText("Item").ClickAsync(new() { Modifiers = new[] { KeyboardModifier.Shift } });
// Hover over element // Hover over element
await page.Locator("#item").HoverAsync(); await page.GetByText("Item").HoverAsync();
// Click the top left corner // Click the top left corner
await page.Locator("#item").ClickAsync(new() { position = new Position { X = 0, Y = 0 } }); await page.GetByText("Item").ClickAsync(new() { position = new Position { X = 0, Y = 0 } });
``` ```
Under the hood, this and other pointer-related methods: Under the hood, this and other pointer-related methods:
@ -346,23 +316,23 @@ Under the hood, this and other pointer-related methods:
Sometimes, apps use non-trivial logic where hovering the element overlays it with another element that intercepts the click. This behavior is indistinguishable from a bug where element gets covered and the click is dispatched elsewhere. If you know this is taking place, you can bypass the [actionability](./actionability.md) checks and force the click: Sometimes, apps use non-trivial logic where hovering the element overlays it with another element that intercepts the click. This behavior is indistinguishable from a bug where element gets covered and the click is dispatched elsewhere. If you know this is taking place, you can bypass the [actionability](./actionability.md) checks and force the click:
```js ```js
await page.locator('button#submit').click({ force: true }); await page.getByRole('button').click({ force: true });
``` ```
```java ```java
page.locator("button#submit").click(new Locator.ClickOptions().setForce(true)); page.getByRole("button").click(new Locator.ClickOptions().setForce(true));
``` ```
```python async ```python async
await page.locator('button#submit').click(force=True) await page.get_by_role("button").click(force=True)
``` ```
```python sync ```python sync
page.locator('button#submit').click(force=True) page.get_by_role("button").click(force=True)
``` ```
```csharp ```csharp
await page.Locator("button#submit").ClickAsync(new() { Force = true }); await page.GetByRole("button").ClickAsync(new() { Force = true });
``` ```
#### Programmatic click #### Programmatic click
@ -370,23 +340,23 @@ await page.Locator("button#submit").ClickAsync(new() { Force = true });
If you are not interested in testing your app under the real conditions and want to simulate the click by any means possible, you can trigger the [`HTMLElement.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click) behavior via simply dispatching a click event on the element with [`method: Locator.dispatchEvent`]: If you are not interested in testing your app under the real conditions and want to simulate the click by any means possible, you can trigger the [`HTMLElement.click()`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click) behavior via simply dispatching a click event on the element with [`method: Locator.dispatchEvent`]:
```js ```js
await page.locator('button#submit').dispatchEvent('click'); await page.getByRole('button').dispatchEvent('click');
``` ```
```java ```java
page.locator("button#submit").dispatchEvent("click"); page.getByRole("button").dispatchEvent("click");
``` ```
```python async ```python async
await page.locator('button#submit').dispatch_event('click') await page.get_by_role("button").dispatch_event('click')
``` ```
```python sync ```python sync
page.locator('button#submit').dispatch_event('click') page.get_by_role("button").dispatch_event('click')
``` ```
```csharp ```csharp
await page.Locator("button#submit").DispatchEventAsync("click"); await page.GetByRole("button").DispatchEventAsync("click");
``` ```
## Type characters ## Type characters
@ -428,57 +398,57 @@ Most of the time, [`method: Page.fill`] will just work. You only need to type ch
```js ```js
// Hit Enter // Hit Enter
await page.locator('#submit').press('Enter'); await page.getByText('Submit').press('Enter');
// Dispatch Control+Right // Dispatch Control+Right
await page.locator('#name').press('Control+ArrowRight'); await page.getByRole('textbox').press('Control+ArrowRight');
// Press $ sign on keyboard // Press $ sign on keyboard
await page.locator('#value').press('$'); await page.getByRole('textbox').press('$');
``` ```
```java ```java
// Hit Enter // Hit Enter
page.locator("#submit").press("Enter"); page.getByText("Submit").press("Enter");
// Dispatch Control+Right // Dispatch Control+Right
page.locator("#name").press("Control+ArrowRight"); page.getByRole("textbox").press("Control+ArrowRight");
// Press $ sign on keyboard // Press $ sign on keyboard
page.locator("#value").press("$"); page.getByRole("textbox").press("$");
``` ```
```python async ```python async
# Hit Enter # Hit Enter
await page.locator('#submit').press('Enter') await page.get_by_text("Submit").press("Enter")
# Dispatch Control+Right # Dispatch Control+Right
await page.locator('#name').press('Control+ArrowRight') await page.get_by_role("textbox").press("Control+ArrowRight")
# Press $ sign on keyboard # Press $ sign on keyboard
await page.locator('#value').press('$') await page.get_by_role("textbox").press("$")
``` ```
```python sync ```python sync
# Hit Enter # Hit Enter
page.locator('#submit').press('Enter') page.get_by_text("Submit").press("Enter")
# Dispatch Control+Right # Dispatch Control+Right
page.locator('#name').press('Control+ArrowRight') page.get_by_role("textbox").press("Control+ArrowRight")
# Press $ sign on keyboard # Press $ sign on keyboard
page.locator('#value').press('$') page.get_by_role("textbox").press("$")
``` ```
```csharp ```csharp
// Hit Enter // Hit Enter
await page.Locator("#submit").PressAsync("Enter"); await page.GetByText("Submit").PressAsync("Enter");
// Dispatch Control+Right // Dispatch Control+Right
await page.Locator("#name").PressAsync("Control+ArrowRight"); await page.GetByRole("textbox").PressAsync("Control+ArrowRight");
// Press $ sign on keyboard // Press $ sign on keyboard
await page.Locator("#value").PressAsync("$"); await page.GetByRole("textbox").PressAsync("$");
``` ```
The [`method: Locator.press`] method focuses the selected element and produces a single keystroke. It accepts the logical key names that are emitted in the [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property of the keyboard events: The [`method: Locator.press`] method focuses the selected element and produces a single keystroke. It accepts the logical key names that are emitted in the [keyboardEvent.key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property of the keyboard events:
@ -546,16 +516,16 @@ You can select input files for upload using the [`method: Locator.setInputFiles`
```js ```js
// Select one file // Select one file
await page.locator('input#upload').setInputFiles('myfile.pdf'); await page.getByLabelText('Upload file').setInputFiles('myfile.pdf');
// Select multiple files // Select multiple files
await page.locator('input#upload').setInputFiles(['file1.txt', 'file2.txt']); await page.getByLabelText('Upload files').setInputFiles(['file1.txt', 'file2.txt']);
// Remove all the selected files // Remove all the selected files
await page.locator('input#upload').setInputFiles([]); await page.getByLabelText('Upload file').setInputFiles([]);
// Upload buffer from memory // Upload buffer from memory
await page.locator('input#upload').setInputFiles({ await page.getByLabelText('Upload file').setInputFiles({
name: 'file.txt', name: 'file.txt',
mimeType: 'text/plain', mimeType: 'text/plain',
buffer: Buffer.from('this is test') buffer: Buffer.from('this is test')
@ -564,31 +534,31 @@ await page.locator('input#upload').setInputFiles({
```java ```java
// Select one file // Select one file
page.locator("input#upload").setInputFiles(Paths.get("myfile.pdf")); page.getByLabelText("Upload file").setInputFiles(Paths.get("myfile.pdf"));
// Select multiple files // Select multiple files
page.locator("input#upload").setInputFiles(new Path[] {Paths.get("file1.txt"), Paths.get("file2.txt")}); page.getByLabelText("Upload files").setInputFiles(new Path[] {Paths.get("file1.txt"), Paths.get("file2.txt")});
// Remove all the selected files // Remove all the selected files
page.locator("input#upload").setInputFiles(new Path[0]); page.getByLabelText("Upload file").setInputFiles(new Path[0]);
// Upload buffer from memory // Upload buffer from memory
page.locator("input#upload").setInputFiles(new FilePayload( page.getByLabelText("Upload file").setInputFiles(new FilePayload(
"file.txt", "text/plain", "this is test".getBytes(StandardCharsets.UTF_8))); "file.txt", "text/plain", "this is test".getBytes(StandardCharsets.UTF_8)));
``` ```
```python async ```python async
# Select one file # Select one file
await page.locator('input#upload').set_input_files('myfile.pdf') await page.get_by_label_text("Upload file").set_input_files('myfile.pdf')
# Select multiple files # Select multiple files
await page.locator('input#upload').set_input_files(['file1.txt', 'file2.txt']) await page.get_by_label_text("Upload files").set_input_files(['file1.txt', 'file2.txt'])
# Remove all the selected files # Remove all the selected files
await page.locator('input#upload').set_input_files([]) await page.get_by_label_text("Upload file").set_input_files([])
# Upload buffer from memory # Upload buffer from memory
await page.locator("input#upload").set_input_files( await page.get_by_label_text("Upload file").set_input_files(
files=[ files=[
{"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"} {"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"}
], ],
@ -597,16 +567,16 @@ await page.locator("input#upload").set_input_files(
```python sync ```python sync
# Select one file # Select one file
page.locator('input#upload').set_input_files('myfile.pdf') page.get_by_label_text("Upload file").set_input_files('myfile.pdf')
# Select multiple files # Select multiple files
page.locator('input#upload').set_input_files(['file1.txt', 'file2.txt']) page.get_by_label_text("Upload files").set_input_files(['file1.txt', 'file2.txt'])
# Remove all the selected files # Remove all the selected files
page.locator('input#upload').set_input_files([]) page.get_by_label_text("Upload file").set_input_files([])
# Upload buffer from memory # Upload buffer from memory
page.locator("input#upload").set_input_files( page.get_by_label_text("Upload file").set_input_files(
files=[ files=[
{"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"} {"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"}
], ],
@ -615,16 +585,16 @@ page.locator("input#upload").set_input_files(
```csharp ```csharp
// Select one file // Select one file
await page.Locator("input#upload").SetInputFilesAsync("myfile.pdf"); await page.GetByLabelText("Upload file").SetInputFilesAsync("myfile.pdf");
// Select multiple files // Select multiple files
await page.Locator("input#upload").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" }); await page.GetByLabelText("Upload files").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" });
// Remove all the selected files // Remove all the selected files
await page.Locator("input#upload").SetInputFilesAsync(new[] {}); await page.GetByLabelText("Upload file").SetInputFilesAsync(new[] {});
// Upload buffer from memory // Upload buffer from memory
await page.Locator("input#upload").SetInputFilesAsync(new FilePayload await page.GetByLabelText("Upload file").SetInputFilesAsync(new FilePayload
{ {
Name = "file.txt", Name = "file.txt",
MimeType = "text/plain", MimeType = "text/plain",
@ -680,23 +650,23 @@ await fileChooser.SetFilesAsync("myfile.pdf");
For the dynamic pages that handle focus events, you can focus the given element with [`method: Locator.focus`]. For the dynamic pages that handle focus events, you can focus the given element with [`method: Locator.focus`].
```js ```js
await page.locator('input#name').focus(); await page.getByLabelText('Password').focus();
``` ```
```java ```java
page.locator("input#name").focus(); page.getByLabelText("Password").focus();
``` ```
```python async ```python async
await page.locator('input#name').focus() await page.get_by_label_text('password').focus()
``` ```
```python sync ```python sync
page.locator('input#name').focus() page.get_by_label_text('password').focus()
``` ```
```csharp ```csharp
await page.Locator("input#name").FocusAsync(); await page.GetByLabelText("Password").FocusAsync();
``` ```
## Drag and Drop ## Drag and Drop

View file

@ -7,27 +7,27 @@ title: "Locators"
a way to find element(s) on the page at any moment. Locator can be created with the [`method: Page.locator`] method. a way to find element(s) on the page at any moment. Locator can be created with the [`method: Page.locator`] method.
```js ```js
const locator = page.locator('text=Submit'); const locator = page.getByText('Submit');
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = page.locator("text=Submit"); Locator locator = page.getByText("Submit");
locator.click(); locator.click();
``` ```
```python async ```python async
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = page.Locator("text=Submit"); var locator = page.GetByText("Submit");
await locator.ClickAsync(); await locator.ClickAsync();
``` ```
@ -37,32 +37,32 @@ DOM changes in between the calls due to re-render, the new element corresponding
locator will be used. locator will be used.
```js ```js
const locator = page.locator('text=Submit'); const locator = page.getByText('Submit');
// ... // ...
await locator.hover(); await locator.hover();
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = page.locator("text=Submit"); Locator locator = page.getByText("Submit");
locator.hover(); locator.hover();
locator.click(); locator.click();
``` ```
```python async ```python async
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
await locator.hover() await locator.hover()
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
locator.hover() locator.hover()
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = page.Locator("text=Submit"); var locator = page.GetByText("Submit");
await locator.HoverAsync(); await locator.HoverAsync();
await locator.ClickAsync(); await locator.ClickAsync();
``` ```
@ -75,57 +75,57 @@ given selector.
```js ```js
// Throws if there are several buttons in DOM: // Throws if there are several buttons in DOM:
await page.locator('button').click(); await page.getByRole('button').click();
// Works because we explicitly tell locator to pick the first element: // Works because we explicitly tell locator to pick the first element:
await page.locator('button').first().click(); // ⚠️ using first disables strictness await page.getByRole('button').first().click(); // ⚠️ using first disables strictness
// Works because count knows what to do with multiple matches: // Works because count knows what to do with multiple matches:
await page.locator('button').count(); await page.getByRole('button').count();
``` ```
```python async ```python async
# Throws if there are several buttons in DOM: # Throws if there are several buttons in DOM:
await page.locator('button').click() await page.get_by_role("button").click()
# Works because we explicitly tell locator to pick the first element: # Works because we explicitly tell locator to pick the first element:
await page.locator('button').first.click() # ⚠️ using first disables strictness await page.get_by_role("button").first.click() # ⚠️ using first disables strictness
# Works because count knows what to do with multiple matches: # Works because count knows what to do with multiple matches:
await page.locator('button').count() await page.get_by_role("button").count()
``` ```
```python sync ```python sync
# Throws if there are several buttons in DOM: # Throws if there are several buttons in DOM:
page.locator('button').click() page.get_by_role("button").click()
# Works because we explicitly tell locator to pick the first element: # Works because we explicitly tell locator to pick the first element:
page.locator('button').first.click() # ⚠️ using first disables strictness page.get_by_role("button").first.click() # ⚠️ using first disables strictness
# Works because count knows what to do with multiple matches: # Works because count knows what to do with multiple matches:
page.locator('button').count() page.get_by_role("button").count()
``` ```
```java ```java
// Throws if there are several buttons in DOM: // Throws if there are several buttons in DOM:
page.locator("button").click(); page.getByRole("button").click();
// Works because we explicitly tell locator to pick the first element: // Works because we explicitly tell locator to pick the first element:
page.locator("button").first().click(); // ⚠️ using first disables strictness page.getByRole("button").first().click(); // ⚠️ using first disables strictness
// Works because count knows what to do with multiple matches: // Works because count knows what to do with multiple matches:
page.locator("button").count(); page.getByRole("button").count();
``` ```
```csharp ```csharp
// Throws if there are several buttons in DOM: // Throws if there are several buttons in DOM:
await page.Locator("button").ClickAsync(); await page.GetByRole("button").ClickAsync();
// Works because we explicitly tell locator to pick the first element: // Works because we explicitly tell locator to pick the first element:
await page.Locator("button").First.ClickAsync(); // ⚠️ using First disables strictness await page.GetByRole("button").First.ClickAsync(); // ⚠️ using First disables strictness
// Works because Count knows what to do with multiple matches: // Works because Count knows what to do with multiple matches:
await page.Locator("button").CountAsync(); await page.GetByRole("button").CountAsync();
``` ```
:::caution :::caution
@ -142,19 +142,19 @@ Use [`method: Page.locator`] method to create a locator. This method takes a sel
The easiest way to find an element is to look for the text it contains. The easiest way to find an element is to look for the text it contains.
```js ```js
await page.locator('text=Log in').click(); await page.getByText('Log in').click();
``` ```
```java ```java
page.locator("text=Log in").click(); page.getByText("Log in").click();
``` ```
```python async ```python async
await page.locator("text=Log in").click() await page.get_by_text("Log in").click()
``` ```
```python sync ```python sync
page.locator("text=Log in").click() page.get_by_text("Log in").click()
``` ```
```csharp ```csharp
await page.Locator("text=Log in").ClickAsync(); await page.GetByText("Log in").ClickAsync();
``` ```
You can also [filter by text](#filter-by-text) when locating in some other way, for example find a particular item in the list. You can also [filter by text](#filter-by-text) when locating in some other way, for example find a particular item in the list.
@ -182,33 +182,33 @@ await page.Locator("data-test-id=product-item", new() { HasText = "Playwright Bo
The `role` selector reflects how users and assistive technology percieve the page, for example whether some element is a button or a checkbox. When locating by role, you should usually pass the accessible name as well, so that locator pinpoints the exact element. The `role` selector reflects how users and assistive technology percieve the page, for example whether some element is a button or a checkbox. When locating by role, you should usually pass the accessible name as well, so that locator pinpoints the exact element.
```js ```js
await page.locator('role=button[name=/submit/i]').click(); await page.getByRole('button', { name: /submit/i }).click();
await page.locator('role=checkbox[checked][name="Check me"]').check(); await page.getByRole('checkbox', { checked: true, name: "Check me" }).check();
``` ```
```python async ```python async
await page.locator('role=button[name=/submit/i]').click() await page.get_by_role("button", name=re.compile("(?i)submit")).click()
await page.locator('role=checkbox[checked][name="Check me"]').check() await page.get_by_role("checkbox", checked=True, name="Check me"]).check()
``` ```
```python sync ```python sync
page.locator('role=button[name=/submit/i]').click() page.get_by_role("button", name=re.compile("(?i)submit")).click()
page.locator('role=checkbox[checked][name="Check me"]').check() page.get_by_role("checkbox", checked=True, name="Check me"]).check()
``` ```
```java ```java
page.locator("role=button[name=/submit/i]").click(); page.getByRole("button", new Page.GetByRoleOptions().setName(Pattern.compile("(?i)submit"))).click();
page.locator("role=checkbox[checked][name=\"Check me\"]").check(); page.getByRole("checkbox", new Page.GetByRoleOptions().setChecked(true).setName("Check me"))).check();
``` ```
```csharp ```csharp
await page.Locator("role=button[name=/submit/i]").ClickAsync(); await page.GetByRole("button", new() { Name = new Regex("(?i)submit") }).ClickAsync();
await page.Locator("role=checkbox[checked][name=\"Check me\"]").CheckAsync(); await page.GetByRole("checkbox", new() { Checked = true, Name = "Check me" }).CheckAsync();
``` ```
[Learn more about the `role` selector](./selectors.md#role-selector). [Learn more about the `role` selector](./selectors.md#role-selector).
@ -262,23 +262,23 @@ You can target the label with something like `text=Password` and perform the fol
For example, to fill the input by targeting the label: For example, to fill the input by targeting the label:
```js ```js
await page.locator('text=Password').fill('secret'); await page.getByText('Password').fill('secret');
``` ```
```java ```java
page.locator("text=Password").fill("secret"); page.getByText("Password").fill("secret");
``` ```
```python async ```python async
await page.locator('text=Password').fill('secret') await page.get_by_text('Password').fill('secret')
``` ```
```python sync ```python sync
page.locator('text=Password').fill('secret') page.get_by_text('Password').fill('secret')
``` ```
```csharp ```csharp
await page.Locator("text=Password").FillAsync("secret"); await page.GetByText("Password").FillAsync("secret");
``` ```
However, other methods will target the label itself, for example `textContent` will return the text content of the label, not the input field. However, other methods will target the label itself, for example `textContent` will return the text content of the label, not the input field.
@ -305,31 +305,31 @@ For example, we can first find a product card that contains text "Product 2", an
```js ```js
const product = page.locator('data-test-id=product-card', { hasText: 'Product 2' }); const product = page.locator('data-test-id=product-card', { hasText: 'Product 2' });
await product.locator('text=Buy').click(); await product.getByText('Buy').click();
``` ```
```python async ```python async
product = page.locator("data-test-id=product-card", has_text="Product 2") product = page.locator("data-test-id=product-card", has_text="Product 2")
await product.locator("text=Buy").click() await product.getByText("Buy").click()
``` ```
```python sync ```python sync
product = page.locator("data-test-id=product-card", has_text="Product 2") product = page.locator("data-test-id=product-card", has_text="Product 2")
product.locator("text=Buy").click() product.get_by_text("Buy").click()
``` ```
```java ```java
Locator product = page.locator("data-test-id=product-card", new Page.LocatorOptions().setHasText("Product 2")); Locator product = page.locator("data-test-id=product-card", new Page.LocatorOptions().setHasText("Product 2"));
product.locator("text=Buy").click(); product.get_by_text("Buy").click();
``` ```
```csharp ```csharp
var product = page.Locator("data-test-id=product-card", new() { HasText = "Product 2" }); var product = page.Locator("data-test-id=product-card", new() { HasText = "Product 2" });
await product.Locator("text=Buy").clickAsync(); await product.GetByText("Buy").clickAsync();
``` ```
### Locate by CSS or XPath selector ### Locate by CSS or XPath selector
@ -531,19 +531,19 @@ You can locate in the same way as if the shadow root was not present at all.
- Click `<span>Details</span>` - Click `<span>Details</span>`
```js ```js
await page.locator('text=Details').click(); await page.getByText('Details').click();
``` ```
```java ```java
page.locator("text=Details").click(); page.getByText("Details").click();
``` ```
```python async ```python async
await page.locator("text=Details").click() await page.get_by_text("Details").click()
``` ```
```python sync ```python sync
page.locator("text=Details").click() page.get_by_text("Details").click()
``` ```
```csharp ```csharp
await page.Locator("text=Details").ClickAsync(); await page.GetByText("Details").ClickAsync();
``` ```
- Click `<x-badge>` - Click `<x-badge>`
@ -742,32 +742,32 @@ await handle.ClickAsync();
With the locator, every time the locator is used, up-to-date DOM element is located in the page using the selector. So in the snippet below, underlying DOM element is going to be located twice. With the locator, every time the locator is used, up-to-date DOM element is located in the page using the selector. So in the snippet below, underlying DOM element is going to be located twice.
```js ```js
const locator = page.locator('text=Submit'); const locator = page.getByText('Submit');
// ... // ...
await locator.hover(); await locator.hover();
await locator.click(); await locator.click();
``` ```
```java ```java
Locator locator = page.locator("text=Submit"); Locator locator = page.getByText("Submit");
locator.hover(); locator.hover();
locator.click(); locator.click();
``` ```
```python async ```python async
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
await locator.hover() await locator.hover()
await locator.click() await locator.click()
``` ```
```python sync ```python sync
locator = page.locator("text=Submit") locator = page.get_by_text("Submit")
locator.hover() locator.hover()
locator.click() locator.click()
``` ```
```csharp ```csharp
var locator = page.Locator("text=Submit"); var locator = page.GetByText("Submit");
await locator.HoverAsync(); await locator.HoverAsync();
await locator.ClickAsync(); await locator.ClickAsync();
``` ```

View file

@ -97,56 +97,56 @@ Alternatively, page interactions like [`method: Page.click`] auto-wait for eleme
```js ```js
// Navigate and wait for element // Navigate and wait for element
await page.goto('https://example.com'); await page.goto('https://example.com');
await page.locator('text=Example Domain').waitFor(); await page.getByText('Example Domain').waitFor();
// Navigate and click element // Navigate and click element
// Click will auto-wait for the element // Click will auto-wait for the element
await page.goto('https://example.com'); await page.goto('https://example.com');
await page.locator('text=Example Domain').click(); await page.getByText('Example Domain').click();
``` ```
```java ```java
// Navigate and wait for element // Navigate and wait for element
page.navigate("https://example.com"); page.navigate("https://example.com");
page.locator("text=Example Domain").waitFor(); page.getByText("Example Domain").waitFor();
// Navigate and click element // Navigate and click element
// Click will auto-wait for the element // Click will auto-wait for the element
page.navigate("https://example.com"); page.navigate("https://example.com");
page.locator("text=Example Domain").click(); page.getByText("Example Domain").click();
``` ```
```python async ```python async
# Navigate and wait for element # Navigate and wait for element
await page.goto("https://example.com") await page.goto("https://example.com")
await page.locator("text=example domain").wait_for() await page.get_by_text("example domain").wait_for()
# Navigate and click element # Navigate and click element
# Click will auto-wait for the element # Click will auto-wait for the element
await page.goto("https://example.com") await page.goto("https://example.com")
await page.locator("text=example domain").click() await page.get_by_text("example domain").click()
``` ```
```python sync ```python sync
# Navigate and wait for element # Navigate and wait for element
page.goto("https://example.com") page.goto("https://example.com")
page.locator("text=example domain").wait_for() page.get_by_text("example domain").wait_for()
# Navigate and click element # Navigate and click element
# Click will auto-wait for the element # Click will auto-wait for the element
page.goto("https://example.com") page.goto("https://example.com")
page.locator("text=example domain").click() page.get_by_text("example domain").click()
``` ```
```csharp ```csharp
// Navigate and wait for element // Navigate and wait for element
await page.GotoAsync("https://example.com"); await page.GotoAsync("https://example.com");
await page.Locator("text=Example Domain").WaitForAsync(); await page.GetByText("Example Domain").WaitForAsync();
// Navigate and click element // Navigate and click element
// Click will auto-wait for the element // Click will auto-wait for the element
await page.GotoAsync("https://example.com"); await page.GotoAsync("https://example.com");
await page.Locator("text=Example Domain").ClickAsync(); await page.GetByText("Example Domain").ClickAsync();
``` ```
## Scenarios initiated by page interaction ## Scenarios initiated by page interaction
@ -159,42 +159,42 @@ By default, [`method: Locator.click`] will wait for the navigation step to compl
```js ```js
// Click will auto-wait for navigation to complete // Click will auto-wait for navigation to complete
await page.locator('text=Login').click(); await page.getByText('Login').click();
// Fill will auto-wait for element on navigated page // Fill will auto-wait for element on navigated page
await page.locator('#username').fill('John Doe'); await page.getByLabelText('User Name').fill('John Doe');
``` ```
```java ```java
// Click will auto-wait for navigation to complete // Click will auto-wait for navigation to complete
page.locator("text=Login").click(); page.getByText("Login").click();
// Fill will auto-wait for element on navigated page // Fill will auto-wait for element on navigated page
page.locator("#username").fill("John Doe"); page.getByLabelText("User Name").fill("John Doe");
``` ```
```python async ```python async
# Click will auto-wait for navigation to complete # Click will auto-wait for navigation to complete
await page.locator("text=Login").click() await page.get_by_text("Login").click()
# Fill will auto-wait for element on navigated page # Fill will auto-wait for element on navigated page
await page.locator("#username").fill("John Doe") await page.get_by_label_text("User Name").fill("John Doe")
``` ```
```python sync ```python sync
# Click will auto-wait for navigation to complete # Click will auto-wait for navigation to complete
page.locator("text=Login").click() page.get_by_text("Login").click()
# Fill will auto-wait for element on navigated page # Fill will auto-wait for element on navigated page
page.locator("#username").fill("John Doe") page.get_by_label_text("User Name").fill("John Doe")
``` ```
```csharp ```csharp
// Click will auto-wait for navigation to complete // Click will auto-wait for navigation to complete
await page.Locator("text=Login").ClickAsync(); await page.GetByText("Login").ClickAsync();
// Fill will auto-wait for element on navigated page // Fill will auto-wait for element on navigated page
await page.Locator("#username").FillAsync("John Doe"); await page.GetByLabelText("User Name").FillAsync("John Doe");
``` ```
### Custom wait ### Custom wait
@ -202,7 +202,7 @@ await page.Locator("#username").FillAsync("John Doe");
`locator.click` can be combined with [`method: Page.waitForLoadState`] to wait for a loading event. `locator.click` can be combined with [`method: Page.waitForLoadState`] to wait for a loading event.
```js ```js
await page.locator('button').click(); // Click triggers navigation await page.getByRole('button').click(); // Click triggers navigation
await page.waitForLoadState('networkidle'); // This resolves after 'networkidle' await page.waitForLoadState('networkidle'); // This resolves after 'networkidle'
``` ```
@ -233,62 +233,62 @@ Alternatively, page interactions like [`method: Locator.click`] auto-wait for el
```js ```js
// Click will auto-wait for the element and trigger navigation // Click will auto-wait for the element and trigger navigation
await page.locator('text=Login').click(); await page.getByText('Login').click();
// Wait for the element // Wait for the element
await page.locator('#username').waitFor(); await page.getByLabelText('User Name').waitFor();
// Click triggers navigation // Click triggers navigation
await page.locator('text=Login').click(); await page.getByText('Login').click();
// Fill will auto-wait for element // Fill will auto-wait for element
await page.locator('#username').fill('John Doe'); await page.getByLabelText('User Name').fill('John Doe');
``` ```
```java ```java
// Click will auto-wait for the element and trigger navigation // Click will auto-wait for the element and trigger navigation
page.locator("text=Login").click(); page.getByText("Login").click();
// Wait for the element // Wait for the element
page.locator("#username").waitFor(); page.getByLabelText("User Name").waitFor();
// Click triggers navigation // Click triggers navigation
page.locator("text=Login").click(); page.getByText("Login").click();
// Fill will auto-wait for element // Fill will auto-wait for element
page.locator("#username").fill("John Doe"); page.getByLabelText("User Name").fill("John Doe");
``` ```
```python async ```python async
# Click will auto-wait for the element and trigger navigation # Click will auto-wait for the element and trigger navigation
await page.locator("text=Login").click() await page.get_by_text("Login").click()
# Wait for the element # Wait for the element
await page.locator("#username").wait_for() await page.get_by_label_text("User Name").wait_for()
# Click triggers navigation # Click triggers navigation
await page.locator("text=Login").click() await page.get_by_text("Login").click()
# Fill will auto-wait for element # Fill will auto-wait for element
await page.locator("#username").fill("John Doe") await page.get_by_label_text("User Name").fill("John Doe")
``` ```
```python sync ```python sync
# Click triggers navigation # Click triggers navigation
page.locator("text=Login").click() page.get_by_text("Login").click()
# Click will auto-wait for the element # Click will auto-wait for the element
page.locator("#username").wait_for() page.get_by_label_text("User Name").wait_for()
# Click triggers navigation # Click triggers navigation
page.locator("text=Login").click() page.get_by_text("Login").click()
# Fill will auto-wait for element # Fill will auto-wait for element
page.locator("#username").fill("John Doe") page.get_by_label_text("User Name").fill("John Doe")
``` ```
```csharp ```csharp
// Click will auto-wait for the element and trigger navigation // Click will auto-wait for the element and trigger navigation
await page.Locator("text=Login").ClickAsync(); await page.GetByText("Login").ClickAsync();
// Wait for the element // Wait for the element
await page.Locator("#username").WaitForAsync(); await page.GetByLabelText("User Name").WaitForAsync();
// Click triggers navigation // Click triggers navigation
await page.Locator("text=Login").ClickAsync(); await page.GetByText("Login").ClickAsync();
// Fill will auto-wait for element // Fill will auto-wait for element
await page.Locator("#username").FillAsync("John Doe"); await page.GetByLabelText("User Name").FillAsync("John Doe");
``` ```
### Asynchronous navigation ### Asynchronous navigation
@ -358,7 +358,7 @@ await Promise.all([
// It is important to call waitForNavigation before click to set up waiting. // It is important to call waitForNavigation before click to set up waiting.
page.waitForNavigation({ url: '**/login' }), page.waitForNavigation({ url: '**/login' }),
// Triggers a navigation with a script redirect. // Triggers a navigation with a script redirect.
page.locator('text=Click me').click(), page.getByText('Click me').click(),
]); ]);
``` ```
@ -366,7 +366,7 @@ await Promise.all([
// Running action in the callback of waitForNavigation prevents a race // Running action in the callback of waitForNavigation prevents a race
// condition between clicking and waiting for a navigation. // condition between clicking and waiting for a navigation.
page.waitForNavigation(new Page.WaitForNavigationOptions().setUrl("**/login"), () -> { page.waitForNavigation(new Page.WaitForNavigationOptions().setUrl("**/login"), () -> {
page.locator("a").click(); // Triggers a navigation with a script redirect page.getByText("Click me").click(); // Triggers a navigation with a script redirect
}); });
``` ```
@ -375,7 +375,7 @@ page.waitForNavigation(new Page.WaitForNavigationOptions().setUrl("**/login"), (
# between clicking and waiting for a navigation. # between clicking and waiting for a navigation.
async with page.expect_navigation(url="**/login"): async with page.expect_navigation(url="**/login"):
# Triggers a navigation with a script redirect # Triggers a navigation with a script redirect
await page.locator("a").click() await page.get_by_text("Click me").click()
``` ```
```python sync ```python sync
@ -383,7 +383,7 @@ async with page.expect_navigation(url="**/login"):
# between clicking and waiting for a navigation. # between clicking and waiting for a navigation.
with page.expect_navigation(url="**/login"): with page.expect_navigation(url="**/login"):
# Triggers a navigation with a script redirect # Triggers a navigation with a script redirect
page.locator("a").click() page.get_by_text("Click me").click()
``` ```
```csharp ```csharp
@ -392,7 +392,7 @@ with page.expect_navigation(url="**/login"):
await page.RunAndWaitForNavigationAsync(async () => await page.RunAndWaitForNavigationAsync(async () =>
{ {
// Triggers a navigation with a script redirect. // Triggers a navigation with a script redirect.
await page.Locator("a").ClickAsync(); await page.GetByText("Click me").ClickAsync();
}, new() }, new()
{ {
UrlString = "**/login" UrlString = "**/login"

View file

@ -251,35 +251,35 @@ Or wait for a network response after the button click with [`method: Page.waitFo
// Use a glob URL pattern // Use a glob URL pattern
const [response] = await Promise.all([ const [response] = await Promise.all([
page.waitForResponse('**/api/fetch_data'), page.waitForResponse('**/api/fetch_data'),
page.locator('button#update').click(), page.getByText('Update').click(),
]); ]);
``` ```
```java ```java
// Use a glob URL pattern // Use a glob URL pattern
Response response = page.waitForResponse("**/api/fetch_data", () -> { Response response = page.waitForResponse("**/api/fetch_data", () -> {
page.locator("button#update").click(); page.getByText("Update").click();
}); });
``` ```
```python async ```python async
# Use a glob url pattern # Use a glob url pattern
async with page.expect_response("**/api/fetch_data") as response_info: async with page.expect_response("**/api/fetch_data") as response_info:
await page.locator("button#update").click() await page.get_by_text("Update").click()
response = await response_info.value response = await response_info.value
``` ```
```python sync ```python sync
# Use a glob url pattern # Use a glob url pattern
with page.expect_response("**/api/fetch_data") as response_info: with page.expect_response("**/api/fetch_data") as response_info:
page.locator("button#update").click() page.get_by_text("Update").click()
response = response_info.value response = response_info.value
``` ```
```csharp ```csharp
// Use a glob URL pattern // Use a glob URL pattern
var waitForResponseTask = page.WaitForResponseAsync("**/api/fetch_data"); var waitForResponseTask = page.WaitForResponseAsync("**/api/fetch_data");
await page.Locator("button#update").ClickAsync(); await page.GetByText("Update").ClickAsync();
var response = await waitForResponseTask; var response = await waitForResponseTask;
``` ```
@ -291,61 +291,61 @@ Wait for [Response]s with [`method: Page.waitForResponse`]
// Use a RegExp // Use a RegExp
const [response] = await Promise.all([ const [response] = await Promise.all([
page.waitForResponse(/\.jpeg$/), page.waitForResponse(/\.jpeg$/),
page.locator('button#update').click(), page.getByText('Update').click(),
]); ]);
// Use a predicate taking a Response object // Use a predicate taking a Response object
const [response] = await Promise.all([ const [response] = await Promise.all([
page.waitForResponse(response => response.url().includes(token)), page.waitForResponse(response => response.url().includes(token)),
page.locator('button#update').click(), page.getByText('Update').click(),
]); ]);
``` ```
```java ```java
// Use a RegExp // Use a RegExp
Response response = page.waitForResponse(Pattern.compile("\\.jpeg$"), () -> { Response response = page.waitForResponse(Pattern.compile("\\.jpeg$"), () -> {
page.locator("button#update").click(); page.getByText("Update").click();
}); });
// Use a predicate taking a Response object // Use a predicate taking a Response object
Response response = page.waitForResponse(r -> r.url().contains(token), () -> { Response response = page.waitForResponse(r -> r.url().contains(token), () -> {
page.locator("button#update").click(); page.getByText("Update").click();
}); });
``` ```
```python async ```python async
# Use a regular expression # Use a regular expression
async with page.expect_response(re.compile(r"\.jpeg$")) as response_info: async with page.expect_response(re.compile(r"\.jpeg$")) as response_info:
await page.locator("button#update").click() await page.get_by_text("Update").click()
response = await response_info.value response = await response_info.value
# Use a predicate taking a response object # Use a predicate taking a response object
async with page.expect_response(lambda response: token in response.url) as response_info: async with page.expect_response(lambda response: token in response.url) as response_info:
await page.locator("button#update").click() await page.get_by_text("Update").click()
response = await response_info.value response = await response_info.value
``` ```
```python sync ```python sync
# Use a regular expression # Use a regular expression
with page.expect_response(re.compile(r"\.jpeg$")) as response_info: with page.expect_response(re.compile(r"\.jpeg$")) as response_info:
page.locator("button#update").click() page.get_by_text("Update").click()
response = response_info.value response = response_info.value
# Use a predicate taking a response object # Use a predicate taking a response object
with page.expect_response(lambda response: token in response.url) as response_info: with page.expect_response(lambda response: token in response.url) as response_info:
page.locator("button#update").click() page.get_by_text("Update").click()
response = response_info.value response = response_info.value
``` ```
```csharp ```csharp
// Use a regular expression // Use a regular expression
var waitForResponseTask = page.WaitForResponseAsync(new Regex("\\.jpeg$")); var waitForResponseTask = page.WaitForResponseAsync(new Regex("\\.jpeg$"));
await page.Locator("button#update").ClickAsync(); await page.GetByText("Update").ClickAsync();
var response = await waitForResponseTask; var response = await waitForResponseTask;
// Use a predicate taking a Response object // Use a predicate taking a Response object
var waitForResponseTask = page.WaitForResponseAsync(r => r.Url.Contains(token)); var waitForResponseTask = page.WaitForResponseAsync(r => r.Url.Contains(token));
await page.Locator("button#update").ClickAsync(); await page.GetByText("Update").ClickAsync();
var response = await waitForResponseTask; var response = await waitForResponseTask;
``` ```
## Handle requests ## Handle requests

View file

@ -71,7 +71,7 @@ test.describe('angularjs homepage todo list', function() {
}); });
// You wrote your first test, cross it off the list // You wrote your first test, cross it off the list
await todoList.nth(2).locator('input').click(); await todoList.nth(2).getByRole('textbox').click();
var completedAmount = page.locator('.done-true'); var completedAmount = page.locator('.done-true');
await expect(completedAmount).toHaveCount(2); await expect(completedAmount).toHaveCount(2);
}); });

View file

@ -224,9 +224,9 @@ module.exports = async config => {
const browser = await chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto(baseURL); await page.goto(baseURL);
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState }); await page.context().storageState({ path: storageState });
await browser.close(); await browser.close();
}; };
@ -241,9 +241,9 @@ async function globalSetup(config: FullConfig) {
const browser = await chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto(baseURL!); await page.goto(baseURL!);
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await page.context().storageState({ path: storageState as string }); await page.context().storageState({ path: storageState as string });
await browser.close(); await browser.close();
} }
@ -373,9 +373,9 @@ module.exports = async config => {
try { try {
await context.tracing.start({ screenshots: true, snapshots: true }); await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto(baseURL); await page.goto(baseURL);
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await context.storageState({ path: storageState }); await context.storageState({ path: storageState });
await context.tracing.stop({ await context.tracing.stop({
path: './test-results/setup-trace.zip', path: './test-results/setup-trace.zip',
@ -403,9 +403,9 @@ async function globalSetup(config: FullConfig) {
try { try {
await context.tracing.start({ screenshots: true, snapshots: true }); await context.tracing.start({ screenshots: true, snapshots: true });
await page.goto(baseURL!); await page.goto(baseURL!);
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await context.storageState({ path: storageState as string }); await context.storageState({ path: storageState as string });
await context.tracing.stop({ await context.tracing.stop({
path: './test-results/setup-trace.zip', path: './test-results/setup-trace.zip',

View file

@ -189,7 +189,7 @@ test.beforeEach(async ({ page, isMobile }) => {
}); });
test('user profile', async ({ page }) => { test('user profile', async ({ page }) => {
await page.locator('text=My Profile').click(); await page.getByText('My Profile').click();
// ... // ...
}); });
``` ```
@ -204,7 +204,7 @@ test.beforeEach(async ({ page, isMobile }) => {
}); });
test('user profile', async ({ page }) => { test('user profile', async ({ page }) => {
await page.locator('text=My Profile').click(); await page.getByText('My Profile').click();
// ... // ...
}); });
``` ```

View file

@ -302,10 +302,10 @@ test.afterAll(async ({ }) => {
test('last created issue should be on the server', async ({ page, request }) => { test('last created issue should be on the server', async ({ page, request }) => {
await page.goto(`https://github.com/${USER}/${REPO}/issues`); await page.goto(`https://github.com/${USER}/${REPO}/issues`);
await page.locator('text=New Issue').click(); await page.getByText('New Issue').click();
await page.locator('[aria-label="Title"]').fill('Bug report 1'); await page.getByRole('textbox', { name: 'Title' }).fill('Bug report 1');
await page.locator('[aria-label="Comment body"]').fill('Bug description'); await page.getByRole('textbox', { name: 'Comment body' }).fill('Bug description');
await page.locator('text=Submit new issue').click(); await page.getByText('Submit new issue').click();
const issueId = page.url().substr(page.url().lastIndexOf('/')); const issueId = page.url().substr(page.url().lastIndexOf('/'));
const newIssue = await request.get(`https://api.github.com/repos/${USER}/${REPO}/issues/${issueId}`); const newIssue = await request.get(`https://api.github.com/repos/${USER}/${REPO}/issues/${issueId}`);
@ -347,10 +347,10 @@ test.afterAll(async ({ }) => {
test('last created issue should be on the server', async ({ page, request }) => { test('last created issue should be on the server', async ({ page, request }) => {
await page.goto(`https://github.com/${USER}/${REPO}/issues`); await page.goto(`https://github.com/${USER}/${REPO}/issues`);
await page.locator('text=New Issue').click(); await page.getByText('New Issue').click();
await page.locator('[aria-label="Title"]').fill('Bug report 1'); await page.getByRole('textbox', { name: 'Title' }).fill('Bug report 1');
await page.locator('[aria-label="Comment body"]').fill('Bug description'); await page.getByRole('textbox', { name: 'Comment body' }).fill('Bug description');
await page.locator('text=Submit new issue').click(); await page.getByText('Submit new issue').click();
const issueId = page.url().substr(page.url().lastIndexOf('/')); const issueId = page.url().substr(page.url().lastIndexOf('/'));
const newIssue = await request.get(`https://api.github.com/repos/${USER}/${REPO}/issues/${issueId}`); const newIssue = await request.get(`https://api.github.com/repos/${USER}/${REPO}/issues/${issueId}`);

View file

@ -77,9 +77,9 @@ const { test, expect } = require('@playwright/test');
test('basic test', async ({ page }) => { test('basic test', async ({ page }) => {
await page.goto('/signin'); await page.goto('/signin');
await page.locator('#username').fill('User'); await page.getByLabelText('User Name').fill('user');
await page.locator('#password').fill('pwd'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
// ... // ...
}); });
``` ```
@ -89,9 +89,9 @@ import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => { test('basic test', async ({ page }) => {
await page.goto('/signin'); await page.goto('/signin');
await page.locator('#username').fill('User'); await page.getByLabelText('User Name').fill('user');
await page.locator('#password').fill('pwd'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
// ... // ...
}); });
``` ```

View file

@ -63,7 +63,7 @@ expect(test.info().errors).toHaveLength(0);
You can specify a custom error message as a second argument to the `expect` function, for example: You can specify a custom error message as a second argument to the `expect` function, for example:
```js ```js
await expect(page.locator('text=Name'), 'should be logged in').toBeVisible(); await expect(page.getByText('Name'), 'should be logged in').toBeVisible();
``` ```
The error would look like this: The error would look like this:
@ -78,7 +78,7 @@ The error would look like this:
2 | 2 |
3 | test('example test', async({ page }) => { 3 | test('example test', async({ page }) => {
> 4 | await expect(page.locator('text=Name'), 'should be logged in').toBeVisible(); > 4 | await expect(page.getByText('Name'), 'should be logged in').toBeVisible();
| ^ | ^
5 | }); 5 | });
6 | 6 |

View file

@ -23,10 +23,10 @@ import { test } from '@playwright/test';
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
// Runs before each test and signs in each page. // Runs before each test and signs in each page.
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('text=Login').click(); await page.getByText('Login').click();
await page.locator('input[name="login"]').fill('username'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('text=Submit').click(); await page.getByText('Submit').click();
}); });
test('first', async ({ page }) => { test('first', async ({ page }) => {
@ -44,10 +44,10 @@ const { test } = require('@playwright/test');
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
// Runs before each test and signs in each page. // Runs before each test and signs in each page.
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('text=Login').click(); await page.getByText('Login').click();
await page.locator('input[name="login"]').fill('username'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('input:has-text("Sign in")').click(); await page.getByText('Sign in').click();
}); });
test('first', async ({ page }) => { test('first', async ({ page }) => {
@ -77,9 +77,9 @@ module.exports = async config => {
const browser = await chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="login"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('input:has-text("Sign in")').click(); await page.getByText('Sign in').click();
// Save signed-in state to 'storageState.json'. // Save signed-in state to 'storageState.json'.
await page.context().storageState({ path: 'storageState.json' }); await page.context().storageState({ path: 'storageState.json' });
await browser.close(); await browser.close();
@ -94,9 +94,9 @@ async function globalSetup(config: FullConfig) {
const browser = await chromium.launch(); const browser = await chromium.launch();
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="login"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('input:has-text("Sign in")').click(); await page.getByText('Sign in').click();
// Save signed-in state to 'storageState.json'. // Save signed-in state to 'storageState.json'.
await page.context().storageState({ path: 'storageState.json' }); await page.context().storageState({ path: 'storageState.json' });
await browser.close(); await browser.close();
@ -226,9 +226,9 @@ exports.test = base.extend({
// Make sure we are not using any other storage state. // Make sure we are not using any other storage state.
const page = await browser.newPage({ storageState: undefined }); const page = await browser.newPage({ storageState: undefined });
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="login"]').fill(users[testInfo.workerIndex].username); await page.getByLabelText('User Name').fill(users[testInfo.workerIndex].username);
await page.locator('input[name="password"]').fill(users[testInfo.workerIndex].password); await page.getByLabelText('Password').fill(users[testInfo.workerIndex].password);
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await page.context().storageState({ path: fileName }); await page.context().storageState({ path: fileName });
await page.close(); await page.close();
} }
@ -265,9 +265,9 @@ export const test = baseTest.extend({
const page = await browser.newPage({ storageState: undefined }); const page = await browser.newPage({ storageState: undefined });
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
// Create a unique username for each worker. // Create a unique username for each worker.
await page.locator('input[name="login"]').fill(users[testInfo.workerIndex].username); await page.getByLabelText('User Name').fill(users[testInfo.workerIndex].username);
await page.locator('input[name="password"]').fill(users[testInfo.workerIndex].password); await page.getByLabelText('Password').fill(users[testInfo.workerIndex].password);
await page.locator('input:has-text("Sign in")').click(); await page.getByText('Sign in').click();
await page.context().storageState({ path: fileName }); await page.context().storageState({ path: fileName });
await page.close(); await page.close();
} }
@ -558,9 +558,9 @@ test.beforeAll(async ({ browser }) => {
// Create page yourself and sign in. // Create page yourself and sign in.
page = await browser.newPage(); page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('input:has-text("Sign in")').click(); await page.getByText('Sign in').click();
}); });
test.afterAll(async () => { test.afterAll(async () => {
@ -589,9 +589,9 @@ test.beforeAll(async ({ browser }) => {
// Create page once and sign in. // Create page once and sign in.
page = await browser.newPage(); page = await browser.newPage();
await page.goto('https://github.com/login'); await page.goto('https://github.com/login');
await page.locator('input[name="user"]').fill('user'); await page.getByLabelText('User Name').fill('user');
await page.locator('input[name="password"]').fill('password'); await page.getByLabelText('Password').fill('password');
await page.locator('input:has-text("Sign in")').click(); await page.getByText('Sign in').click();
}); });
test.afterAll(async () => { test.afterAll(async () => {

View file

@ -334,9 +334,9 @@ exports.test = base.test.extend({
// Create the account with Playwright. // Create the account with Playwright.
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto('/signup'); await page.goto('/signup');
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
await page.locator('text=Sign up').click(); await page.getByText('Sign up').click();
// Make sure everything is ok. // Make sure everything is ok.
await expect(page.locator('#result')).toHaveText('Success'); await expect(page.locator('#result')).toHaveText('Success');
// Do not forget to cleanup. // Do not forget to cleanup.
@ -350,9 +350,9 @@ exports.test = base.test.extend({
// Sign in with our account. // Sign in with our account.
const { username, password } = account; const { username, password } = account;
await page.goto('/signin'); await page.goto('/signin');
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await expect(page.locator('#userinfo')).toHaveText(username); await expect(page.locator('#userinfo')).toHaveText(username);
// Use signed-in page in the test. // Use signed-in page in the test.
@ -381,9 +381,9 @@ export const test = base.extend<{}, { account: Account }>({
// Create the account with Playwright. // Create the account with Playwright.
const page = await browser.newPage(); const page = await browser.newPage();
await page.goto('/signup'); await page.goto('/signup');
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
await page.locator('text=Sign up').click(); await page.getByText('Sign up').click();
// Make sure everything is ok. // Make sure everything is ok.
await expect(page.locator('#result')).toHaveText('Success'); await expect(page.locator('#result')).toHaveText('Success');
// Do not forget to cleanup. // Do not forget to cleanup.
@ -397,9 +397,9 @@ export const test = base.extend<{}, { account: Account }>({
// Sign in with our account. // Sign in with our account.
const { username, password } = account; const { username, password } = account;
await page.goto('/signin'); await page.goto('/signin');
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
await page.locator('text=Sign in').click(); await page.getByText('Sign in').click();
await expect(page.locator('#userinfo')).toHaveText(username); await expect(page.locator('#userinfo')).toHaveText(username);
// Use signed-in page in the test. // Use signed-in page in the test.

View file

@ -142,7 +142,7 @@ test('runs first', async () => {
}); });
test('runs second', async () => { test('runs second', async () => {
await page.locator('text=Get Started').click(); await page.getByText('Get Started').click();
}); });
``` ```
@ -169,7 +169,7 @@ test('runs first', async () => {
}); });
test('runs second', async () => { test('runs second', async () => {
await page.locator('text=Get Started').click(); await page.getByText('Get Started').click();
}); });
``` ```

View file

@ -143,8 +143,8 @@ exports.test = base.test.extend({
page: async ({ page, person }, use) => { page: async ({ page, person }, use) => {
await page.goto('/chat'); await page.goto('/chat');
// We use "person" parameter as a "name" for the chat room. // We use "person" parameter as a "name" for the chat room.
await page.locator('#name').fill(person); await page.getByLabelText('User Name').fill(person);
await page.locator('text=Enter chat room').click(); await page.getByText('Enter chat room').click();
// Each test will get a "page" that already has the person name. // Each test will get a "page" that already has the person name.
await use(page); await use(page);
}, },
@ -168,8 +168,8 @@ export const test = base.test.extend<TestOptions>({
page: async ({ page, person }, use) => { page: async ({ page, person }, use) => {
await page.goto('/chat'); await page.goto('/chat');
// We use "person" parameter as a "name" for the chat room. // We use "person" parameter as a "name" for the chat room.
await page.locator('#name').fill(person); await page.getByLabelText('User Name').fill(person);
await page.locator('text=Enter chat room').click(); await page.getByText('Enter chat room').click();
// Each test will get a "page" that already has the person name. // Each test will get a "page" that already has the person name.
await use(page); await use(page);
}, },
@ -190,8 +190,8 @@ For example, consider the following test file that needs a username and a passwo
// example.spec.js // example.spec.js
test(`example test`, async ({ page }) => { test(`example test`, async ({ page }) => {
// ... // ...
await page.locator('#username').fill(process.env.USERNAME); await page.getByLabelText('User Name').fill(process.env.USERNAME);
await page.locator('#password').fill(process.env.PASSWORD); await page.getByLabelText('Password').fill(process.env.PASSWORD);
}); });
``` ```
@ -199,8 +199,8 @@ test(`example test`, async ({ page }) => {
// example.spec.ts // example.spec.ts
test(`example test`, async ({ page }) => { test(`example test`, async ({ page }) => {
// ... // ...
await page.locator('#username').fill(process.env.USERNAME); await page.getByLabelText('User Name').fill(process.env.USERNAME);
await page.locator('#password').fill(process.env.PASSWORD); await page.getByLabelText('Password').fill(process.env.PASSWORD);
}); });
``` ```

View file

@ -213,7 +213,7 @@ test('runs first', async () => {
}); });
test('runs second', async () => { test('runs second', async () => {
await page.locator('text=Get Started').click(); await page.getByText('Get Started').click();
}); });
``` ```
@ -239,6 +239,6 @@ test('runs first', async () => {
}); });
test('runs second', async () => { test('runs second', async () => {
await page.locator('text=Get Started').click(); await page.getByText('Get Started').click();
}); });
``` ```

View file

@ -185,7 +185,7 @@ API reference: [`property: TestConfig.expect`].
const { test, expect } = require('@playwright/test'); const { test, expect } = require('@playwright/test');
test('basic test', async ({ page }) => { test('basic test', async ({ page }) => {
await expect(page.locator('button')).toHaveText('Sign in', { timeout: 10000 }); await expect(page.getByRole('button')).toHaveText('Sign in', { timeout: 10000 });
}); });
``` ```
@ -193,7 +193,7 @@ test('basic test', async ({ page }) => {
import { test, expect } from '@playwright/test'; import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => { test('basic test', async ({ page }) => {
await expect(page.locator('button')).toHaveText('Sign in', { timeout: 10000 }); await expect(page.getByRole('button')).toHaveText('Sign in', { timeout: 10000 });
}); });
``` ```
@ -251,7 +251,7 @@ const { test, expect } = require('@playwright/test');
test('basic test', async ({ page }) => { test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev', { timeout: 30000 }); await page.goto('https://playwright.dev', { timeout: 30000 });
await page.locator('text=Get Started').click({ timeout: 10000 }); await page.getByText('Get Started').click({ timeout: 10000 });
}); });
``` ```
@ -260,7 +260,7 @@ import { test, expect } from '@playwright/test';
test('basic test', async ({ page }) => { test('basic test', async ({ page }) => {
await page.goto('https://playwright.dev', { timeout: 30000 }); await page.goto('https://playwright.dev', { timeout: 30000 });
await page.locator('text=Get Started').click({ timeout: 10000 }); await page.getByText('Get Started').click({ timeout: 10000 });
}); });
``` ```

View file

@ -25,8 +25,8 @@ import { test, expect } from '@playwright/test';
import { username, password } from './helper'; import { username, password } from './helper';
test('example', async ({ page }) => { test('example', async ({ page }) => {
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
}); });
``` ```
@ -62,8 +62,8 @@ import { test, expect } from '@playwright/test';
import { username, password } from './helper.ts'; import { username, password } from './helper.ts';
test('example', async ({ page }) => { test('example', async ({ page }) => {
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
}); });
``` ```
@ -96,8 +96,8 @@ import { test, expect } from '@playwright/test';
import { username, password } from '@myhelper/credentials'; import { username, password } from '@myhelper/credentials';
test('example', async ({ page }) => { test('example', async ({ page }) => {
await page.locator('#username').fill(username); await page.getByLabelText('User Name').fill(username);
await page.locator('#password').fill(password); await page.getByLabelText('Password').fill(password);
}); });
``` ```

View file

@ -27,7 +27,7 @@ If you use DOM Testing Library in the browser (for example, you bundle end-to-en
| `expect(screen.getByLabelText('Password')).toHaveValue('secret')` | `await expect(component.getByLabelText('Password')).toHaveValue('secret')` | | `expect(screen.getByLabelText('Password')).toHaveValue('secret')` | `await expect(component.getByLabelText('Password')).toHaveValue('secret')` |
| `screen.findByText('...')` | `component.getByText('...')` | | `screen.findByText('...')` | `component.getByText('...')` |
| `screen.getByTestId('...')` | `component.getByTestId('...')` | | `screen.getByTestId('...')` | `component.getByTestId('...')` |
| `screen.queryByPlaceholderText('...')` | `component.locator('[placeholder="..."]')` | | `screen.queryByPlaceholderText('...')` | `component.getByPlaceholderText('...')` |
| `screen.getByRole('button', { pressed: true })` | `component.getByRole('button', { pressed: true })`| | `screen.getByRole('button', { pressed: true })` | `component.getByRole('button', { pressed: true })`|
## Example ## Example
@ -64,12 +64,12 @@ test('should sign in', async ({ page, mount }) => { // 2
const component = await mount(<SignInPage />); // 3 const component = await mount(<SignInPage />); // 3
// Perform actions. // Perform actions.
await component.locator('text=Username').fill('John'); // 4 await component.getByText('Username').fill('John'); // 4
await component.locator('text=Password').fill('secret'); await component.getByText('Password').fill('secret');
await component.locator('text=Sign in').click(); await component.getByText('Sign in').click();
// Verify signed in state by waiting until "Welcome" message appears. // Verify signed in state by waiting until "Welcome" message appears.
await expect(component.locator('text=Welcome, John')).toBeVisible(); // 5 await expect(component.getByText('Welcome, John')).toBeVisible(); // 5
}); });
``` ```
@ -83,14 +83,7 @@ Migration highlights (see inline comments in the Playwright Test code snippet):
## Migrating queries ## Migrating queries
All queries like `getBy...`, `findBy...`, `queryBy...` and their multi-element counterparts are replaced with `page.locator('...')`. Locators always auto-wait and retry when needed, so you don't have to worry about choosing the right method. When you want to do a [list operation](./locators#lists), e.g. assert a list of texts, Playwright automatically performs multi-element operations. All queries like `getBy...`, `findBy...`, `queryBy...` and their multi-element counterparts are replaced with `component.getBy...` locators. Locators always auto-wait and retry when needed, so you don't have to worry about choosing the right method. When you want to do a [list operation](./locators#lists), e.g. assert a list of texts, Playwright automatically performs multi-element operations.
1. `getByRole`: use [role selector](./selectors#role-selector) `component.locator('role=button[name="Sign up"]')`.
1. `getByText`: use `component.locator('text=some value')` and other variations of the [text selector](./selectors#text-selector).
1. `getByTestId`: use [test id selectors](./selectors#id-data-testid-data-test-id-data-test-selectors), for example `component.locator('data-testid=some value')`.
1. `getByPlaceholderText`: use css alternative `component.locator('[placeholder="some value"]')`.
1. `getByAltText`: use css alternative `component.locator('[alt="some value"]')` or [role selector](./selectors#role-selector) `component.locator('role=img[name="some value"]')`.
1. `getByTitle`: use css alternative `component.locator('[title="some value"]')`
## Replacing `waitFor` ## Replacing `waitFor`
@ -104,8 +97,8 @@ await waitFor(() => {
await waitForElementToBeRemoved(() => queryByText('the mummy')) await waitForElementToBeRemoved(() => queryByText('the mummy'))
// Playwright // Playwright
await expect(page.locator('text=the lion king')).toBeVisible() await expect(page.getByText('the lion king')).toBeVisible()
await expect(page.locator('text=the mummy')).toBeHidden() await expect(page.getByText('the mummy')).toBeHidden()
``` ```
When you cannot find a suitable assertion, use [`expect.poll`](./test-assertions#polling) instead. When you cannot find a suitable assertion, use [`expect.poll`](./test-assertions#polling) instead.
@ -128,7 +121,7 @@ const helloMessage = within(messages).getByText('hello')
// Playwright // Playwright
const messages = component.locator('id=messages') const messages = component.locator('id=messages')
const helloMessage = messages.locator('text=hello') const helloMessage = messages.getByText('hello')
``` ```
## Playwright Test Super Powers ## Playwright Test Super Powers

View file

@ -120,7 +120,7 @@ import { test, expect } from './webView2Test';
test('test WebView2', async ({ page }) => { test('test WebView2', async ({ page }) => {
await page.goto('https://playwright.dev'); await page.goto('https://playwright.dev');
const getStarted = page.locator('text=Get Started'); const getStarted = page.getByText('Get Started');
await expect(getStarted).toBeVisible(); await expect(getStarted).toBeVisible();
}); });
``` ```
@ -242,7 +242,7 @@ public class TestExample {
@Test @Test
public void shouldClickButton() { public void shouldClickButton() {
page.navigate("https://playwright.dev"); page.navigate("https://playwright.dev");
Locator gettingStarted = page.locator("text=Get started"); Locator gettingStarted = page.getByText("Get started");
assertThat(gettingStarted).isVisible(); assertThat(gettingStarted).isVisible();
} }
} }
@ -338,7 +338,7 @@ from playwright.sync_api import Page, expect
def test_webview2(page: Page): def test_webview2(page: Page):
page.goto("https://playwright.dev") page.goto("https://playwright.dev")
get_started = page.locator("text=Get Started") get_started = page.get_by_text("Get Started")
expect(get_started).to_be_visible() expect(get_started).to_be_visible()
``` ```
@ -420,7 +420,7 @@ public class Tests : WebView2Test
public async Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage() public async Task HomepageHasPlaywrightInTitleAndGetStartedLinkLinkingtoTheIntroPage()
{ {
await Page.GotoAsync("https://playwright.dev"); await Page.GotoAsync("https://playwright.dev");
var getStarted = Page.Locator("text=Get Started"); var getStarted = Page.GetByText("Get Started");
await Expect(getStarted).ToBeVisibleAsync(); await Expect(getStarted).ToBeVisibleAsync();
} }
} }

View file

@ -28,14 +28,14 @@ test('homepage has Playwright in title and get started link linking to the intro
await expect(page).toHaveTitle(/Playwright/); await expect(page).toHaveTitle(/Playwright/);
// create a locator // create a locator
const getStarted = page.locator('text=Get Started'); const getStarted = page.getByText('Get Started');
// Expect an attribute "to be strictly equal" to the value. // Expect an attribute "to be strictly equal" to the value.
await expect(getStarted).toHaveAttribute('href', '/docs/intro'); await expect(getStarted).toHaveAttribute('href', '/docs/intro');
// Click the get started link. // Click the get started link.
await getStarted.click(); await getStarted.click();
// Expects the URL to contain intro. // Expects the URL to contain intro.
await expect(page).toHaveURL(/.*intro/); await expect(page).toHaveURL(/.*intro/);
}); });
@ -51,7 +51,7 @@ test('homepage has Playwright in title and get started link linking to the intro
await expect(page).toHaveTitle(/Playwright/); await expect(page).toHaveTitle(/Playwright/);
// create a locator // create a locator
const getStarted = page.locator('text=Get Started'); const getStarted = page.getByText('Get Started');
// Expect an attribute "to be strictly equal" to the value. // Expect an attribute "to be strictly equal" to the value.
await expect(getStarted).toHaveAttribute('href', '/docs/intro'); await expect(getStarted).toHaveAttribute('href', '/docs/intro');
@ -82,7 +82,7 @@ await expect(page).toHaveTitle(/Playwright/);
[Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as `.click` `.fill` etc. Custom locators can be created with the [`method: Page.locator`] method. [Locators](./locators.md) are the central piece of Playwright's auto-waiting and retry-ability. Locators represent a way to find element(s) on the page at any moment and are used to perform actions on elements such as `.click` `.fill` etc. Custom locators can be created with the [`method: Page.locator`] method.
```js ```js
const getStarted = page.locator('text=Get Started'); const getStarted = page.getByText('Get Started');
await expect(getStarted).toHaveAttribute('href', '/docs/installation'); await expect(getStarted).toHaveAttribute('href', '/docs/installation');
await getStarted.click(); await getStarted.click();
@ -92,7 +92,7 @@ await getStarted.click();
```js ```js
await expect(page.locator('text=Installation')).toBeVisible(); await expect(page.getByText('Installation')).toBeVisible();
``` ```

View file

@ -2421,7 +2421,7 @@ export interface Page {
* id="my-frame">`: * id="my-frame">`:
* *
* ```js * ```js
* const locator = page.frameLocator('#my-iframe').locator('text=Submit'); * const locator = page.frameLocator('#my-iframe').getByText('Submit');
* await locator.click(); * await locator.click();
* ``` * ```
* *
@ -4152,7 +4152,7 @@ export interface Page {
* when this method is called. If current document has already reached the required state, resolves immediately. * when this method is called. If current document has already reached the required state, resolves immediately.
* *
* ```js * ```js
* await page.click('button'); // Click triggers navigation. * await page.getByRole('button').click(); // Click triggers navigation.
* await page.waitForLoadState(); // The promise resolves after 'load' event. * await page.waitForLoadState(); // The promise resolves after 'load' event.
* ``` * ```
* *
@ -4161,7 +4161,7 @@ export interface Page {
* // It is important to call waitForEvent before click to set up waiting. * // It is important to call waitForEvent before click to set up waiting.
* page.waitForEvent('popup'), * page.waitForEvent('popup'),
* // Click triggers a popup. * // Click triggers a popup.
* page.locator('button').click(), * page.getByRole('button').click(),
* ]) * ])
* await popup.waitForLoadState('domcontentloaded'); // The promise resolves after 'domcontentloaded' event. * await popup.waitForLoadState('domcontentloaded'); // The promise resolves after 'domcontentloaded' event.
* console.log(await popup.title()); // Popup is ready to use. * console.log(await popup.title()); // Popup is ready to use.
@ -5512,7 +5512,7 @@ export interface Frame {
* id="my-frame">`: * id="my-frame">`:
* *
* ```js * ```js
* const locator = frame.frameLocator('#my-iframe').locator('text=Submit'); * const locator = frame.frameLocator('#my-iframe').getByText('Submit');
* await locator.click(); * await locator.click();
* ``` * ```
* *
@ -6724,7 +6724,7 @@ export interface BrowserContext {
* <button onclick="onClick()">Click me</button> * <button onclick="onClick()">Click me</button>
* <div></div> * <div></div>
* `); * `);
* await page.locator('button').click(); * await page.getByRole('button').click();
* })(); * })();
* ``` * ```
* *
@ -6778,7 +6778,7 @@ export interface BrowserContext {
* <button onclick="onClick()">Click me</button> * <button onclick="onClick()">Click me</button>
* <div></div> * <div></div>
* `); * `);
* await page.locator('button').click(); * await page.getByRole('button').click();
* })(); * })();
* ``` * ```
* *
@ -7350,7 +7350,7 @@ export interface BrowserContext {
* <button onclick="onClick()">Click me</button> * <button onclick="onClick()">Click me</button>
* <div></div> * <div></div>
* `); * `);
* await page.locator('button').click(); * await page.getByRole('button').click();
* })(); * })();
* ``` * ```
* *
@ -8030,7 +8030,7 @@ export interface JSHandle<T = any> {
* in the snippet below, underlying DOM element is going to be located twice. * in the snippet below, underlying DOM element is going to be located twice.
* *
* ```js * ```js
* const locator = page.locator('text=Submit'); * const locator = page.getByText('Submit');
* // ... * // ...
* await locator.hover(); * await locator.hover();
* await locator.click(); * await locator.click();
@ -9906,7 +9906,7 @@ export interface Locator {
* // ... * // ...
* await rowLocator * await rowLocator
* .filter({ hasText: 'text in column 1' }) * .filter({ hasText: 'text in column 1' })
* .filter({ has: page.locator('button', { hasText: 'column 2 button' }) }) * .filter({ has: page.getByRole('button', { name: 'column 2 button' }) })
* .screenshot(); * .screenshot();
* ``` * ```
* *
@ -9953,7 +9953,7 @@ export interface Locator {
* that iframe: * that iframe:
* *
* ```js * ```js
* const locator = page.frameLocator('iframe').locator('text=Submit'); * const locator = page.frameLocator('iframe').getByText('Submit');
* await locator.click(); * await locator.click();
* ``` * ```
* *
@ -10746,8 +10746,8 @@ export interface Locator {
* An example of typing into a text field and then submitting the form: * An example of typing into a text field and then submitting the form:
* *
* ```js * ```js
* const element = page.locator('input'); * const element = page.getByLabelText('Password');
* await element.type('some text'); * await element.type('my password');
* await element.press('Enter'); * await element.press('Enter');
* ``` * ```
* *
@ -14805,7 +14805,7 @@ export interface Dialog {
* // It is important to call waitForEvent before click to set up waiting. * // It is important to call waitForEvent before click to set up waiting.
* page.waitForEvent('download'), * page.waitForEvent('download'),
* // Triggers the download. * // Triggers the download.
* page.locator('text=Download file').click(), * page.getByText('Download file').click(),
* ]); * ]);
* // wait for download to complete * // wait for download to complete
* const path = await download.path(); * const path = await download.path();
@ -15108,7 +15108,7 @@ export interface Electron {
* // It is important to call waitForEvent before click to set up waiting. * // It is important to call waitForEvent before click to set up waiting.
* page.waitForEvent('filechooser'), * page.waitForEvent('filechooser'),
* // Opens the file chooser. * // Opens the file chooser.
* page.locator('text=Upload').click(), * page.getByText('Upload').click(),
* ]); * ]);
* await fileChooser.setFiles('myfile.pdf'); * await fileChooser.setFiles('myfile.pdf');
* ``` * ```
@ -15191,7 +15191,7 @@ export interface FileChooser {
* [locator.frameLocator(selector)](https://playwright.dev/docs/api/class-locator#locator-frame-locator) method. * [locator.frameLocator(selector)](https://playwright.dev/docs/api/class-locator#locator-frame-locator) method.
* *
* ```js * ```js
* const locator = page.frameLocator('#my-frame').locator('text=Submit'); * const locator = page.frameLocator('#my-frame').getByText('Submit');
* await locator.click(); * await locator.click();
* ``` * ```
* *
@ -15202,10 +15202,10 @@ export interface FileChooser {
* *
* ```js * ```js
* // Throws if there are several frames in DOM: * // Throws if there are several frames in DOM:
* await page.frameLocator('.result-frame').locator('button').click(); * await page.frameLocator('.result-frame').getByRole('button').click();
* *
* // Works because we explicitly tell locator to pick the first frame: * // Works because we explicitly tell locator to pick the first frame:
* await page.frameLocator('.result-frame').first().locator('button').click(); * await page.frameLocator('.result-frame').first().getByRole('button').click();
* ``` * ```
* *
* **Converting Locator to FrameLocator** * **Converting Locator to FrameLocator**
@ -16572,7 +16572,7 @@ export interface Tracing {
* await page.goto('https://playwright.dev'); * await page.goto('https://playwright.dev');
* *
* await context.tracing.startChunk(); * await context.tracing.startChunk();
* await page.locator('text=Get Started').click(); * await page.getByText('Get Started').click();
* // Everything between startChunk and stopChunk will be recorded in the trace. * // Everything between startChunk and stopChunk will be recorded in the trace.
* await context.tracing.stopChunk({ path: 'trace1.zip' }); * await context.tracing.stopChunk({ path: 'trace1.zip' });
* *

View file

@ -3078,9 +3078,9 @@ export interface PlaywrightTestArgs {
* *
* test('basic test', async ({ page }) => { * test('basic test', async ({ page }) => {
* await page.goto('/signin'); * await page.goto('/signin');
* await page.locator('#username').fill('User'); * await page.getByLabelText('User Name').fill('user');
* await page.locator('#password').fill('pwd'); * await page.getByLabelText('Password').fill('password');
* await page.locator('text=Sign in').click(); * await page.getByText('Sign in').click();
* // ... * // ...
* }); * });
* ``` * ```
@ -3255,7 +3255,7 @@ interface APIResponseAssertions {
* *
* test('status becomes submitted', async ({ page }) => { * test('status becomes submitted', async ({ page }) => {
* // ... * // ...
* await page.locator('#submit-button').click(); * await page.getByRole('button').click();
* await expect(page.locator('.status')).toHaveText('Submitted'); * await expect(page.locator('.status')).toHaveText('Submitted');
* }); * });
* ``` * ```
@ -3277,7 +3277,7 @@ interface LocatorAssertions {
* Ensures the [Locator] points to a checked input. * Ensures the [Locator] points to a checked input.
* *
* ```js * ```js
* const locator = page.locator('.subscribe'); * const locator = page.getByLabelText('Subscribe to newsletter');
* await expect(locator).toBeChecked(); * await expect(locator).toBeChecked();
* ``` * ```
* *
@ -3316,7 +3316,7 @@ interface LocatorAssertions {
* Ensures the [Locator] points to an editable element. * Ensures the [Locator] points to an editable element.
* *
* ```js * ```js
* const locator = page.locator('input'); * const locator = page.getByRole('textbox');
* await expect(locator).toBeEditable(); * await expect(locator).toBeEditable();
* ``` * ```
* *
@ -3371,7 +3371,7 @@ interface LocatorAssertions {
* Ensures the [Locator] points to a focused DOM node. * Ensures the [Locator] points to a focused DOM node.
* *
* ```js * ```js
* const locator = page.locator('input'); * const locator = page.getByRole('textbox');
* await expect(locator).toBeFocused(); * await expect(locator).toBeFocused();
* ``` * ```
* *
@ -3557,7 +3557,7 @@ interface LocatorAssertions {
* Ensures the [Locator] resolves to an element with the given computed CSS style. * Ensures the [Locator] resolves to an element with the given computed CSS style.
* *
* ```js * ```js
* const locator = page.locator('button'); * const locator = page.getByRole('button');
* await expect(locator).toHaveCSS('display', 'flex'); * await expect(locator).toHaveCSS('display', 'flex');
* ``` * ```
* *
@ -3576,7 +3576,7 @@ interface LocatorAssertions {
* Ensures the [Locator] points to an element with the given DOM Node ID. * Ensures the [Locator] points to an element with the given DOM Node ID.
* *
* ```js * ```js
* const locator = page.locator('input'); * const locator = page.getByRole('textbox');
* await expect(locator).toHaveId('lastname'); * await expect(locator).toHaveId('lastname');
* ``` * ```
* *
@ -3615,7 +3615,7 @@ interface LocatorAssertions {
* screenshot with the expectation. * screenshot with the expectation.
* *
* ```js * ```js
* const locator = page.locator('button'); * const locator = page.getByRole('button');
* await expect(locator).toHaveScreenshot('image.png'); * await expect(locator).toHaveScreenshot('image.png');
* ``` * ```
* *
@ -3690,7 +3690,7 @@ interface LocatorAssertions {
* screenshot with the expectation. * screenshot with the expectation.
* *
* ```js * ```js
* const locator = page.locator('button'); * const locator = page.getByRole('button');
* await expect(locator).toHaveScreenshot(); * await expect(locator).toHaveScreenshot();
* ``` * ```
* *
@ -3880,7 +3880,7 @@ interface LocatorAssertions {
* *
* test('navigates to login', async ({ page }) => { * test('navigates to login', async ({ page }) => {
* // ... * // ...
* await page.locator('#login').click(); * await page.getByText('Sign in').click();
* await expect(page).toHaveURL(/.*\/login/); * await expect(page).toHaveURL(/.*\/login/);
* }); * });
* ``` * ```