2023-06-02 17:46:10 +00:00
|
|
|
# Locators
|
|
|
|
|
2023-07-27 07:23:28 +00:00
|
|
|
Locators is a new, experimental API that combines the functionalities of
|
|
|
|
waiting and actions. With additional precondition checks, it
|
|
|
|
enables automatic retries for failed actions, resulting in more reliable and
|
|
|
|
less flaky automation scripts.
|
2023-06-02 17:46:10 +00:00
|
|
|
|
|
|
|
:::note
|
|
|
|
|
|
|
|
Locators API is experimental and we will not follow semver for breaking changes
|
|
|
|
in the Locators API.
|
|
|
|
|
|
|
|
:::
|
|
|
|
|
2023-07-27 07:23:28 +00:00
|
|
|
## Use cases
|
|
|
|
|
|
|
|
### Waiting for an element
|
|
|
|
|
|
|
|
```ts
|
|
|
|
await page.locator('button').wait();
|
|
|
|
```
|
|
|
|
|
|
|
|
The following preconditions are automatically checked:
|
|
|
|
|
|
|
|
- Waits for the element to become
|
|
|
|
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
|
|
|
|
|
|
|
### Waiting for a function
|
|
|
|
|
|
|
|
```ts
|
|
|
|
await page
|
|
|
|
.locator(() => {
|
|
|
|
let resolve!: (node: HTMLCanvasElement) => void;
|
|
|
|
const promise = new Promise(res => {
|
|
|
|
return (resolve = res);
|
|
|
|
});
|
|
|
|
const observer = new MutationObserver(records => {
|
|
|
|
for (const record of records) {
|
|
|
|
if (record.target instanceof HTMLCanvasElement) {
|
|
|
|
resolve(record.target);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
observer.observe(document);
|
|
|
|
return promise;
|
|
|
|
})
|
|
|
|
.wait();
|
|
|
|
```
|
|
|
|
|
|
|
|
### Clicking an element
|
2023-06-02 17:46:10 +00:00
|
|
|
|
|
|
|
```ts
|
|
|
|
await page.locator('button').click();
|
|
|
|
```
|
|
|
|
|
|
|
|
The following preconditions are automatically checked:
|
|
|
|
|
|
|
|
- Ensures the element is in the viewport.
|
|
|
|
- Waits for the element to become
|
|
|
|
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
|
|
|
- Waits for the element to become enabled.
|
|
|
|
- Waits for the element to have a stable bounding box over two consecutive
|
|
|
|
animation frames.
|
|
|
|
|
2023-07-27 07:23:28 +00:00
|
|
|
### Clicking an element matching a criteria
|
|
|
|
|
|
|
|
```ts
|
|
|
|
await page
|
|
|
|
.locator('button')
|
|
|
|
.filter(button => !button.disabled)
|
|
|
|
.click();
|
|
|
|
```
|
|
|
|
|
|
|
|
The following preconditions are automatically checked:
|
|
|
|
|
|
|
|
- Ensures the element is in the viewport.
|
|
|
|
- Waits for the element to become
|
|
|
|
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
|
|
|
- Waits for the element to become enabled.
|
|
|
|
- Waits for the element to have a stable bounding box over two consecutive
|
|
|
|
animation frames.
|
|
|
|
|
|
|
|
### Filling out an input
|
2023-06-02 17:46:10 +00:00
|
|
|
|
|
|
|
```ts
|
|
|
|
await page.locator('input').fill('value');
|
|
|
|
```
|
|
|
|
|
|
|
|
Automatically detects the input type and choose an approritate way to fill it out with the provided value.
|
|
|
|
|
|
|
|
The following preconditions are automatically checked:
|
|
|
|
|
|
|
|
- Ensures the element is in the viewport.
|
|
|
|
- Waits for the element to become
|
|
|
|
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
|
|
|
- Waits for the element to become enabled.
|
|
|
|
- Waits for the element to have a stable bounding box over two consecutive
|
|
|
|
animation frames.
|
|
|
|
|
2023-07-27 07:23:28 +00:00
|
|
|
### Retrieving an element property
|
|
|
|
|
|
|
|
```ts
|
|
|
|
const enabled = await page
|
|
|
|
.locator('button')
|
|
|
|
.map(button => !button.disabled)
|
|
|
|
.wait();
|
|
|
|
```
|
|
|
|
|
|
|
|
### Hover over an element
|
2023-06-02 17:46:10 +00:00
|
|
|
|
|
|
|
```ts
|
|
|
|
await page.locator('div').hover();
|
|
|
|
```
|
|
|
|
|
|
|
|
The following preconditions are automatically checked:
|
|
|
|
|
|
|
|
- Ensures the element is in the viewport.
|
|
|
|
- Waits for the element to become
|
|
|
|
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
|
|
|
- Waits for the element to have a stable bounding box over two consecutive
|
|
|
|
animation frames.
|
|
|
|
|
2023-07-27 07:23:28 +00:00
|
|
|
### Scroll an element
|
2023-06-02 17:46:10 +00:00
|
|
|
|
|
|
|
```ts
|
|
|
|
await page.locator('div').scroll({
|
|
|
|
scrollLeft: 10,
|
|
|
|
scrollTop: 20,
|
|
|
|
});
|
|
|
|
```
|
|
|
|
|
|
|
|
The following preconditions are automatically checked:
|
|
|
|
|
|
|
|
- Ensures the element is in the viewport.
|
|
|
|
- Waits for the element to become
|
|
|
|
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
|
|
|
- Waits for the element to have a stable bounding box over two consecutive
|
|
|
|
animation frames.
|
|
|
|
|
|
|
|
## Configuring locators
|
|
|
|
|
|
|
|
Locators can be configured to tune configure the preconditions and other other options:
|
|
|
|
|
|
|
|
```ts
|
|
|
|
await page
|
|
|
|
.locator('button')
|
|
|
|
.setEnsureElementIsInTheViewport(false)
|
|
|
|
.setTimeout(0)
|
|
|
|
.setVisibility(null)
|
|
|
|
.setWaitForEnabled(false)
|
|
|
|
.setWaitForStableBoundingBox(false)
|
|
|
|
.click();
|
|
|
|
```
|
|
|
|
|
|
|
|
## Getting locator events
|
|
|
|
|
|
|
|
Currently, locators support a single event that notifies you when the locator is about to perform the action:
|
|
|
|
|
|
|
|
```ts
|
|
|
|
let willClick = false;
|
|
|
|
await page
|
|
|
|
.locator('button')
|
|
|
|
.on(LocatorEmittedEvents.Action, () => {
|
|
|
|
willClick = true;
|
|
|
|
})
|
|
|
|
.click();
|
|
|
|
```
|
|
|
|
|
|
|
|
This event can be used for logging/debugging or other purposes. The event might
|
|
|
|
fire multiple times if the locator retries the action.
|