2021-07-27 15:27:36 -07:00
/ * *
* Copyright 2018 Google Inc . All rights reserved .
* Modifications copyright ( c ) Microsoft Corporation .
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an "AS IS" BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
* /
import { test as it , expect } from './pageTest' ;
2022-03-10 19:42:52 +01:00
it ( 'should respect first() and last() @smoke' , async ( { page } ) = > {
2021-07-27 15:27:36 -07:00
await page . setContent ( `
< section >
< div > < p > A < / p > < / div >
< div > < p > A < / p > < p > A < / p > < / div >
< div > < p > A < / p > < p > A < / p > < p > A < / p > < / div >
< / section > ` );
expect ( await page . locator ( 'div >> p' ) . count ( ) ) . toBe ( 6 ) ;
expect ( await page . locator ( 'div' ) . locator ( 'p' ) . count ( ) ) . toBe ( 6 ) ;
expect ( await page . locator ( 'div' ) . first ( ) . locator ( 'p' ) . count ( ) ) . toBe ( 1 ) ;
2021-07-27 15:58:18 -07:00
expect ( await page . locator ( 'div' ) . last ( ) . locator ( 'p' ) . count ( ) ) . toBe ( 3 ) ;
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should respect nth()' , async ( { page } ) = > {
2021-07-27 15:58:18 -07:00
await page . setContent ( `
< section >
< div > < p > A < / p > < / div >
< div > < p > A < / p > < p > A < / p > < / div >
< div > < p > A < / p > < p > A < / p > < p > A < / p > < / div >
< / section > ` );
expect ( await page . locator ( 'div >> p' ) . nth ( 0 ) . count ( ) ) . toBe ( 1 ) ;
expect ( await page . locator ( 'div' ) . nth ( 1 ) . locator ( 'p' ) . count ( ) ) . toBe ( 2 ) ;
expect ( await page . locator ( 'div' ) . nth ( 2 ) . locator ( 'p' ) . count ( ) ) . toBe ( 3 ) ;
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should throw on capture w/ nth()' , async ( { page } ) = > {
2021-07-27 15:58:18 -07:00
await page . setContent ( ` <section><div><p>A</p></div></section> ` ) ;
2021-08-11 11:06:09 -07:00
const e = await page . locator ( '*css=div >> p' ) . nth ( 1 ) . click ( ) . catch ( e = > e ) ;
2021-07-27 15:58:18 -07:00
expect ( e . message ) . toContain ( ` Can't query n-th element ` ) ;
2021-07-27 15:27:36 -07:00
} ) ;
2021-07-28 15:44:44 -07:00
2021-09-27 18:58:08 +02:00
it ( 'should throw on due to strictness' , async ( { page } ) = > {
2021-07-28 15:44:44 -07:00
await page . setContent ( ` <div>A</div><div>B</div> ` ) ;
const e = await page . locator ( 'div' ) . isVisible ( ) . catch ( e = > e ) ;
expect ( e . message ) . toContain ( ` strict mode violation ` ) ;
} ) ;
2021-09-27 18:58:08 +02:00
it ( 'should throw on due to strictness 2' , async ( { page } ) = > {
2021-07-28 15:44:44 -07:00
await page . setContent ( ` <select><option>One</option><option>Two</option></select> ` ) ;
const e = await page . locator ( 'option' ) . evaluate ( e = > { } ) . catch ( e = > e ) ;
expect ( e . message ) . toContain ( ` strict mode violation ` ) ;
} ) ;
2021-12-03 09:27:06 -08:00
it ( 'should filter by text' , async ( { page } ) = > {
await page . setContent ( ` <div>Foobar</div><div>Bar</div> ` ) ;
2021-12-14 15:37:31 -08:00
await expect ( page . locator ( 'div' , { hasText : 'Foo' } ) ) . toHaveText ( 'Foobar' ) ;
2021-12-03 09:27:06 -08:00
} ) ;
it ( 'should filter by text 2' , async ( { page } ) = > {
await page . setContent ( ` <div>foo <span>hello world</span> bar</div> ` ) ;
2021-12-14 15:37:31 -08:00
await expect ( page . locator ( 'div' , { hasText : 'hello world' } ) ) . toHaveText ( 'foo hello world bar' ) ;
2021-12-03 09:27:06 -08:00
} ) ;
it ( 'should filter by regex' , async ( { page } ) = > {
await page . setContent ( ` <div>Foobar</div><div>Bar</div> ` ) ;
2021-12-14 15:37:31 -08:00
await expect ( page . locator ( 'div' , { hasText : /Foo.*/ } ) ) . toHaveText ( 'Foobar' ) ;
2021-12-03 09:27:06 -08:00
} ) ;
it ( 'should filter by text with quotes' , async ( { page } ) = > {
await page . setContent ( ` <div>Hello "world"</div><div>Hello world</div> ` ) ;
2021-12-14 15:37:31 -08:00
await expect ( page . locator ( 'div' , { hasText : 'Hello "world"' } ) ) . toHaveText ( 'Hello "world"' ) ;
2021-12-03 09:27:06 -08:00
} ) ;
it ( 'should filter by regex with quotes' , async ( { page } ) = > {
await page . setContent ( ` <div>Hello "world"</div><div>Hello world</div> ` ) ;
2021-12-14 15:37:31 -08:00
await expect ( page . locator ( 'div' , { hasText : /Hello "world"/ } ) ) . toHaveText ( 'Hello "world"' ) ;
2021-12-03 09:27:06 -08:00
} ) ;
2021-12-07 19:33:04 -08:00
2023-09-11 15:49:04 -07:00
it ( 'should filter by regex with a single quote' , async ( { page } ) = > {
await page . setContent ( ` <button>let's let's<span>hello</span></button> ` ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let's/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let's/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let['abc]s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let['abc]s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\\'s/i } ) ) . not . toBeVisible ( ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\\'s/i } ) ) . not . toBeVisible ( ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let's let\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let's let\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\'s let's/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\'s let's/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await page . setContent ( ` <button>let \\ 's let \\ 's<span>hello</span></button> ` ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\'s/i } ) ) . not . toBeVisible ( ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\'s/i } ) ) . not . toBeVisible ( ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\\'s let\\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\\'s let\\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . locator ( 'button' , { hasText : /let\\\'s let\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
await expect . soft ( page . getByRole ( 'button' , { name : /let\\\'s let\\'s/i } ) . locator ( 'span' ) ) . toHaveText ( 'hello' ) ;
2023-09-19 13:16:50 -07:00
await page . setContent ( ` <button>let's hello</button> ` ) ;
await expect . soft ( page . locator ( 'button' , { hasText : / l e t ' s / i u } ) ) . t o H a v e T e x t ( ` l e t ' s h e l l o ` ) ;
await expect . soft ( page . getByRole ( 'button' , { name : / l e t ' s / i u } ) ) . t o H a v e T e x t ( ` l e t ' s h e l l o ` ) ;
2023-09-11 15:49:04 -07:00
} ) ;
2021-12-07 19:33:04 -08:00
it ( 'should filter by regex and regexp flags' , async ( { page } ) = > {
await page . setContent ( ` <div>Hello "world"</div><div>Hello world</div> ` ) ;
2021-12-14 15:37:31 -08:00
await expect ( page . locator ( 'div' , { hasText : /hElLo "world"/i } ) ) . toHaveText ( 'Hello "world"' ) ;
2021-12-07 19:33:04 -08:00
} ) ;
2022-02-02 16:55:50 -08:00
2022-07-11 14:24:08 -07:00
it ( 'should filter by case-insensitive regex in a child' , async ( { page } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/15348' } ) ;
await page . setContent ( ` <div class="test"><h5>Title Text</h5></div> ` ) ;
await expect ( page . locator ( 'div' , { hasText : /^title text$/i } ) ) . toHaveText ( 'Title Text' ) ;
} ) ;
2022-07-14 08:23:11 -07:00
it ( 'should filter by case-insensitive regex in multiple children' , async ( { page } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/15348' } ) ;
await page . setContent ( ` <div class="test"><h5>Title</h5> <h2><i>Text</i></h2></div> ` ) ;
await expect ( page . locator ( 'div' , { hasText : /^title text$/i } ) ) . toHaveClass ( 'test' ) ;
} ) ;
it ( 'should filter by regex with special symbols' , async ( { page } ) = > {
it . info ( ) . annotations . push ( { type : 'issue' , description : 'https://github.com/microsoft/playwright/issues/15348' } ) ;
await page . setContent ( ` <div class="test"><h5>First/"and"</h5><h2><i>Second \\ </i></h2></div> ` ) ;
await expect ( page . locator ( 'div' , { hasText : / ^ f i r s t \ / " . * " s e c o n d \ \ $ / s i } ) ) . t o H a v e C l a s s ( ' t e s t ' ) ;
} ) ;
2022-02-04 15:34:33 -08:00
it ( 'should support has:locator' , async ( { page , trace } ) = > {
it . skip ( trace === 'on' ) ;
2022-02-02 16:55:50 -08:00
await page . setContent ( ` <div><span>hello</span></div><div><span>world</span></div> ` ) ;
await expect ( page . locator ( ` div ` , {
has : page.locator ( ` text=world ` )
} ) ) . toHaveCount ( 1 ) ;
2023-03-29 23:17:17 -07:00
expect ( await page . locator ( ` div ` , {
2022-02-02 16:55:50 -08:00
has : page.locator ( ` text=world ` )
2023-03-29 23:17:17 -07:00
} ) . evaluate ( e = > e . outerHTML ) ) . toBe ( ` <div><span>world</span></div> ` ) ;
2022-02-02 16:55:50 -08:00
await expect ( page . locator ( ` div ` , {
has : page.locator ( ` text="hello" ` )
} ) ) . toHaveCount ( 1 ) ;
2023-03-29 23:17:17 -07:00
expect ( await page . locator ( ` div ` , {
2022-02-02 16:55:50 -08:00
has : page.locator ( ` text="hello" ` )
2023-03-29 23:17:17 -07:00
} ) . evaluate ( e = > e . outerHTML ) ) . toBe ( ` <div><span>hello</span></div> ` ) ;
2022-02-02 16:55:50 -08:00
await expect ( page . locator ( ` div ` , {
has : page.locator ( ` xpath=./span ` )
} ) ) . toHaveCount ( 2 ) ;
await expect ( page . locator ( ` div ` , {
has : page.locator ( ` span ` )
} ) ) . toHaveCount ( 2 ) ;
await expect ( page . locator ( ` div ` , {
has : page.locator ( ` span ` , { hasText : 'wor' } )
} ) ) . toHaveCount ( 1 ) ;
2023-03-29 23:17:17 -07:00
expect ( await page . locator ( ` div ` , {
2022-02-02 16:55:50 -08:00
has : page.locator ( ` span ` , { hasText : 'wor' } )
2023-03-29 23:17:17 -07:00
} ) . evaluate ( e = > e . outerHTML ) ) . toBe ( ` <div><span>world</span></div> ` ) ;
2022-02-02 16:55:50 -08:00
await expect ( page . locator ( ` div ` , {
has : page.locator ( ` span ` ) ,
hasText : 'wor' ,
} ) ) . toHaveCount ( 1 ) ;
} ) ;
2022-05-08 21:59:40 +01:00
it ( 'should support locator.filter' , async ( { page , trace } ) = > {
2022-04-25 20:06:18 +01:00
it . skip ( trace === 'on' ) ;
await page . setContent ( ` <section><div><span>hello</span></div><div><span>world</span></div></section> ` ) ;
2022-05-08 21:59:40 +01:00
await expect ( page . locator ( ` div ` ) . filter ( { hasText : 'hello' } ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` , { hasText : 'hello' } ) . filter ( { hasText : 'hello' } ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` , { hasText : 'hello' } ) . filter ( { hasText : 'world' } ) ) . toHaveCount ( 0 ) ;
await expect ( page . locator ( ` section ` , { hasText : 'hello' } ) . filter ( { hasText : 'world' } ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` ) . filter ( { hasText : 'hello' } ) . locator ( 'span' ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` ) . filter ( { has : page.locator ( 'span' , { hasText : 'world' } ) } ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` ) . filter ( { has : page.locator ( 'span' ) } ) ) . toHaveCount ( 2 ) ;
await expect ( page . locator ( ` div ` ) . filter ( {
2022-04-25 20:06:18 +01:00
has : page.locator ( 'span' ) ,
hasText : 'world' ,
} ) ) . toHaveCount ( 1 ) ;
2023-04-05 12:45:46 -07:00
await expect ( page . locator ( ` div ` ) . filter ( { hasNot : page.locator ( 'span' , { hasText : 'world' } ) } ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` ) . filter ( { hasNot : page.locator ( 'section' ) } ) ) . toHaveCount ( 2 ) ;
await expect ( page . locator ( ` div ` ) . filter ( { hasNot : page.locator ( 'span' ) } ) ) . toHaveCount ( 0 ) ;
2023-04-05 14:13:28 -07:00
await expect ( page . locator ( ` div ` ) . filter ( { hasNotText : 'hello' } ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( ` div ` ) . filter ( { hasNotText : 'foo' } ) ) . toHaveCount ( 2 ) ;
2022-04-25 20:06:18 +01:00
} ) ;
2023-05-05 11:14:01 -07:00
it ( 'should support locator.and' , async ( { page } ) = > {
await page . setContent ( `
< div data-testid = foo > hello < / div > < div data-testid = bar > world < / div >
< span data-testid = foo > hello2 < / span > < span data-testid = bar > world2 < / span >
` );
await expect ( page . locator ( 'div' ) . and ( page . locator ( 'div' ) ) ) . toHaveCount ( 2 ) ;
await expect ( page . locator ( 'div' ) . and ( page . getByTestId ( 'foo' ) ) ) . toHaveText ( [ 'hello' ] ) ;
await expect ( page . locator ( 'div' ) . and ( page . getByTestId ( 'bar' ) ) ) . toHaveText ( [ 'world' ] ) ;
await expect ( page . getByTestId ( 'foo' ) . and ( page . locator ( 'div' ) ) ) . toHaveText ( [ 'hello' ] ) ;
await expect ( page . getByTestId ( 'bar' ) . and ( page . locator ( 'span' ) ) ) . toHaveText ( [ 'world2' ] ) ;
await expect ( page . locator ( 'span' ) . and ( page . getByTestId ( /bar|foo/ ) ) ) . toHaveCount ( 2 ) ;
} ) ;
2023-03-22 15:28:59 -07:00
it ( 'should support locator.or' , async ( { page } ) = > {
await page . setContent ( ` <div>hello</div><span>world</span> ` ) ;
await expect ( page . locator ( 'div' ) . or ( page . locator ( 'span' ) ) ) . toHaveCount ( 2 ) ;
await expect ( page . locator ( 'div' ) . or ( page . locator ( 'span' ) ) ) . toHaveText ( [ 'hello' , 'world' ] ) ;
await expect ( page . locator ( 'span' ) . or ( page . locator ( 'article' ) ) . or ( page . locator ( 'div' ) ) ) . toHaveText ( [ 'hello' , 'world' ] ) ;
2024-05-08 20:40:03 +02:00
await expect ( page . locator ( 'article' ) . or ( page . locator ( 'something' ) ) ) . toHaveCount ( 0 ) ;
2023-03-22 15:28:59 -07:00
await expect ( page . locator ( 'article' ) . or ( page . locator ( 'div' ) ) ) . toHaveText ( 'hello' ) ;
await expect ( page . locator ( 'article' ) . or ( page . locator ( 'span' ) ) ) . toHaveText ( 'world' ) ;
await expect ( page . locator ( 'div' ) . or ( page . locator ( 'article' ) ) ) . toHaveText ( 'hello' ) ;
await expect ( page . locator ( 'span' ) . or ( page . locator ( 'article' ) ) ) . toHaveText ( 'world' ) ;
} ) ;
2023-07-14 12:21:45 -07:00
it ( 'should support locator.locator with and/or' , async ( { page } ) = > {
await page . setContent ( `
< div > one < span > two < / span > < button > three < / button > < / div >
< span > four < / span >
< button > five < / button >
` );
await expect ( page . locator ( 'div' ) . locator ( page . locator ( 'button' ) ) ) . toHaveText ( [ 'three' ] ) ;
await expect ( page . locator ( 'div' ) . locator ( page . locator ( 'button' ) . or ( page . locator ( 'span' ) ) ) ) . toHaveText ( [ 'two' , 'three' ] ) ;
await expect ( page . locator ( 'button' ) . or ( page . locator ( 'span' ) ) ) . toHaveText ( [ 'two' , 'three' , 'four' , 'five' ] ) ;
await expect ( page . locator ( 'div' ) . locator ( page . locator ( 'button' ) . and ( page . getByRole ( 'button' ) ) ) ) . toHaveText ( [ 'three' ] ) ;
await expect ( page . locator ( 'button' ) . and ( page . getByRole ( 'button' ) ) ) . toHaveText ( [ 'three' , 'five' ] ) ;
} ) ;
2023-06-19 15:22:26 -07:00
it ( 'should allow some, but not all nested frameLocators' , async ( { page } ) = > {
await page . setContent ( ` <iframe srcdoc="<span id=target>world</span>"></iframe><span>hello</span> ` ) ;
await expect ( page . frameLocator ( 'iframe' ) . locator ( 'span' ) . or ( page . frameLocator ( 'iframe' ) . locator ( 'article' ) ) ) . toHaveText ( 'world' ) ;
await expect ( page . frameLocator ( 'iframe' ) . locator ( 'article' ) . or ( page . frameLocator ( 'iframe' ) . locator ( 'span' ) ) ) . toHaveText ( 'world' ) ;
await expect ( page . frameLocator ( 'iframe' ) . locator ( 'span' ) . and ( page . frameLocator ( 'iframe' ) . locator ( '#target' ) ) ) . toHaveText ( 'world' ) ;
const error1 = await expect ( page . frameLocator ( 'iframe' ) . locator ( 'div' ) . or ( page . frameLocator ( '#iframe' ) . locator ( 'span' ) ) ) . toHaveText ( 'world' ) . catch ( e = > e ) ;
2024-09-18 20:15:01 -07:00
expect ( error1 . message ) . toContain ( ` Frame locators are not allowed inside composite locators, while querying "locator('iframe').contentFrame().locator('div').or(locator('#iframe').contentFrame().locator('span')) ` ) ;
2023-06-19 15:22:26 -07:00
const error2 = await expect ( page . frameLocator ( 'iframe' ) . locator ( 'div' ) . and ( page . frameLocator ( '#iframe' ) . locator ( 'span' ) ) ) . toHaveText ( 'world' ) . catch ( e = > e ) ;
2024-09-18 20:15:01 -07:00
expect ( error2 . message ) . toContain ( ` Frame locators are not allowed inside composite locators, while querying "locator('iframe').contentFrame().locator('div').and(locator('#iframe').contentFrame().locator('span')) ` ) ;
2023-06-19 15:22:26 -07:00
} ) ;
2022-05-03 10:33:33 +01:00
it ( 'should enforce same frame for has/leftOf/rightOf/above/below/near' , async ( { page , server } ) = > {
2022-02-02 16:55:50 -08:00
await page . goto ( server . PREFIX + '/frames/two-frames.html' ) ;
const child = page . frames ( ) [ 1 ] ;
2022-05-12 18:50:19 +01:00
for ( const option of [ 'has' ] ) {
2022-05-03 10:33:33 +01:00
let error ;
try {
page . locator ( 'div' , { [ option ] : child . locator ( 'span' ) } ) ;
} catch ( e ) {
error = e ;
}
expect ( error . message ) . toContain ( ` Inner " ${ option } " locator must belong to the same frame. ` ) ;
}
} ) ;
2022-09-27 15:13:56 -08:00
it ( 'alias methods coverage' , async ( { page } ) = > {
await page . setContent ( ` <div><button>Submit</button></div> ` ) ;
2022-09-29 11:50:52 -08:00
await expect ( page . locator ( 'button' ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( 'div' ) . locator ( 'button' ) ) . toHaveCount ( 1 ) ;
await expect ( page . locator ( 'div' ) . getByRole ( 'button' ) ) . toHaveCount ( 1 ) ;
await expect ( page . mainFrame ( ) . locator ( 'button' ) ) . toHaveCount ( 1 ) ;
2022-09-27 15:13:56 -08:00
} ) ;