Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement Locator.nth() #7137

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
12 changes: 12 additions & 0 deletions docs/guide/browser/locators.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,18 @@ Internally, this method calls `.elements` and wraps every element using [`page.e

- [See `locator.elements()`](#elements)

### nth, first, last

```ts
function nth(index: number): Locator
function first(): Locator
function last(): Locator
```

These methods return a new locator that matches only a specific element within a multi-element query.

It is similar to calling `.elements()[n]` but more readable, with better failure messages, and can be retried more easily with `expect.element`.

## Properties

### selector
Expand Down
12 changes: 12 additions & 0 deletions packages/browser/src/client/tester/locators/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,18 @@ export abstract class Locator {
return this.elements().map(element => this.elementLocator(element))
}

public nth(index: number): Locator {
return this.locator(`nth=${index}`)
}

public first(): Locator {
return this.nth(0)
}

public last(): Locator {
return this.nth(-1)
}

public toString(): string {
return this.selector
}
Expand Down
5 changes: 5 additions & 0 deletions test/browser/fixtures/locators/blog.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ test('renders blog posts', async () => {

expect(screen.getByRole('listitem').all()).toHaveLength(3)

expect(screen.getByRole('listitem').nth(0).element()).toHaveTextContent(/molestiae ut ut quas/)
await expect.element(screen.getByRole('listitem').nth(666)).not.toBeInTheDocument()
expect(screen.getByRole('listitem').first().element()).toHaveTextContent(/molestiae ut ut quas/)
expect(screen.getByRole('listitem').last().element()).toHaveTextContent(/eum et est/)

expect(screen.getByPlaceholder('non-existing').query()).not.toBeInTheDocument()
})
Loading