Playwright Actions
This chapter introduces navigation and click-related actions in Playwright, as well as the automatic waiting mechanism behind these actions.
* * *
## What is Action
Action is a method in Playwright used to simulate user behavior, such as clicking buttons, entering text, or selecting dropdowns.
Before executing each Action, Playwright automatically waits for the target element to become actionable.
* * *
## Actionability Checks
Before executing each action, Playwright performs a series of checks on the target element:
| Step | Check Condition | Description |
| --- | --- | --- |
| 1. Attached | Element is attached to the DOM tree | Element exists in the page |
| 2. Visible | Element is visible (not `display:none` or `visibility:hidden`) | User can see the element |
| 3. Stable | Element position is stable (animation finished) | Avoid misoperations during animation |
| 4. Receives Events | Element is not covered by other elements | Ensure clicks can be received by the element |
| 5. Enabled | Element is not disabled (not `disabled`) | User can interact with it |
If any step fails, Playwright will wait and retry until timeout.
> These 5 checks are automatically done by Playwright, and you don't need to write any extra waiting code. This is also the fundamental reason why Playwright can significantly reduce flaky tests.
* * *
## Forced Actions { force: true }
Sometimes you need to bypass actionability checks, such as clicking a button hidden by a mask or testing the state of invisible elements.
## Example
// Force click, skip all actionability checks
await page.getByRole('button',{ name:'submit'}).click({ force:true});
> `force: true` is for testing operations that real users cannot do, and should not be used in most cases. If your test requires `force: true`, first check if there are interaction design issues.
* * *
## Navigation Actions
### page.goto() Page Navigation
## Example
// Basic navigation
await page.goto('https://example.com/');
// Wait for DOMContentLoaded (page structure loaded)
await page.goto('https://example.com/',{ waitUntil:'domcontentloaded'});
// Wait for network idle (all async data loaded)
await page.goto('https://example.com/',{
waitUntil:'networkidle',// Network idle
timeout:60000,// Timeout 60 seconds
referer:'https://google.com',// Referer source
});
### page.goBack() / goForward() / reload()
## Example
// Go back one page
await page.goBack();
// Go forward one page
await page.goForward();
// Refresh page
await page.reload();
* * *
## Click Actions
### locator.click() Single Click
## Example
// Basic click
await page.getByRole('button',{ name:'Login'}).click();
// Click with options
await page.getByRole('button',{ name:'Login'}).click({
button:'left',// Mouse button: 'left' | 'right' | 'middle'
clickCount:1,// Click count
delay:100,// Delay between press and release (milliseconds)
timeout:5000,// Timeout
modifiers:[],// Modifier keys: ['Alt', 'Control', 'Meta', 'Shift']
});
### locator.dblclick() Double Click
## Example
// Double click element
await page.getByText('Double-click to edit').dblclick();
### Right Click
## Example
// Right click (open context menu)
await page.getByText('Right-click menu').click({ button:'right'});
### Modifier Key Click
## Example
// Ctrl + click (multi-select)
await page.getByRole('option').click({ modifiers:['Control']});
// Shift + click (range select / open in new window)
await page.getByRole('link').click({ modifiers:['Shift']});
### Coordinate Click
## Example
// Click specific position on element (relative to element's top-left corner)
await page.locator('canvas').click({
position:{ x:100, y:50},
});
### locator.hover() Hover
## Example
// Mouse hover (trigger hover effect or dropdown menu)
await page.getByRole('link',{ name:'Tutorial'}).hover();
// Click the popup submenu after hovering
await page.getByRole('link',{ name:'Playwright Tutorial'}).click();
* * *
## Click vs Hover Scenario Differences
| Action | Applicable Scenario |
| --- | --- |
| `click()` | Button click, link navigation, checkbox toggle |
| `dblclick()` | Enter edit mode, double-click to select text |
| `click({ button: 'right' })` | Open browser native context menu |
| `hover()` | Trigger hover menu, Tooltip |
| `click({ position })` | Canvas operations, custom graphic interaction |
* * *
## Text Input Actions
### locator.fill() Clear and Fill
`fill()` will first clear the input field, then fill in the new value. It is the most commonly used and recommended method for input operations.
## Example
// Clear input field and fill new value
await page.getByLabel('Username').fill('tutorial_user');
await page.getByLabel('Password').fill('secure_password');
await page.getByPlaceholder('SearchTUTORIALTutorial').fill('Playwright');
### locator.type() Type Character by Character
`type()` inputs character by character, simulating real keyboard typing, with configurable interval between each key press.
## Example
// Type character by character (100ms delay between each character)
await page.getByLabel('Search').type('Playwright',{ delay:100});
### Difference between fill vs type
| Method | Behavior | Applicable Scenario |
| --- | --- | --- |
| `fill()` | Clear and fill at once | Most scenarios (recommended) |
| `type()` | Input character by character, trigger each key event | Need to trigger input suggestions, real-time search |
> In most cases, you can just use `fill()`. Only when the input field has real-time search (keydown/keyup events) do you need to use `type()`.
### locator.clear() Clear
## Example
// Clear input field content
await page.getByLabel('Username').clear();
* * *
## Selection Actions
### locator.check() / uncheck() Checkbox
## Example
// Check checkbox
await page.getByLabel('I agree to the service agreement').check();
// Uncheck checkbox
await page.getByLabel('Receive email notifications').uncheck();
// Set checkbox state
await page.getByLabel('Remember me').setChecked(true);// Checked
await page.getByLabel('
YouTip