@@ -450,6 +450,148 @@ It is sugar for `nth(-1)`.
450450page.getByRole('textbox').last() // ✅
451451` ` `
452452
453+ ## and
454+
455+ ` ` ` ts
456+ function and(locator: Locator): Locator
457+ ` ` `
458+
459+ This method creates a new locator that matches both the parent and provided locator . The following example finds a button with a specific title :
460+
461+ ` ` ` ts
462+ page.getByRole('button').and(page.getByTitle('Subscribe'))
463+ ` ` `
464+
465+ ## or
466+
467+ ` ` ` ts
468+ function or(locator: Locator): Locator
469+ ` ` `
470+
471+ This method creates a new locator that matches either one or both locators .
472+
473+ ::: warning
474+ Note that if locator matches more than a single element , calling another method might throw an error if it expects a single element :
475+
476+ ` ` ` tsx
477+ <>
478+ <button>Click me</button>
479+ <a href="https://vitest.dev">Error happened!</a>
480+ </>
481+
482+ page.getByRole('button')
483+ .or(page.getByRole('link'))
484+ .click() // ❌ matches multiple elements
485+ ` ` `
486+ :::
487+
488+ ## filter
489+
490+ ` ` ` ts
491+ function filter(options: LocatorOptions): Locator
492+ ` ` `
493+
494+ This methods narrows down the locator according to the options , such as filtering by text . It can be chained to apply multiple filters .
495+
496+ ### has
497+
498+ - ** Type :** ` Locator `
499+
500+ This options narrows down the selector to match elements that contain other elements matching provided locator . For example , with this HTML :
501+
502+ ` ` ` html{1,3}
503+ <article>
504+ <div>Vitest</div>
505+ </article>
506+ <article>
507+ <div>Rolldown</div>
508+ </article>
509+ ` ` `
510+
511+ We can narrow down the locator to only find the ` article ` with ` Vitest ` text inside :
512+
513+ ` ` ` ts
514+ page.getByRole('article').filter({ has: page.getByText('Vitest') }) // ✅
515+ ` ` `
516+
517+ ::: warning
518+ Provided locator (` page.getByText('Vitest') ` in the example ) must be relative to the parent locator (` page.getByRole('article') ` in the example ). It will be queried starting with the parent locator , not the document root .
519+
520+ Meaning , you cannot pass down a locator that queries the element outside of the parent locator :
521+
522+ ` ` ` ts
523+ page.getByText('Vitest').filter({ has: page.getByRole('article') }) // ❌
524+ ` ` `
525+
526+ This example will fail because the ` article ` element is outside the element with ` Vitest ` text .
527+ :::
528+
529+ ::: tip
530+ This method can be chained to narrow down the element even further :
531+
532+ ` ` ` ts
533+ page.getByRole('article')
534+ .filter({ has: page.getByRole('button', { name: 'delete row' }) })
535+ .filter({ has: page.getByText('Vitest') })
536+ ` ` `
537+ :::
538+
539+ ### hasNot
540+
541+ - ** Type :** ` Locator `
542+
543+ This option narrows down the selector to match elements that do not contain other elements matching provided locator . For example , with this HTML :
544+
545+ ` ` ` html{1,3}
546+ <article>
547+ <div>Vitest</div>
548+ </article>
549+ <article>
550+ <div>Rolldown</div>
551+ </article>
552+ ` ` `
553+
554+ We can narrow down the locator to only find the ` article ` that doesn ' t have `Rolldown` inside.
555+
556+ ` ` ` ts
557+ page.getByRole('article')
558+ .filter({ hasNot: page.getByText('Rolldown') }) // ✅
559+ page.getByRole('article')
560+ .filter({ hasNot: page.getByText('Vitest') }) // ❌
561+ ` ` `
562+
563+ ::: warning
564+ Note that provided locator is queried against the parent , not the document root , just like [` has ` ](#has ) option .
565+ :::
566+
567+ ### hasText
568+
569+ - ** Type :** ` string | RegExp `
570+
571+ This options narrows down the selector to only match elements that contain provided text somewhere inside . When the ` string ` is passed , matching is case - insensitive and searches for a substring .
572+
573+ ` ` ` html{1,3}
574+ <article>
575+ <div>Vitest</div>
576+ </article>
577+ <article>
578+ <div>Rolldown</div>
579+ </article>
580+ ` ` `
581+
582+ Both locators will find the same element because the search is case - insensitive :
583+
584+ ` ` ` ts
585+ page.getByRole('article').filter({ hasText: 'Vitest' }) // ✅
586+ page.getByRole('article').filter({ hasText: 'Vite' }) // ✅
587+ ` ` `
588+
589+ ### hasNotText
590+
591+ - ** Type :** ` string | RegExp `
592+
593+ This options narrows down the selector to only match elements that do not contain provided text somewhere inside . When the ` string ` is passed , matching is case - insensitive and searches for a substring .
594+
453595## Methods
454596
455597All methods are asynchronous and must be awaited . Since Vitest 3 , tests will fail if a method is not awaited .
0 commit comments