Playwright Actions
This chapter introduces Playwright operations related to navigation and clicking, as well as the automatic waiting mechanism behind these operations.
What is an Action
An Action is a method in Playwright used tosimulate user behaviorsuch as clicking buttons, entering text, and selecting dropdowns.
Before each Action executes, Playwright automatically waits for the target element to becomeactionable state。
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 (notdisplay:noneorvisibility:hidden) | user can see the element |
| 3. Stable | Element is stable (animations finished) | Avoid mistaken actions during animations |
| 4. Receives Events | Element is not obscured by other elements | Ensure the click can be received by the element |
| 5. Enabled | Element is not disabled (notdisabled) | user can interact with it |
If any check fails, Playwright will wait and retry until the timeout is reached.
These 5 checks are performed automatically by Playwright, so you don't need to write any extra waiting code. This is also the fundamental reason why Playwright can greatly reduce flaky tests.
Forced Actions { force: true }
Sometimes you need to bypass actionability checks, for example, clicking a button hidden by an overlay or testing the state of an invisible element.
Example
await page.getByRole('button', { name: 'Submit' }).click({ force: true });
force: trueis an operation beyond what real users can do, and should not be used in the vast majority of cases. If your test requiresforce: true, first check whether there is an interaction design issue.
Navigation Actions
page.goto() Page Navigation
Example
await page.goto('https://www.example.com/');
// Wait for DOMContentLoaded (page structure loaded)
await page.goto('https://www.example.com/', { waitUntil: 'domcontentloaded' });
// Wait for network idle (all async data loaded)
await page.goto('https://www.example.com/', {
waitUntil: 'networkidle', // Network idle
timeout: 60000, // Timeout 60 seconds
referer: 'https://google.com', // Referer source
});
page.goBack() / goForward() / reload()
Example
await page.goBack();
// Go forward one page
await page.goForward();
// Refresh page
await page.reload();
Click Actions
locator.click() Single Click
Example
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
await page.getByText('Double-click to edit').dblclick();
Right-click
Example
await page.getByText('Right-click menu').click({ button: 'right' });
Modifier Key Click
Example
await page.getByRole('option').click({ modifiers: ['Control'] });
// Shift + click (range selection / open in new window)
await page.getByRole('link').click({ modifiers: ['Shift'] });
Coordinate Click
Example
await page.locator('canvas').click({
position: { x: 100, y: 50 },
});
locator.hover() Hover
Example
await page.getByRole('link', { name: 'Tutorial' }).hover();
// After hovering, click the popup submenu
await page.getByRole('link', { name: 'Playwright Tutorial' }).click();
Click vs Hover Usage Scenarios
| Operation | Applicable Scenario |
|---|---|
click() | Button clicks, link navigation, checkbox toggling |
dblclick() | Entering edit mode, double-click to select text |
click({ button: 'right' }) | Opening the browser's native context menu |
hover() | Triggering hover menus, Tooltip hints |
click({ position }) | Canvas operations, custom graphic interactions |
Text Input Actions
locator.fill() Clear and Fill
fill()It first clears the input field and then fills in the new value. It is the most commonly used and recommended method for input operations.
Example
await page.getByLabel('Username').fill('example_user');
await page.getByLabel('Password').fill('secure_password');
await page.getByPlaceholder('Search EXAMPLE tutorials').fill('Playwright');
locator.type() Character-by-Character Input
type()It types characters one by one, simulating real keystrokes, and you can set an interval between each key press.
Example
await page.getByLabel('Search').type('Playwright', { delay: 100 });
Difference Between fill and type
| Method | Behavior | Applicable Scenario |
|---|---|---|
fill() | Clear and fill in one go | Most scenarios (recommended) |
type() | Character-by-character input, triggering each key press event | When needing to trigger input suggestions, real-time search |
In most cases, use
fill()That's it. Only when the input field has real-time search (keydown/keyup events) is it necessary to usetype()。
locator.clear() Clear
Example
await page.getByLabel('Username').clear();
Selection Actions
locator.check() / uncheck() Checkbox
Example
await page.getByLabel('I agree to the service agreement').check();
// Uncheck
await page.getByLabel('Receive email notifications').uncheck();
// Set the checked state
await page.getByLabel('Remember me').setChecked(true); // Verify it is checked
await page.getByLabel('Remember me').setChecked(false); // Verify it is unchecked
locator.selectOption() Dropdown Selection
Example
await page.getByLabel('City').selectOption('beijing');
// Select by visible text
await page.getByLabel('City').selectOption({ label: 'Shanghai' });
// Multi-select dropdown
await page.getByLabel('Interest tags').selectOption([
{ label: 'Programming' },
{ value: 'design' },
]);
// Select by index (item 0, item 2)
await page.getByLabel('City').selectOption({ index: 0 });
Keyboard Actions
page.keyboard.press() Press Key
Example
await page.keyboard.press('Enter');
// Select all (Control + A)
await page.keyboard.press('Control+A');
// Copy and paste
await page.keyboard.press('Control+C');
await page.keyboard.press('Control+V');
// Undo
await page.keyboard.press('Control+Z');
page.keyboard.down() / up() Press Down / Release
Example
await page.keyboard.down('Shift');
// Press other keys during this time (equivalent to holding Shift while pressing other keys)
await page.keyboard.press('ArrowRight'); // Shift + Right arrow (select text)
await page.keyboard.press('ArrowRight');
// Release Shift
await page.keyboard.up('Shift');
Special Key Names
| Key name | Corresponding key |
|---|---|
Enter | Enter |
Escape | Esc to exit |
Tab | Tab to switch focus |
Backspace | Backspace to delete |
Delete | Delete key |
ArrowUp/Down/Left/Right | Arrow keys |
PageUp/PageDown | Page keys |
Home/End | Home / End |
Control/Alt/Shift/Meta | Modifier keys |
page.keyboard.type() Type Text via Keyboard
Example
await page.keyboard.type('EXAMPLE Tutorial', { delay: 50 });
page.keyboard.insertText() Insert Directly
Example
await page.keyboard.insertText('Quickly inserted text');
Mouse Actions
Coordinate Click and Move
Example
await page.mouse.click(100, 200);
// Double-click at coordinates
await page.mouse.dblclick(100, 200);
// Move the mouse to coordinates
await page.mouse.move(100, 200);
// Press / Release
await page.mouse.down();
await page.mouse.up();
Mouse Wheel
Example
await page.mouse.wheel(0, 500);
// Scroll left 200px
await page.mouse.wheel(200, 0);
locator.dragTo() Drag
Example
const source = page.getByText('Drag me');
const target = page.getByTestId('drop-zone');
await source.dragTo(target);
// Drag with options
await source.dragTo(target, {
sourcePosition: { x: 0, y: 0 }, // Drag start point (relative to the source element)
targetPosition: { x: 10, y: 10 }, // Drag target point (relative to the target element)
});
Choosing Between page.mouse and locator.click
| Method | Applicable scenario |
|---|---|
locator.click() | Click page elements (most scenarios) |
page.mouse.click() | Click specific coordinates (scenarios without DOM like Canvas, charts) |
File Upload
locator.setInputFiles() Single/Multiple Files
Example
await page
.getByLabel('Choose file')
.setInputFiles('path/to/document.pdf');
// Upload multiple files
await page
.getByLabel('Choose file')
.setInputFiles([
'path/to/file1.png',
'path/to/file2.png',
]);
// Clear selected files
await page.getByLabel('Choose file').setInputFiles([]);
File paths are relative to the current working directory (project root directory).
File Download
Example
const downloadPromise = page.waitForEvent('download');
// Perform the operation that triggers the download
await page.getByRole('button', { name: 'Download report' }).click();
// Wait for the download to complete
const download = await downloadPromise;
// Get the suggested filename
console.log(download.suggestedFilename());
// Save to the specified path
await download.saveAs('downloads/report.pdf');