new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Playwright · all subjects

actions/auto-waiting

62 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

Force option disables non-essential actionability checks

Some actions like Locator.click support a force option that disables non-essential actionability checks. For example, passing truthy force to Locator.click will not check that the target element actually receives click events.

Auto-waiting for actions — actionability checks before execution

Playwright performs actionability checks on elements before making actions to ensure they behave as expected. It auto-waits for all relevant checks to pass and only then performs the requested action. If required checks do not pass within the given timeout, the action fails with TimeoutError.

Actionability checks by action type

Actionability checks vary by action. check, click, dblclick, setChecked, tap, uncheck require: Visible, Stable, Receives Events, Enabled. hover and dragTo require: Visible, Stable, Receives Events. screenshot requires: Visible, Stable. fill and clear require: Visible, Enabled, Editable. selectOption requires: Visible, Enabled. selectText requires: Visible. scrollIntoViewIfNeeded requires: Stable. blur, dispatchEvent, focus, press, pressSequentially, setInputFiles require: none.

Actionability checks for Locator.click

Before executing click, Playwright ensures: the locator resolves to exactly one element, the element is visible, the element is stable (not animating or completed animation), the element receives events (not obscured by other elements), and the element is enabled.

Navigation lifecycle events in Playwright

Playwright splits the process of showing a new document in a page into navigation and loading. Navigation starts by changing the page URL or by interacting with the page (such as clicking a link). Navigation is committed when the response headers have been parsed and session history is updated. Only after the navigation succeeds (is committed) does the page start loading the document. Loading covers getting the remaining response body over the network, parsing, executing scripts, and firing load events. During loading, page.url is set to the new URL, document content is loaded and parsed, the Page.DOMContentLoaded event is fired, the page executes scripts and loads resources like stylesheets and images, the Page.load event is fired, and the page executes dynamically loaded scripts.

page.goto waits for load event

The page.goto() method loads a page and waits for the web page to fire the load event, which is fired when the whole page has loaded, including all dependent resources such as stylesheets, scripts, iframes, and images.

page.goto handles client-side redirects

If the page does a client-side redirect before load, page.goto() will wait for the redirected page to fire the load event.

Actions auto-wait for actionability

In Playwright, you can interact with the page at any moment. Actions will automatically wait for the target elements to become actionable. For example, Playwright will wait for text to become visible, wait for actionability checks to pass for the element, and then perform the action like clicking.

page.waitForURL for multi-navigation scenarios

When clicking an element could trigger multiple navigations, it is recommended to explicitly use page.waitForURL() to wait for a specific URL.

Polyfill waitForAngular for Angular 2+

To polyfill waitForAngular for Angular 2+ without keeping Protractor as a dependency, use an async function that calls page.evaluate with code that waits for all Angular testabilities to be stable. The function accesses window.getAllAngularTestabilities(), maps each testability to a promise that resolves when whenStable is called, and awaits all promises.

All Playwright calls must be awaited

Almost all Playwright calls are prefixed with await. Locator creation with page.locator() is one of the few methods that is synchronous and does not need to be awaited.

Playwright Test replaces Protractor waitForAngular with auto-waiting

Playwright Test has built-in auto-waiting that makes Protractor's waitForAngular unneeded in the general case. However, for edge cases, waitForAngular can be polyfilled.

Explicit waits often unnecessary

You probably don't need explicit wait with Playwright. Methods like page.waitForNavigation and page.waitForSelector remain but in many cases will not be necessary due to auto-waiting.

Playwright locator action methods

Playwright locators support action methods: click(), focus(), hover(), tap(), fill(), check(), uncheck(), selectOption(), and setInputFiles(). These are called on page.locator(selector) with the selector passed to locator(), not as a parameter to the action method.

Locators are central to auto-waiting and retry-ability

Locators are the central piece of Playwright's auto-waiting and retry-ability features.

Page.fill force option ignores actionability

The `force` option was added to `Page.fill()`, `Frame.fill()`, and `ElementHandle.fill()` methods in Playwright 1.13, allowing filling without waiting for actionability.

Page.selectOption force option ignores actionability

The `force` option was added to `Page.selectOption()`, `Frame.selectOption()`, and `ElementHandle.selectOption()` methods in Playwright 1.13.

Page.goto commit waiting option

Page navigations now support a new `'commit'` waiting option in `Page.goto()` (introduced in 1.17).

Mouse.wheel scrolls vertically or horizontally

