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

locators

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

Shorthand attribute selectors

Playwright supports shorthand for selecting elements using certain attributes: 'id', 'data-testid', 'data-test-id', 'data-test'. For example, 'id=username' fills an input with id 'username', and 'data-test-id=submit' clicks an element with data-test-id 'submit'.

Attribute selectors do not support CSS pseudo-classes

Attribute selectors are not CSS selectors, so CSS-specific pseudo-classes like :enabled are not supported. For more features, use a proper CSS selector, for example 'css=[data-test="login"]:enabled'.

Chaining selectors with >> operator

Selectors defined as 'engine=body' or in short-form can be combined with the '>>' token. When selectors are chained, the next one is queried relative to the previous one's result. For example, 'css=article >> css=.bar > .baz >> css=span[attr=value]' is equivalent to document.querySelector('article').querySelector('.bar > .baz').querySelector('span[attr=value]').

Escaping >> in selector body

If a selector needs to include '>>' in the body, it should be escaped inside a string to not be confused with the chaining separator. For example, 'text="some >> text"' searches for text containing '>>'.

Chained selector intermediate matches with *

By default, chained selectors resolve to an element queried by the last selector. A selector can be prefixed with '*' to capture elements queried by an intermediate selector. For example, 'css=article >> text=Hello' captures the element with text 'Hello', while '*css=article >> text=Hello' captures the article element that contains some element with text 'Hello'.

FrameLocator.owner example

const frameLocator = page.frameLocator('iframe[name="embedded"]'); const locator = frameLocator.owner(); await expect(locator).toBeVisible();

Locator has option filters by child locator

Locators can include a has option to filter elements that contain a specific child element: page.locator('article', { has: page.locator('.highlight') }).click();

Locator.page returns locator's page

The Locator.page method returns the Page associated with the locator.

Locator has option for element composition

The has option in locators allows filtering elements that contain specific child elements, enabling complex element selection patterns.

Frame locators are strict by default

Frame locators introduced in Playwright 1.17 are strict by default. They capture the logic to retrieve an iframe and then locate elements within that iframe. Frame locators will wait for the iframe to appear and can be used in Web-First assertions. Frame locators can be created with either `page.frameLocator()` or `locator.frameLocator()` methods.

Frame locator example usage

Example of creating and using a frame locator: const locator = page.frameLocator('#my-iframe').locator('text=Submit'); await locator.click();

Locators are strict by default

Locators introduced in Playwright 1.14 are strict by default, meaning they ensure the selector points to a single element and throw otherwise. This prevents selector ambiguity issues common in automation testing.

Locator API represents element view

The Locator API (introduced in 1.14) represents a view to the elements on a page and captures the logic sufficient to retrieve the element at any given moment. The key difference from ElementHandle is that Locator captures the retrieval logic, while ElementHandle points to a particular element.

React selector engine syntax

React selectors (experimental in 1.14) allow selecting elements by component name and/or property values using syntax similar to attribute selectors. Example: await page.locator('_react=SubmitButton[enabled=true]').click();

Vue selector engine syntax

Vue selectors (experimental in 1.14) allow selecting elements by component name and/or property values. Example: await page.locator('_vue=submit-button[enabled=true]').click();

getByTitle locator by title attribute

The Page.getByTitle method locates an element by its title attribute.

nth selector engine usage

The `nth` selector engine (introduced in 1.14) is equivalent to the `:nth-match` pseudo class but can be combined with other selector engines. Alternative syntax using locators: page.locator('button').first(), page.locator('button').nth(0), page.locator('button').last()

visible selector engine usage

The `visible` selector engine (introduced in 1.14) is equivalent to the `:visible` pseudo class but can be combined with other selector engines. Example: await page.locator('button >> visible=true').click();

Strict mode throws on selector ambiguity

Strict mode (introduced in 1.14) ensures a selector points to a single element and throws if it matches multiple elements. Pass `strict: true` to action calls to opt in. Example: await page.click('button', { strict: true });

CSS selector extensions in 1.7

Playwright 1.7 introduced new CSS selector extensions and revamped the selectors implementation for more flexible selectors.

has-text pseudo-class for CSS selectors

The `:has-text("example")` pseudo-class (introduced in 1.9) matches any element containing "example" somewhere inside, possibly in a child or descendant element.

CSS selectors with layout matching

Playwright 1.8 introduced layout-based CSS selectors: `:left-of()`, `:right-of()`, `:above()`, and `:below()` for selecting elements based on layout.

getByTestId locator by data-testid attribute

The Page.getByTestId method locates an element based on its data-testid attribute (the attribute name can be configured).

getByPlaceholder locator by input placeholder

The Page.getByPlaceholder method locates an input element by its placeholder text.

getByAltText locator by alt text

The Page.getByAltText method locates an element (usually an image) by its text alternative (alt attribute).

getByLabel locator by associated label text

The Page.getByLabel method locates a form control by the associated label's text.

addLocatorHandler times option limits handler execution

The times option in Page.addLocatorHandler specifies the maximum number of times the handler should be executed. After reaching this limit, the handler will no longer be invoked.

addLocatorHandler example with overlay

const locator = page.getByText('This interstitial covers the button'); await page.addLocatorHandler(locator, async overlay => { await overlay.locator('#close').click(); }, { times: 3, noWaitAfter: true }); await page.removeLocatorHandler(locator);

Locator.contentFrame converts Locator to FrameLocator

