docs: migrate page actions to locator actions 1/n (#15586)

This commit is contained in:
Max Schmitt 2022-07-12 22:39:31 +02:00 committed by GitHub
parent 8858162692
commit 428cdc073c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 228 additions and 244 deletions

View file

@ -65,6 +65,12 @@ actionable state:
- [`method: Page.isEnabled`] - [`method: Page.isEnabled`]
- [`method: Page.isHidden`] - [`method: Page.isHidden`]
- [`method: Page.isVisible`] - [`method: Page.isVisible`]
- [`method: Locator.isChecked`]
- [`method: Locator.isDisabled`]
- [`method: Locator.isEditable`]
- [`method: Locator.isEnabled`]
- [`method: Locator.isHidden`]
- [`method: Locator.isVisible`]
<br/> <br/>

View file

@ -368,10 +368,10 @@ it was created:
public async Task LastCreatedIssueShouldBeOnTheServer() public async Task LastCreatedIssueShouldBeOnTheServer()
{ {
await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues"); await Page.GotoAsync("https://github.com/" + USER + "/" + REPO + "/issues");
await Page.ClickAsync("text=New Issue"); await Page.Locator("text=New Issue").ClickAsync();
await Page.FillAsync("[aria-label='Title']", "Bug report 1"); await Page.Locator("[aria-label='Title']").FillAsync("Bug report 1");
await Page.FillAsync("[aria-label='Comment body']", "Bug description"); await Page.Locator("[aria-label='Comment body']").FillAsync("Bug description");
await Page.ClickAsync("text=Submit new issue"); await Page.Locator("text=Submit new issue").ClickAsync();
String issueId = Page.Url.Substring(Page.Url.LastIndexOf('/')); String issueId = Page.Url.Substring(Page.Url.LastIndexOf('/'));
var newIssue = await Request.GetAsync("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId); var newIssue = await Request.GetAsync("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId);

View file

@ -403,10 +403,10 @@ it was created:
@Test @Test
void lastCreatedIssueShouldBeOnTheServer() { void lastCreatedIssueShouldBeOnTheServer() {
page.navigate("https://github.com/" + USER + "/" + REPO + "/issues"); page.navigate("https://github.com/" + USER + "/" + REPO + "/issues");
page.click("text=New Issue"); page.locator("text=New Issue").click();
page.fill("[aria-label='Title']", "Bug report 1"); page.locator("[aria-label='Title']").fill("Bug report 1");
page.fill("[aria-label='Comment body']", "Bug description"); page.locator("[aria-label='Comment body']").fill("Bug description");
page.click("text=Submit new issue"); page.locator("text=Submit new issue").click();
String issueId = page.url().substring(page.url().lastIndexOf('/')); String issueId = page.url().substring(page.url().lastIndexOf('/'));
APIResponse newIssue = request.get("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId); APIResponse newIssue = request.get("https://github.com/" + USER + "/" + REPO + "/issues/" + issueId);

View file

@ -254,10 +254,10 @@ it was created:
```python ```python
def test_last_created_issue_should_be_on_the_server(api_request_context: APIRequestContext, page: Page) -> None: def test_last_created_issue_should_be_on_the_server(api_request_context: APIRequestContext, page: Page) -> None:
page.goto(f"https://github.com/{GITHUB_USER}/{GITHUB_REPO}/issues") page.goto(f"https://github.com/{GITHUB_USER}/{GITHUB_REPO}/issues")
page.click("text=New issue") page.locator("text=New issue").click()
page.fill("[aria-label='Title']", "Bug report 1") page.locator("[aria-label='Title']").fill("Bug report 1")
page.fill("[aria-label='Comment body']", "Bug description") page.locator("[aria-label='Comment body']").fill("Bug description")
page.click("text=Submit new issue") page.locator("text=Submit new issue").click()
issue_id = page.url.split("/")[-1] issue_id = page.url.split("/")[-1]
new_issue = api_request_context.get(f"https://github.com/{GITHUB_USER}/{GITHUB_REPO}/issues/{issue_id}") new_issue = api_request_context.get(f"https://github.com/{GITHUB_USER}/{GITHUB_REPO}/issues/{issue_id}")

View file

@ -78,7 +78,7 @@ class BrowserTypeExamples
var chromium = playwright.Chromium; var chromium = playwright.Chromium;
var browser = await chromium.LaunchAsync(); var browser = await chromium.LaunchAsync();
var page = await browser.NewPageAsync(); var page = await browser.NewPageAsync();
await page.GoToAsync("https://www.bing.com"); await page.GotoAsync("https://www.bing.com");
// other actions // other actions
await browser.CloseAsync(); await browser.CloseAsync();
} }

View file

@ -29,10 +29,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.click('text=Login'); await page.locator('text=Login').click();
await page.fill('input[name="login"]', USERNAME); await page.locator('input[name="login"]').fill(USERNAME);
await page.fill('input[name="password"]', PASSWORD); await page.locator('input[name="password"]').fill(PASSWORD);
await page.click('text=Submit'); await page.locator('text=Submit').click();
// Verify app is logged in // Verify app is logged in
``` ```
@ -40,10 +40,10 @@ await page.click('text=Submit');
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.click("text=Login"); page.locator("text=Login").click();
page.fill("input[name='login']", USERNAME); page.locator("input[name='login']").fill(USERNAME);
page.fill("input[name='password']", PASSWORD); page.locator("input[name='password']").fill(PASSWORD);
page.click("text=Submit"); page.locator("text=Submit").click();
// Verify app is logged in // Verify app is logged in
``` ```
@ -52,10 +52,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.click('text=Login') await page.locator('text=Login').click()
await page.fill('input[name="login"]', USERNAME) await page.locator('input[name="login"]').fill(USERNAME)
await page.fill('input[name="password"]', PASSWORD) await page.locator('input[name="password"]').fill(PASSWORD)
await page.click('text=Submit') await page.locator('text=Submit').click()
# Verify app is logged in # Verify app is logged in
``` ```
@ -64,21 +64,21 @@ 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.click('text=Login') page.locator('text=Login').click()
page.fill('input[name="login"]', USERNAME) page.locator('input[name="login"]').fill(USERNAME)
page.fill('input[name="password"]', PASSWORD) page.locator('input[name="password"]').fill(PASSWORD)
page.click('text=Submit') page.locator('text=Submit').click()
# Verify app is logged in # Verify app is logged in
``` ```
```csharp ```csharp
var page = await context.NewPageAsync(); var page = await context.NewPageAsync();
await page.NavigateAsync("https://github.com/login"); await page.GotoAsync("https://github.com/login");
// Interact with login form // Interact with login form
await page.ClickAsync("text=Login"); await page.Locator("text=Login").ClickAsync();
await page.FillAsync("input[name='login']", USERNAME); await page.Locator("input[name='login']").FillAsync(USERNAME);
await page.FillAsync("input[name='password']", PASSWORD); await page.Locator("input[name='password']").FillAsync(PASSWORD);
await page.ClickAsync("text=Submit"); await page.Locator("text=Submit").ClickAsync();
// Verify app is logged in // Verify app is logged in
``` ```

View file

@ -13,27 +13,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.click('button'); await page.locator('button').click();
``` ```
```java ```java
page.onDialog(dialog -> dialog.accept()); page.onDialog(dialog -> dialog.accept());
page.click("button"); page.locator("button").click();
``` ```
```python async ```python async
page.on("dialog", lambda dialog: dialog.accept()) page.on("dialog", lambda dialog: dialog.accept())
await page.click("button") await page.locator("button".click())
``` ```
```python sync ```python sync
page.on("dialog", lambda dialog: dialog.accept()) page.on("dialog", lambda dialog: dialog.accept())
page.click("button") page.locator("button").click()
``` ```
```csharp ```csharp
page.Dialog += (_, dialog) => dialog.AcceptAsync(); page.Dialog += (_, dialog) => dialog.AcceptAsync();
await page.ClickAsync("button"); await page.Locator("button").ClickAsync();
``` ```
:::note :::note
@ -48,27 +48,27 @@ WRONG!
```js ```js
page.on('dialog', dialog => console.log(dialog.message())); page.on('dialog', dialog => console.log(dialog.message()));
await page.click('button'); // Will hang here await page.locator('button').click(); // Will hang here
``` ```
```java ```java
page.onDialog(dialog -> System.out.println(dialog.message())); page.onDialog(dialog -> System.out.println(dialog.message()));
page.click("button"); // Will hang here page.locator("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.click("button") # Will hang here await page.locator("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.click("button") # Will hang here page.locator("button").click() # Will hang here
``` ```
```csharp ```csharp
page.Dialog += (_, dialog) => Console.WriteLine(dialog.Message); page.Dialog += (_, dialog) => Console.WriteLine(dialog.Message);
await page.ClickAsync("button"); // Will hang here await page.Locator("button").ClickAsync(); // Will hang here
``` ```
:::note :::note
@ -92,7 +92,7 @@ page.on('dialog', async dialog => {
assert(dialog.type() === 'beforeunload'); assert(dialog.type() === 'beforeunload');
await dialog.dismiss(); await dialog.dismiss();
}); });
await page.close({runBeforeUnload: true}); await page.close({ runBeforeUnload: true });
``` ```
```java ```java

View file

@ -34,7 +34,7 @@ const path = await download.path();
// Wait for the download to start // Wait for the download to start
Download download = page.waitForDownload(() -> { Download download = page.waitForDownload(() -> {
// Perform the action that initiates download // Perform the action that initiates download
page.click("button#delayed-download"); page.locator("button#delayed-download").click();
}); });
// Wait for the download process to complete // Wait for the download process to complete
Path path = download.path(); Path path = download.path();
@ -44,7 +44,7 @@ Path path = download.path();
# Start waiting for the download # Start waiting for the download
async with page.expect_download() as download_info: async with page.expect_download() as download_info:
# Perform the action that initiates download # Perform the action that initiates download
await page.click("button#delayed-download") await page.locator("button#delayed-download").click()
download = await download_info.value download = await download_info.value
# Wait for the download process to complete # Wait for the download process to complete
path = await download.path() path = await download.path()
@ -54,7 +54,7 @@ path = await download.path()
# Start waiting for the download # Start waiting for the download
with page.expect_download() as download_info: with page.expect_download() as download_info:
# Perform the action that initiates download # Perform the action that initiates download
page.click("button#delayed-download") page.locator("button#delayed-download").click()
download = download_info.value download = download_info.value
# Wait for the download process to complete # Wait for the download process to complete
path = download.path() path = download.path()
@ -64,7 +64,7 @@ path = download.path()
// Start the task of waiting for the download // Start the task of waiting for the download
var waitForDownloadTask = page.WaitForDownloadAsync(); var waitForDownloadTask = page.WaitForDownloadAsync();
// Perform the action that initiates download // Perform the action that initiates download
await page.ClickAsync("#downloadButton"); await page.Locator("#downloadButton").ClickAsync();
// Wait for the download process to complete // Wait for the download process to complete
var download = await waitForDownloadTask; var download = await waitForDownloadTask;
var path = await download.PathAsync(); var path = await download.PathAsync();

View file

@ -11,94 +11,94 @@ This is the easiest way to fill out the form fields. It focuses the element and
```js ```js
// Text input // Text input
await page.fill('#name', 'Peter'); await page.locator('#name').fill('Peter');
// Date input // Date input
await page.fill('#date', '2020-02-02'); await page.locator('#date').fill('2020-02-02');
// Time input // Time input
await page.fill('#time', '13:15'); await page.locator('#time').fill('13:15');
// Local datetime input // Local datetime input
await page.fill('#local', '2020-03-02T05:15'); await page.locator('#local').fill('2020-03-02T05:15');
// Input through label // Input through label
await page.fill('text=First Name', 'Peter'); await page.locator('text=First Name').fill('Peter');
``` ```
```java ```java
// Text input // Text input
page.fill("#name", "Peter"); page.locator("#name").fill("Peter");
// Date input // Date input
page.fill("#date", "2020-02-02"); page.locator("#date").fill("2020-02-02");
// Time input // Time input
page.fill("#time", "13-15"); page.locator("#time").fill("13-15");
// Local datetime input // Local datetime input
page.fill("#local", "2020-03-02T05:15"); page.locator("#local").fill("2020-03-02T05:15");
// Input through label // Input through label
page.fill("text=First Name", "Peter"); page.locator("text=First Name").fill("Peter");
``` ```
```python async ```python async
# Text input # Text input
await page.fill('#name', 'Peter') await page.locator('#name').fill('Peter')
# Date input # Date input
await page.fill('#date', '2020-02-02') await page.locator('#date').fill('2020-02-02')
# Time input # Time input
await page.fill('#time', '13:15') await page.locator('#time').fill('13:15')
# Local datetime input # Local datetime input
await page.fill('#local', '2020-03-02T05:15') await page.locator('#local').fill('2020-03-02T05:15')
# Input through label # Input through label
await page.fill('text=First Name', 'Peter') await page.locator('text=First Name').fill('Peter')
``` ```
```python sync ```python sync
# Text input # Text input
page.fill('#name', 'Peter') page.locator('#name').fill('Peter')
# Date input # Date input
page.fill('#date', '2020-02-02') page.locator('#date').fill('2020-02-02')
# Time input # Time input
page.fill('#time', '13:15') page.locator('#time').fill('13:15')
# Local datetime input # Local datetime input
page.fill('#local', '2020-03-02T05:15') page.locator('#local').fill('2020-03-02T05:15')
# Input through label # Input through label
page.fill('text=First Name', 'Peter') page.locator('text=First Name').fill('Peter')
``` ```
```csharp ```csharp
// Text input // Text input
await page.FillAsync("#name", "Peter"); await page.Locator("#name").FillAsync("Peter");
// Date input // Date input
await page.FillAsync("#date", "2020-02-02"); await page.Locator("#date").FillAsync("2020-02-02");
// Time input // Time input
await page.FillAsync("#time", "13-15"); await page.Locator("#time").FillAsync("13-15");
// Local datetime input // Local datetime input
await page.FillAsync("#local", "2020-03-02T05:15"); await page.Locator("#local").FillAsync("2020-03-02T05:15");
// Input through label // Input through label
await page.FillAsync("text=First Name", "Peter"); await page.Locator("text=First Name").FillAsync("Peter");
``` ```
### API reference ### API reference
- [`method: Locator.fill`]
- [`method: Page.fill`] - [`method: Page.fill`]
- [`method: Frame.fill`] - [`method: Frame.fill`]
- [`method: ElementHandle.fill`]
<br/> <br/>
@ -108,170 +108,150 @@ This is the easiest way to check and uncheck a checkbox or a radio button. This
```js ```js
// Check the checkbox // Check the checkbox
await page.check('#agree'); await page.locator('#agree').check();
// Assert the checked state // Assert the checked state
expect(await page.isChecked('#agree')).toBeTruthy() expect(await page.locator('#agree').isChecked()).toBeTruthy()
// Uncheck by input <label>. // Uncheck by input <label>.
await page.uncheck('#subscribe-label'); await page.locator('#subscribe-label').uncheck();
// Select the radio button // Select the radio button
await page.check('text=XL'); await page.locator('text=XL').check();
``` ```
```java ```java
// Check the checkbox // Check the checkbox
page.check("#agree"); page.locator("#agree").check();
// Assert the checked state // Assert the checked state
assertTrue(page.isChecked("#agree")); assertTrue(page.locator("#agree").isChecked());
// Uncheck by input <label>. // Uncheck by input <label>.
page.uncheck("#subscribe-label"); page.locator("#subscribe-label").uncheck();
// Select the radio button // Select the radio button
page.check("text=XL"); page.locator("text=XL").check();
``` ```
```python async ```python async
# Check the checkbox # Check the checkbox
await page.check('#agree') await page.locator('#agree').check()
# Assert the checked state # Assert the checked state
assert await page.is_checked('#agree') is True assert await page.locator('#agree').is_checked() is True
# Uncheck by input <label>. # Uncheck by input <label>.
await page.uncheck('#subscribe-label') await page.locator('#subscribe-label').uncheck()
# Select the radio button # Select the radio button
await page.check('text=XL') await page.locator('text=XL').check()
``` ```
```python sync ```python sync
# Check the checkbox # Check the checkbox
page.check('#agree') page.locator('#agree').check()
# Assert the checked state # Assert the checked state
assert page.is_checked('#agree') is True assert page.locator('#agree').is_checked() is True
# Uncheck by input <label>. # Uncheck by input <label>.
page.uncheck('#subscribe-label') page.locator('#subscribe-label').uncheck()
# Select the radio button # Select the radio button
page.check('text=XL') page.locator('text=XL').check()
``` ```
```csharp ```csharp
// Check the checkbox // Check the checkbox
await page.CheckAsync("#agree"); await page.Locator("#agree").CheckAsync();
// Assert the checked state // Assert the checked state
Assert.True(await page.IsCheckedAsync("#agree")); Assert.True(await page.Locator("#agree").IsCheckedAsync());
// Uncheck by input <label>. // Uncheck by input <label>.
await page.UncheckAsync("#subscribe-label"); await page.Locator("#subscribe-label").UncheckAsync();
// Select the radio button // Select the radio button
await page.CheckAsync("text=XL"); await page.Locator("text=XL").CheckAsync();
``` ```
### API reference ### API reference
- [`method: Page.check`]
- [`method: Page.isChecked`]
- [`method: Page.uncheck`]
- [`method: Locator.check`] - [`method: Locator.check`]
- [`method: Locator.isChecked`] - [`method: Locator.isChecked`]
- [`method: Locator.uncheck`] - [`method: Locator.uncheck`]
- [`method: Page.check`]
- [`method: Page.isChecked`]
- [`method: Page.uncheck`]
<br/> <br/>
## Select options ## Select options
Selects one or multiple options in the `<select>` element. Selects one or multiple options in the `<select>` element.
You can specify option `value`, `label` or `elementHandle` to select. Multiple options can be selected. You can specify option `value`, or `label` to select. Multiple options can be selected.
```js ```js
// Single selection matching the value // Single selection matching the value
await page.selectOption('select#colors', 'blue'); await page.locator('select#colors').selectOption('blue');
// Single selection matching the label // Single selection matching the label
await page.selectOption('select#colors', { label: 'Blue' }); await page.locator('select#colors').selectOption({ label: 'Blue' });
// Multiple selected items // Multiple selected items
await page.selectOption('select#colors', ['red', 'green', 'blue']); await page.locator('select#colors').selectOption(['red', 'green', 'blue']);
// Select the option via element handle
const option = await page.$('#best-option');
await page.selectOption('select#colors', option);
``` ```
```java ```java
// Single selection matching the value // Single selection matching the value
page.selectOption("select#colors", "blue"); page.locator("select#colors").selectOption("blue");
// Single selection matching the label // Single selection matching the label
page.selectOption("select#colors", new SelectOption().setLabel("Blue")); page.locator("select#colors").selectOption(new SelectOption().setLabel("Blue"));
// Multiple selected items // Multiple selected items
page.selectOption("select#colors", new String[] {"red", "green", "blue"}); page.locator("select#colors").selectOption(new String[] {"red", "green", "blue"});
// Select the option via element handle
ElementHandle option = page.querySelector("#best-option");
page.selectOption("select#colors", option);
``` ```
```python async ```python async
# Single selection matching the value # Single selection matching the value
await page.select_option('select#colors', 'blue') await page.locator('select#colors').select_option('blue')
# Single selection matching the label # Single selection matching the label
await page.select_option('select#colors', label='Blue') await page.locator('select#colors').select_option(label='Blue')
# Multiple selected items # Multiple selected items
await page.select_option('select#colors', ['red', 'green', 'blue']) await page.locator('select#colors').select_option(['red', 'green', 'blue'])
# Select the option via element handle
option = await page.query_selector('#best-option')
await page.select_option('select#colors', option)
``` ```
```python sync ```python sync
# Single selection matching the value # Single selection matching the value
page.select_option('select#colors', 'blue') page.locator('select#colors').select_option('blue')
# Single selection matching the label # Single selection matching the label
page.select_option('select#colors', label='Blue') page.locator('select#colors').select_option(label='Blue')
# Multiple selected items # Multiple selected items
page.select_option('select#colors', ['red', 'green', 'blue']) page.locator('select#colors').select_option(['red', 'green', 'blue'])
# Select the option via element handle
option = page.query_selector('#best-option')
page.select_option('select#colors', option)
``` ```
```csharp ```csharp
// Single selection matching the value // Single selection matching the value
await page.SelectOptionAsync("select#colors", "blue"); await page.Locator("select#colors").SelectOptionAsync("blue");
// Single selection matching the label // Single selection matching the label
await page.SelectOptionAsync("select#colors", new SelectOptionValue { Label = "blue" })); await page.Locator("select#colors").SelectOptionAsync(new SelectOptionValue { Label = "blue" }));
// Multiple selected items // Multiple selected items
await page.SelectOptionAsync("select#colors", new[] { "blue", "green", "red" }); await page.Locator("select#colors").SelectOptionAsync(new[] { "blue", "green", "red" });
// Select the option via element handle
var option = await page.QuerySelectorAsync("#best-option");
await page.SelectOptionAsync("select#colors", option);
``` ```
### API reference ### API reference
- [`method: Locator.selectOption`]
- [`method: Page.selectOption`] - [`method: Page.selectOption`]
- [`method: Frame.selectOption`] - [`method: Frame.selectOption`]
- [`method: ElementHandle.selectOption`]
<br/> <br/>
@ -281,102 +261,102 @@ Performs a simple human click.
```js ```js
// Generic click // Generic click
await page.click('button#submit'); await page.locator('button#submit').click();
// Double click // Double click
await page.dblclick('#item'); await page.locator('#item').dblclick();
// Right click // Right click
await page.click('#item', { button: 'right' }); await page.locator('#item').click({ button: 'right' });
// Shift + click // Shift + click
await page.click('#item', { modifiers: ['Shift'] }); await page.locator('#item').click({ modifiers: ['Shift'] });
// Hover over element // Hover over element
await page.hover('#item'); await page.locator('#item').hover();
// Click the top left corner // Click the top left corner
await page.click('#item', { position: { x: 0, y: 0} }); await page.locator('#item').click({ position: { x: 0, y: 0} });
``` ```
```java ```java
// Generic click // Generic click
page.click("button#submit"); page.locator("button#submit").click();
// Double click // Double click
page.dblclick("#item"); page.locator("#item").dblclick();
// Right click // Right click
page.click("#item", new Page.ClickOptions().setButton(MouseButton.RIGHT)); page.locator("#item").click(new Locator.ClickOptions().setButton(MouseButton.RIGHT));
// Shift + click // Shift + click
page.click("#item", new Page.ClickOptions().setModifiers(Arrays.asList(KeyboardModifier.SHIFT))); page.locator("#item").click(new Locator.ClickOptions().setModifiers(Arrays.asList(KeyboardModifier.SHIFT)));
// Hover over element // Hover over element
page.hover("#item"); page.locator("#item").hover();
// Click the top left corner // Click the top left corner
page.click("#item", new Page.ClickOptions().setPosition(0, 0)); page.locator("#item").click(new Locator.ClickOptions().setPosition(0, 0));
``` ```
```python async ```python async
# Generic click # Generic click
await page.click('button#submit') await page.locator('button#submit').click()
# Double click # Double click
await page.dblclick('#item') await page.locator('#item').dblclick()
# Right click # Right click
await page.click('#item', button='right') await page.locator('#item').click(button='right')
# Shift + click # Shift + click
await page.click('#item', modifiers=['Shift']) await page.locator('#item').click(modifiers=['Shift'])
# Hover over element # Hover over element
await page.hover('#item') await page.locator('#item').hover()
# Click the top left corner # Click the top left corner
await page.click('#item', position={ 'x': 0, 'y': 0}) await page.locator('#item').click(position={ 'x': 0, 'y': 0})
``` ```
```python sync ```python sync
# Generic click # Generic click
page.click('button#submit') page.locator('button#submit').click()
# Double click # Double click
page.dblclick('#item') page.locator('#item').dblclick()
# Right click # Right click
page.click('#item', button='right') page.locator('#item').click(button='right')
# Shift + click # Shift + click
page.click('#item', modifiers=['Shift']) page.locator('#item').click(modifiers=['Shift'])
# Hover over element # Hover over element
page.hover('#item') page.locator('#item').hover()
# Click the top left corner # Click the top left corner
page.click('#item', position={ 'x': 0, 'y': 0}) page.locator('#item').click(position={ 'x': 0, 'y': 0})
``` ```
```csharp ```csharp
// Generic click // Generic click
await page.ClickAsync("button#submit"); await page.Locator("button#submit").ClickAsync();
// Double click // Double click
await page.DblClickAsync("#item"); await page.Locator("#item").DblClickAsync();
// Right click // Right click
await page.ClickAsync("#item", new PageClickOptions { Button = MouseButton.Right }); await page.Locator("#item").ClickAsync(new() { Button = MouseButton.Right });
// Shift + click // Shift + click
await page.ClickAsync("#item", new PageClickOptions { Modifiers = new[] { KeyboardModifier.Shift } }); await page.Locator("#item").ClickAsync(new() { Modifiers = new[] { KeyboardModifier.Shift } });
// Hover over element // Hover over element
await page.HoverAsync("#item"); await page.Locator("#item").HoverAsync();
// Click the top left corner // Click the top left corner
await page.ClickAsync("#item", new PageClickOptions { position = new Position { X = 0, Y = 0 } }); await page.Locator("#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:
@ -393,23 +373,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.click('button#submit', { force: true }); await page.locator('button#submit').click({ force: true });
``` ```
```java ```java
page.click("button#submit", new Page.ClickOptions().setForce(true)); page.locator("button#submit").click(new Locator.ClickOptions().setForce(true));
``` ```
```python async ```python async
await page.click('button#submit', force=True) await page.locator('button#submit').click(force=True)
``` ```
```python sync ```python sync
page.click('button#submit', force=True) page.locator('button#submit').click(force=True)
``` ```
```csharp ```csharp
await page.ClickAsync("button#submit", new PageClickOptions { Force = true }); await page.Locator("button#submit").ClickAsync(new() { Force = true });
``` ```
#### Programmatic click #### Programmatic click
@ -417,39 +397,39 @@ await page.ClickAsync("button#submit", new PageClickOptions { 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: 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:
```js ```js
await page.dispatchEvent('button#submit', 'click'); await page.locator('button#submit').dispatchEvent('click');
``` ```
```java ```java
page.dispatchEvent("button#submit", "click"); page.locator("button#submit").dispatchEvent("click");
``` ```
```python async ```python async
await page.dispatch_event('button#submit', 'click') await page.locator('button#submit').dispatch_event('click')
``` ```
```python sync ```python sync
page.dispatch_event('button#submit', 'click') page.locator('button#submit').dispatch_event('click')
``` ```
```csharp ```csharp
await page.DispatchEventAsync("button#submit", "click"); await page.Locator("button#submit").DispatchEventAsync("click");
``` ```
### API reference ### API reference
- [`method: Locator.click`]
- [`method: Page.click`] - [`method: Page.click`]
- [`method: Frame.click`] - [`method: Frame.click`]
- [`method: ElementHandle.click`] - [`method: Locator.dblclick`]
- [`method: Page.dblclick`] - [`method: Page.dblclick`]
- [`method: Frame.dblclick`] - [`method: Frame.dblclick`]
- [`method: ElementHandle.dblclick`] - [`method: Locator.hover`]
- [`method: Page.hover`] - [`method: Page.hover`]
- [`method: Frame.hover`] - [`method: Frame.hover`]
- [`method: ElementHandle.hover`] - [`method: Locator.dispatchEvent`]
- [`method: Page.dispatchEvent`] - [`method: Page.dispatchEvent`]
- [`method: Frame.dispatchEvent`] - [`method: Frame.dispatchEvent`]
- [`method: ElementHandle.dispatchEvent`]
<br/> <br/>
@ -459,27 +439,27 @@ Type into the field character by character, as if it was a user with a real keyb
```js ```js
// Type character by character // Type character by character
await page.type('#area', 'Hello World!'); await page.locator('#area').type('Hello World!');
``` ```
```java ```java
// Type character by character // Type character by character
page.type("#area", "Hello World!"); page.locator("#area").type("Hello World!");
``` ```
```python async ```python async
# Type character by character # Type character by character
await page.type('#area', 'Hello World!') await page.locator('#area').type('Hello World!')
``` ```
```python sync ```python sync
# Type character by character # Type character by character
page.type('#area', 'Hello World!') page.locator('#area').type('Hello World!')
``` ```
```csharp ```csharp
// Type character by character // Type character by character
await page.TypeAsync("#area", "Hello World!"); await page.Locator("#area").TypeAsync("Hello World!");
``` ```
This method will emit all the necessary keyboard events, with all the `keydown`, `keyup`, `keypress` events in place. You can even specify the optional `delay` between the key presses to simulate real user behavior. This method will emit all the necessary keyboard events, with all the `keydown`, `keyup`, `keypress` events in place. You can even specify the optional `delay` between the key presses to simulate real user behavior.
@ -490,9 +470,9 @@ Most of the time, [`method: Page.fill`] will just work. You only need to type ch
### API reference ### API reference
- [`method: Locator.type`]
- [`method: Page.type`] - [`method: Page.type`]
- [`method: Frame.type`] - [`method: Frame.type`]
- [`method: ElementHandle.type`]
- [`method: Keyboard.type`] - [`method: Keyboard.type`]
<br/> <br/>
@ -501,57 +481,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.press('#submit', 'Enter'); await page.locator('#submit').press('Enter');
// Dispatch Control+Right // Dispatch Control+Right
await page.press('#name', 'Control+ArrowRight'); await page.locator('#name').press('Control+ArrowRight');
// Press $ sign on keyboard // Press $ sign on keyboard
await page.press('#value', '$'); await page.locator('#value').press('$');
``` ```
```java ```java
// Hit Enter // Hit Enter
page.press("#submit", "Enter"); page.locator("#submit").press("Enter");
// Dispatch Control+Right // Dispatch Control+Right
page.press("#name", "Control+ArrowRight"); page.locator("#name").press("Control+ArrowRight");
// Press $ sign on keyboard // Press $ sign on keyboard
page.press("#value", "$"); page.locator("#value").press("$");
``` ```
```python async ```python async
# Hit Enter # Hit Enter
await page.press('#submit', 'Enter') await page.locator('#submit').press('Enter')
# Dispatch Control+Right # Dispatch Control+Right
await page.press('#name', 'Control+ArrowRight') await page.locator('#name').press('Control+ArrowRight')
# Press $ sign on keyboard # Press $ sign on keyboard
await page.press('#value', '$') await page.locator('#value').press('$')
``` ```
```python sync ```python sync
# Hit Enter # Hit Enter
page.press('#submit', 'Enter') page.locator('#submit').press('Enter')
# Dispatch Control+Right # Dispatch Control+Right
page.press('#name', 'Control+ArrowRight') page.locator('#name').press('Control+ArrowRight')
# Press $ sign on keyboard # Press $ sign on keyboard
page.press('#value', '$') page.locator('#value').press('$')
``` ```
```csharp ```csharp
// Hit Enter // Hit Enter
await page.PressAsync("#submit", "Enter"); await page.Locator("#submit").PressAsync("Enter");
// Dispatch Control+Right // Dispatch Control+Right
await page.PressAsync("#name", "Control+ArrowRight"); await page.Locator("#name").PressAsync("Control+ArrowRight");
// Press $ sign on keyboard // Press $ sign on keyboard
await page.PressAsync("#value", "$"); await page.Locator("#value").PressAsync("$");
``` ```
This 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: This 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:
@ -571,42 +551,42 @@ Simple version produces a single character. This character is case-sensitive, so
```js ```js
// <input id=name> // <input id=name>
await page.press('#name', 'Shift+A'); await page.locator('#name').press('Shift+A');
// <input id=name> // <input id=name>
await page.press('#name', 'Shift+ArrowLeft'); await page.locator('#name').press('Shift+ArrowLeft');
``` ```
```java ```java
// <input id=name> // <input id=name>
page.press("#name", "Shift+A"); page.locator("#name").press("Shift+A");
// <input id=name> // <input id=name>
page.press("#name", "Shift+ArrowLeft"); page.locator("#name").press("Shift+ArrowLeft");
``` ```
```python async ```python async
# <input id=name> # <input id=name>
await page.press('#name', 'Shift+A') await page.locator('#name').press('Shift+A')
# <input id=name> # <input id=name>
await page.press('#name', 'Shift+ArrowLeft') await page.locator('#name').press('Shift+ArrowLeft')
``` ```
```python sync ```python sync
# <input id=name> # <input id=name>
page.press('#name', 'Shift+A') page.locator('#name').press('Shift+A')
# <input id=name> # <input id=name>
page.press('#name', 'Shift+ArrowLeft') page.locator('#name').press('Shift+ArrowLeft')
``` ```
```csharp ```csharp
// <input id=name> // <input id=name>
await page.PressAsync("#name", "Shift+A"); await page.Locator("#name").PressAsync("Shift+A");
// <input id=name> // <input id=name>
await page.PressAsync("#name", "Shift+ArrowLeft"); await page.Locator("#name").PressAsync("Shift+ArrowLeft");
``` ```
Shortcuts such as `"Control+o"` or `"Control+Shift+T"` are supported as well. When specified with the modifier, modifier is pressed and being held while the subsequent key is being pressed. Shortcuts such as `"Control+o"` or `"Control+Shift+T"` are supported as well. When specified with the modifier, modifier is pressed and being held while the subsequent key is being pressed.
@ -616,9 +596,9 @@ Note that you still need to specify the capital `A` in `Shift-A` to produce the
### API reference ### API reference
- [`method: Locator.press`]
- [`method: Page.press`] - [`method: Page.press`]
- [`method: Frame.press`] - [`method: Frame.press`]
- [`method: ElementHandle.press`]
- [`method: Keyboard.press`] - [`method: Keyboard.press`]
<br/> <br/>
@ -629,16 +609,16 @@ You can select input files for upload using the [`method: Page.setInputFiles`] m
```js ```js
// Select one file // Select one file
await page.setInputFiles('input#upload', 'myfile.pdf'); await page.locator('input#upload').setInputFiles('myfile.pdf');
// Select multiple files // Select multiple files
await page.setInputFiles('input#upload', ['file1.txt', 'file2.txt']); await page.locator('input#upload').setInputFiles(['file1.txt', 'file2.txt']);
// Remove all the selected files // Remove all the selected files
await page.setInputFiles('input#upload', []); await page.locator('input#upload').setInputFiles([]);
// Upload buffer from memory // Upload buffer from memory
await page.setInputFiles('input#upload', { await page.locator('input#upload').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')
@ -647,32 +627,31 @@ await page.setInputFiles('input#upload', {
```java ```java
// Select one file // Select one file
page.setInputFiles("input#upload", Paths.get("myfile.pdf")); page.locator("input#upload").setInputFiles(Paths.get("myfile.pdf"));
// Select multiple files // Select multiple files
page.setInputFiles("input#upload", new Path[] {Paths.get("file1.txt"), Paths.get("file2.txt")}); page.locator("input#upload").setInputFiles(new Path[] {Paths.get("file1.txt"), Paths.get("file2.txt")});
// Remove all the selected files // Remove all the selected files
page.setInputFiles("input#upload", new Path[0]); page.locator("input#upload").setInputFiles(new Path[0]);
// Upload buffer from memory // Upload buffer from memory
page.setInputFiles("input#upload", new FilePayload( page.locator("input#upload").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.set_input_files('input#upload', 'myfile.pdf') await page.locator('input#upload').set_input_files('myfile.pdf')
# Select multiple files # Select multiple files
await page.set_input_files('input#upload', ['file1.txt', 'file2.txt']) await page.locator('input#upload').set_input_files(['file1.txt', 'file2.txt'])
# Remove all the selected files # Remove all the selected files
await page.set_input_files('input#upload', []) await page.locator('input#upload').set_input_files([])
# Upload buffer from memory # Upload buffer from memory
await page.set_input_files( await page.locator("input#upload").set_input_files(
"input#upload",
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"}
], ],
@ -681,17 +660,16 @@ await page.set_input_files(
```python sync ```python sync
# Select one file # Select one file
page.set_input_files('input#upload', 'myfile.pdf') page.locator('input#upload').set_input_files('myfile.pdf')
# Select multiple files # Select multiple files
page.set_input_files('input#upload', ['file1.txt', 'file2.txt']) page.locator('input#upload').set_input_files(['file1.txt', 'file2.txt'])
# Remove all the selected files # Remove all the selected files
page.set_input_files('input#upload', []) page.locator('input#upload').set_input_files([])
# Upload buffer from memory # Upload buffer from memory
page.set_input_files( page.locator("input#upload").set_input_files(
"input#upload",
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"}
], ],
@ -700,16 +678,16 @@ page.set_input_files(
```csharp ```csharp
// Select one file // Select one file
await page.SetInputFilesAsync("input#upload", "myfile.pdf"); await page.Locator("input#upload").SetInputFilesAsync("myfile.pdf");
// Select multiple files // Select multiple files
await page.SetInputFilesAsync("input#upload", new[] { "file1.txt", "file12.txt" }); await page.Locator("input#upload").SetInputFilesAsync(new[] { "file1.txt", "file12.txt" });
// Remove all the selected files // Remove all the selected files
await page.SetInputFilesAsync("input#upload", new[] {}); await page.Locator("input#upload").SetInputFilesAsync(new[] {});
// Upload buffer from memory // Upload buffer from memory
await page.SetInputFilesAsync("input#upload", new FilePayload await page.Locator("input#upload").SetInputFilesAsync(new FilePayload
{ {
Name = "file.txt", Name = "file.txt",
MimeType = "text/plain", MimeType = "text/plain",
@ -733,21 +711,21 @@ await fileChooser.setFiles('myfile.pdf');
```java ```java
FileChooser fileChooser = page.waitForFileChooser(() -> { FileChooser fileChooser = page.waitForFileChooser(() -> {
page.click("upload"); page.locator("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.click("upload") await page.locator("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.click("upload") page.locator("upload").click()
file_chooser = fc_info.value file_chooser = fc_info.value
file_chooser.set_files("myfile.pdf") file_chooser.set_files("myfile.pdf")
``` ```
@ -755,16 +733,16 @@ file_chooser.set_files("myfile.pdf")
```csharp ```csharp
var fileChooser = page.RunAndWaitForFileChooserAsync(async () => var fileChooser = page.RunAndWaitForFileChooserAsync(async () =>
{ {
await page.ClickAsync("upload"); await page.Locator("upload").ClickAsync();
}); });
await fileChooser.SetFilesAsync("myfile.pdf"); await fileChooser.SetFilesAsync("myfile.pdf");
``` ```
### API reference ### API reference
- [FileChooser] - [FileChooser]
- [`method: Locator.setInputFiles`]
- [`method: Page.setInputFiles`] - [`method: Page.setInputFiles`]
- [`method: Frame.setInputFiles`] - [`method: Frame.setInputFiles`]
- [`method: ElementHandle.setInputFiles`]
<br/> <br/>
@ -773,28 +751,28 @@ await fileChooser.SetFilesAsync("myfile.pdf");
For the dynamic pages that handle focus events, you can focus the given element. For the dynamic pages that handle focus events, you can focus the given element.
```js ```js
await page.focus('input#name'); await page.locator('input#name').focus();
``` ```
```java ```java
page.focus("input#name"); page.locator("input#name").focus();
``` ```
```python async ```python async
await page.focus('input#name') await page.locator('input#name').focus()
``` ```
```python sync ```python sync
page.focus('input#name') page.locator('input#name').focus()
``` ```
```csharp ```csharp
await page.FocusAsync("input#name"); await page.Locator("input#name").FocusAsync();
``` ```
### API reference ### API reference
- [`method: Locator.focus`]
- [`method: Page.focus`] - [`method: Page.focus`]
- [`method: Frame.focus`] - [`method: Frame.focus`]
- [`method: ElementHandle.focus`]
<br/> <br/>