The `Mouse.wheel()` method (introduced in 1.15) allows scrolling vertically or horizontally.

Locator handler waits for overlay to disappear after execution

After executing a handler added with Page.addLocatorHandler, Playwright waits until the overlay that triggered the handler is no longer visible. This behavior can be disabled with the noWaitAfter option.

Locator.pressSequentially presses keys one by one

The Locator.pressSequentially method presses keys one-by-one, useful for special keyboard handling on pages that require sequential key presses instead of instant input.

Page.type deprecation in favor of Locator.fill

Page.type, Frame.type, Locator.type, and ElementHandle.type are deprecated. Use Locator.fill instead which is much faster, or Locator.pressSequentially for special keyboard handling.

Locator.blur removes focus

The Locator.blur method removes focus from an element.

Locator.clear clears input

The Locator.clear method clears the value of an input or textarea element.

Locator.selectOption matches by value or label

The Locator.selectOption method now matches options by value or label text, providing more flexible option selection.

Page.dragTo drags element to target

The Locator.dragTo method drags an element to a target location.

Locator.waitFor waits for single element with state

The `Locator.waitFor()` method waits for a locator to resolve to a single element with a given state. It defaults to `state: 'visible'`. It is especially useful when working with lists.

Locator.waitFor example usage

Example of using Locator.waitFor(): const completeness = page.locator('text=Success'); await completeness.waitFor(); expect(await page.screenshot()).toMatchSnapshot('screen.png');

Page.dragAndDrop programmatic drag-and-drop

The `Page.dragAndDrop()` API (introduced in 1.13) provides programmatic drag-and-drop support.

Page.waitForURL awaits navigations

The `Page.waitForURL()` method (introduced in 1.11) awaits navigations to a specific URL.

trial option for dry-running actions

The `trial` option in Playwright 1.11 allows dry-running actions in Page.check(), Page.uncheck(), Page.click(), Page.dblclick(), Page.hover(), and Page.tap() methods.

Async predicates in Playwright API

Support for async predicates was added across the API in methods such as Page.waitForRequest() in Playwright 1.11.

Page.selectOption waits for options

The `Page.selectOption()` method (as of 1.8) now waits for the options to be present before selecting.

Locator.dispatchEvent does not set Event.isTrusted property

When using Locator.dispatchEvent to manually dispatch TouchEvents, the Event.isTrusted property is not set. If the web page relies on this property, you must disable the isTrusted check during tests.

Pan gesture example - touchstart, touchmove, touchend sequence

To emulate a pan gesture, dispatch touchstart with initial touch point coordinates, then dispatch multiple touchmove events with incrementally updated coordinates, and finally dispatch touchend. The example shows a pan function that moves a touch point by deltaX and deltaY pixels over a specified number of steps (default 5). Only clientX and clientY coordinates need to be set if the app only cares about those; pageX/pageY/screenX/screenY may be needed for more complex scenarios.

Pan gesture JavaScript example with Locator.dispatchEvent

```js import { test, expect, devices, type Locator } from '@playwright/test'; test.use({ ...devices['Pixel 7'] }); async function pan(locator: Locator, deltaX?: number, deltaY?: number, steps?: number) { const { centerX, centerY } = await locator.evaluate((target: HTMLElement) => { const bounds = target.getBoundingClientRect(); const centerX = bounds.left + bounds.width / 2; const centerY = bounds.top + bounds.height / 2; return { centerX, centerY }; }); const touches = [{ identifier: 0, clientX: centerX, clientY: centerY, }]; await locator.dispatchEvent('touchstart', { touches, changedTouches: touches, targetTouches: touches }); steps = steps ?? 5; deltaX = deltaX ?? 0; deltaY = deltaY ?? 0; for (let i = 1; i <= steps; i++) { const touches = [{ identifier: 0, clientX: centerX + deltaX * i / steps, clientY: centerY + deltaY * i / steps, }]; await locator.dispatchEvent('touchmove', { touches, changedTouches: touches, targetTouches: touches }); } await locator.dispatchEvent('touchend'); } test(`pan gesture to move the map`, async ({ page }) => { await page.goto('https://www.google.com/maps/place/@37.4117722,-122.0713234,15z', { waitUntil: 'commit' }); await page.getByRole('button', { name: 'Keep using web' }).click(); await expect(page.getByRole('button', { name: 'Keep using web' })).not.toBeVisible(); const met = page.locator('[data-test-id="met"]'); for (let i = 0; i < 5; i++) await pan(met, 200, 100); await expect(met).toHaveScreenshot(); }); ```