The new Locator.contentFrame method converts a Locator object to a FrameLocator, useful when you have a Locator and need to interact with content inside an iframe.

FrameLocator.owner converts FrameLocator to Locator

The new FrameLocator.owner method converts a FrameLocator object to a Locator, useful when you need to interact with the iframe element itself.

contentFrame example

const locator = page.locator('iframe[name="embedded"]'); const frameLocator = locator.contentFrame(); await frameLocator.getByRole('button').click();

Page.addLocatorHandler registers overlay handler callback

The Page.addLocatorHandler method registers a callback that is invoked when a specified element becomes visible and may block Playwright actions. The callback can dismiss overlays like cookie dialogs.

addLocatorHandler cookie dialog example

await page.addLocatorHandler( page.getByRole('heading', { name: 'Hej! You are in control of your cookies.' }), async () => { await page.getByRole('button', { name: 'Accept all' }).click(); }); await page.goto('https://www.ikea.com/');

Locator.filter with hasNot and hasNotText options

The Locator.filter method now supports hasNot and hasNotText options to find elements that do not match certain conditions.

Locator.or creates union locator

The Locator.or method creates a locator that matches either of two locators, useful for handling variable UI like dialogs that may appear instead of expected elements.

removeLocatorHandler removes previously added handlers

Page.removeLocatorHandler removes a handler that was previously registered with Page.addLocatorHandler for a specific locator.

addLocatorHandler passes locator as argument to handler

The handler callback in Page.addLocatorHandler now receives the locator as an argument, allowing the handler to interact with the element that triggered it.

getByRole locator with ARIA role and attributes

The Page.getByRole method locates elements by their ARIA role, ARIA attributes, and accessible name, following accessibility best practices.

getByText locator by text content

The Page.getByText method locates elements by their visible text content.

Locator.filter filters locator by conditions

The Locator.filter method creates a new locator that only matches elements satisfying additional conditions like hasText.

Locator.and creates intersection locator

The Locator.and method creates a locator that matches elements satisfying both locator conditions, useful for precise element selection.

Locator hasText filter option

Locators can be filtered by text using the hasText option: page.locator('li', { hasText: 'my item' }).locator('button').click();

testIdAttribute configuration option

The testIdAttribute option changes the default data-testid attribute used by Playwright locators. Defaults to 'data-testid'. Example: 'pw-test-id' changes the attribute to data-pw-test-id.

Basic Playwright actions on locators

The most popular Playwright actions are: check (check the input checkbox), click (click the element), uncheck (uncheck the input checkbox), hover (hover mouse over the element), fill (fill the form field, input text), focus (focus the element), press (press single key), setInputFiles (pick files to upload), and selectOption (select option in the drop down).

ElementHandle is discouraged

The use of ElementHandle is discouraged. Use Locator objects and web-first assertions instead.

Fetching ElementHandle with waitForSelector

When ElementHandle is required, fetch it with page.waitForSelector() or Frame.waitForSelector() methods. These APIs wait for the element to be attached and visible.

Obtaining JSHandle example

To obtain a JSHandle, call page.evaluateHandle with a JavaScript expression: const jsHandle = await page.evaluateHandle('window');

ElementHandle boundingBox example

To assert the bounding box of an element: const elementHandle = page.waitForSelector('#box'); const boundingBox = await elementHandle.boundingBox(); expect(boundingBox.width).toBe(100);

ElementHandle getAttribute example

To assert an element attribute: const classNames = await elementHandle.getAttribute('class'); expect(classNames.includes('highlighted')).toBeTruthy();

Passing handles to evaluate method

Handles can be passed into page.evaluate() and similar methods as parameters. This allows using handles in subsequent evaluations within the page context.

Handle lifecycle and garbage collection

Handles are acquired using page methods such as page.evaluateHandle(), page.querySelector(), or page.querySelectorAll() and their frame counterparts. Once created, handles retain objects from garbage collection unless the page navigates or the handle is manually disposed via JSHandle.dispose() method.

Disposing handles example

To release a handle when no longer needed: await myArrayHandle.dispose();

Locator vs ElementHandle difference

ElementHandle points to a particular DOM element at a moment in time. If that element changes text or React renders a different component, the handle still points to the stale DOM element. Locator captures the logic of how to retrieve an element, so every time it is used, the up-to-date DOM element is located using the selector.

Locator example with fresh element

Locator example showing how it retrieves fresh elements: const locator = page.getByText('Submit'); await locator.hover(); await locator.click(); The locator re-locates the underlying DOM element each time it is used.

ElementHandle example with stale element

ElementHandle example showing the problem of stale references: const handle = await page.$('text=Submit'); await handle.hover(); await handle.click(); The handle points to a specific element that may become stale.

When to use ElementHandle

Only recommend using ElementHandle in the rare cases when you need to perform extensive DOM traversal on a static page. For all user actions and assertions use locator instead.

JSHandle vs ElementHandle types

Playwright can create two types of handles to page objects. JSHandle references any JavaScript object in the page. ElementHandle references DOM elements in the page and has extra methods for performing actions and asserting properties. Since any DOM element is also a JavaScript object, any ElementHandle is a JSHandle as well.

Passing handle to evaluate with parameters

Handles can be passed as parameters to page.evaluate() by including them in an object or array: await page.evaluate(arg => arg.myArray.push(arg.newElement), { myArray: myArrayHandle, newElement: 2 });

Give your agent this brain