Pinch gesture example - two touch points moving together

To emulate a pinch gesture, dispatch touchstart with two touch points (identifier 0 and 1) equally distant from the element center. Then dispatch multiple touchmove events with coordinates adjusted to move the touch points closer together (pinch in) or farther apart (pinch out). Finally dispatch touchend with empty touches arrays. The direction parameter controls whether the gesture pinches in or out. Default deltaX is 50 pixels, default steps is 5.

Pinch gesture JavaScript example with Locator.dispatchEvent

```js import { test, expect, devices, type Locator } from '@playwright/test'; test.use({ ...devices['Pixel 7'] }); async function pinch(locator: Locator, arg: { deltaX?: number, deltaY?: number, steps?: number, direction?: 'in' | 'out' }) { const { centerX, centerY } = await locator.evaluate((target: HTMLElement) => { const bounds = target.getBoundingClientRect(); const centerX = bounds.left + bounds.width / 2; const centerY = bounds.top + bounds.height / 2; return { centerX, centerY }; }); const deltaX = arg.deltaX ?? 50; const steps = arg.steps ?? 5; const stepDeltaX = deltaX / (steps + 1); const touches = [ { identifier: 0, clientX: centerX - (arg.direction === 'in' ? deltaX : stepDeltaX), clientY: centerY, }, { identifier: 1, clientX: centerX + (arg.direction === 'in' ? deltaX : stepDeltaX), clientY: centerY, }, ]; await locator.dispatchEvent('touchstart', { touches, changedTouches: touches, targetTouches: touches }); for (let i = 1; i <= steps; i++) { const offset = (arg.direction === 'in' ? (deltaX - i * stepDeltaX) : (stepDeltaX * (i + 1))); const touches = [ { identifier: 0, clientX: centerX - offset, clientY: centerY, }, { identifier: 0, clientX: centerX + offset, clientY: centerY, }, ]; await locator.dispatchEvent('touchmove', { touches, changedTouches: touches, targetTouches: touches }); } await locator.dispatchEvent('touchend', { touches: [], changedTouches: [], targetTouches: [] }); } test(`pinch in gesture to zoom out the map`, async ({ page }) => { await page.goto('https://www.google.com/maps/place/@37.4117722,-122.0713234,15z', { waitUntil: 'commit' }); await page.getByRole('button', { name: 'Keep using web' }).click(); await expect(page.getByRole('button', { name: 'Keep using web' })).not.toBeVisible(); const met = page.locator('[data-test-id="met"]'); for (let i = 0; i < 5; i++) await pinch(met, { deltaX: 40, direction: 'in' }); await expect(met).toHaveScreenshot(); }); ```

page.goto waits for load state

Playwright waits for the page to reach the load state before continuing when using page.goto().

Keyboard shortcuts with modifiers

Shortcuts such as 'Control+o' or 'Control+Shift+T' are supported. When specified with a modifier, the modifier is pressed and held while the subsequent key is being pressed. Capital letters must be explicitly specified (Shift+A produces capital 'A', Shift+a produces lowercase 'a').

Locator.pressSequentially() for character-by-character input

The Locator.pressSequentially() method types characters into a field one by one, as if using a real keyboard. It emits all necessary keyboard events including keydown, keyup, and keypress events. An optional delay parameter can specify the delay between key presses to simulate real user behavior. This should only be used when special keyboard handling is required; Locator.fill() is preferred for regular text input.

Locator.press() for single keystrokes

The Locator.press() method focuses the selected element and produces a single keystroke. It accepts logical key names emitted in keyboardEvent.key property: Backquote, Minus, Equal, Backslash, Backspace, Tab, Delete, Escape, ArrowDown, End, Enter, Home, Insert, PageDown, PageUp, ArrowRight, ArrowUp, F1 - F12, Digit0 - Digit9, KeyA - KeyZ, and others. Single characters like 'a' or '#' can also be specified. Modification shortcuts supported are Shift, Control, Alt, and Meta.

Locator.fill() for text input

The Locator.fill() method is the easiest way to fill out form fields. It focuses the element and triggers an input event with the entered text. It works for <input>, <textarea>, and [contenteditable] elements.

Locator.setChecked() for checkboxes and radio buttons

The Locator.setChecked() method is used to check and uncheck checkboxes or radio buttons. It works with input[type=checkbox], input[type=radio], and [role=checkbox] elements.

Locator.selectOption() for select elements

The Locator.selectOption() method selects one or multiple options in a <select> element. You can specify option value or label to select. Multiple options can be selected by passing an array.

Click auto-waiting behavior

When clicking an element, Playwright automatically: waits for element with given selector to be in DOM, waits for it to become displayed (not empty, no display:none, no visibility:hidden), waits for it to stop moving (until css transition finishes), scrolls the element into view, waits for it to receive pointer events at the action point (waits until element becomes non-obscured by other elements), and retries if the element is detached during any of these checks.

Forcing clicks with force option

The click() method accepts a force: true option to bypass actionability checks. This is useful when apps use non-trivial logic where hovering overlays the element with another element that intercepts the click.

Programmatic click with dispatchEvent

The Locator.dispatchEvent() method can dispatch a click event on an element, triggering HTMLElement.click() behavior without testing under real conditions. This simulates the click by any means possible.

Handling dynamically created file input elements

When an input element is created dynamically, you can handle the Page.fileChooser event or use page.waitForEvent('filechooser') before clicking. Start waiting for the file chooser before clicking (with no await), then click the upload element, and call setFiles() on the returned fileChooser object.

Locator.focus() for focusing elements

The Locator.focus() method focuses a given element. This is useful for dynamic pages that handle focus events.

Locator.dragTo() for drag and drop

The Locator.dragTo() method performs a drag and drop operation. It hovers the element that will be dragged, presses left mouse button, moves mouse to the element that will receive the drop, and releases left mouse button.

Manual drag operation with low-level methods

For precise control over drag operations, use lower-level methods: Locator.hover(), Mouse.down(), Mouse.move(), and Mouse.up(). If your page relies on dragover event being dispatched, you need at least two mouse moves to trigger it in all browsers. Repeat Locator.hover() or Mouse.move() twice. The sequence is: hover drag element, mouse down, hover drop element, hover drop element second time, mouse up.

Automatic scrolling behavior

Playwright automatically scrolls elements into view before performing actions. Most of the time you do not need to scroll explicitly.

Locator.scrollIntoViewIfNeeded() for manual scrolling

The Locator.scrollIntoViewIfNeeded() method scrolls an element into view. This is useful in rare cases such as forcing an 'infinite list' to load more elements or positioning the page for a specific screenshot.

Precise scrolling control with Mouse.wheel() and evaluate

For more precise scrolling control, use Mouse.wheel() to scroll with the mouse wheel at a specific position, or Locator.evaluate() to programmatically scroll a specific element by modifying its scrollTop property.

Mouse click options in JavaScript

The click() method in JavaScript accepts options including button ('left', 'right', 'middle'), modifiers array (e.g., ['Shift'], ['ControlOrMeta']), and position object with x and y coordinates.

Mouse click operations examples

JavaScript examples: generic click with await page.getByRole('button').click(), double click with await page.getByText('Item').dblclick(), right click with await page.getByText('Item').click({ button: 'right' }), Shift+click with await page.getByText('Item').click({ modifiers: ['Shift'] }), Ctrl/Meta+click with await page.getByText('Item').click({ modifiers: ['ControlOrMeta'] }), hover with await page.getByText('Item').hover(), and click at coordinates with await page.getByText('Item').click({ position: { x: 0, y: 0 } }).

Text fill examples for different input types

JavaScript examples for Locator.fill(): text input with await page.getByRole('textbox').fill('Peter'), date input with await page.getByLabel('Birth date').fill('2020-02-02'), time input with await page.getByLabel('Appointment time').fill('13:15'), and local datetime input with await page.getByLabel('Local time').fill('2020-03-02T05:15').

Checkbox and radio button examples

JavaScript examples: check checkbox with await page.getByLabel('I agree to the terms above').check(), assert checked state with expect(page.getByLabel('Subscribe to newsletter')).toBeChecked(), and select radio button with await page.getByLabel('XL').check().

Select option examples

JavaScript examples for Locator.selectOption(): single selection matching value or label with await page.getByLabel('Choose a color').selectOption('blue'), single selection with explicit label with await page.getByLabel('Choose a color').selectOption({ label: 'Blue' }), and multiple selections with await page.getByLabel('Choose multiple colors').selectOption(['red', 'green', 'blue']).

Give your agent this brain