From bcce48362aa513a012127854ac3f49bfe2fe0098 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Mon, 4 May 2020 11:03:44 -0700 Subject: [PATCH] api(waitForSelector): make "state: visible" default, includes rename to state (#2091) --- docs/api.md | 12 +++--- docs/core-concepts.md | 8 ++-- src/frames.ts | 18 +++++---- src/selectors.ts | 8 ++-- src/types.ts | 2 +- test/launcher.spec.js | 4 +- test/waittask.spec.js | 62 +++++++++++++++++------------ utils/generate_types/overrides.d.ts | 2 +- utils/generate_types/test/test.ts | 22 +++++----- 9 files changed, 75 insertions(+), 63 deletions(-) diff --git a/docs/api.md b/docs/api.md index 4894bfabc38f3..b434f07bc4114 100644 --- a/docs/api.md +++ b/docs/api.md @@ -1811,11 +1811,11 @@ return finalResponse.ok(); #### page.waitForSelector(selector[, options]) - `selector` <[string]> A selector of an element to wait for - `options` <[Object]> - - `waitFor` <"attached"|"detached"|"visible"|"hidden"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`attached`) or not present in dom (`detached`). Defaults to `attached`. + - `state` <"attached"|"detached"|"visible"|"hidden"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`attached`) or not present in dom (`detached`). Defaults to `visible`. - `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. -- returns: <[Promise]> Promise which resolves when element specified by selector satisfies `waitFor` option. Resolves to `null` if waiting for `hidden` or `detached`. +- returns: <[Promise]> Promise which resolves when element specified by selector satisfies `state` option. Resolves to `null` if waiting for `hidden` or `detached`. -Wait for the `selector` to satisfy `waitFor` option (either appear/disappear from dom, or become visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. +Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. Element is considered `visible` when it has non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible. Element is considired `hidden` when it is not `visible` as defined above. @@ -2435,11 +2435,11 @@ const [response] = await Promise.all([ #### frame.waitForSelector(selector[, options]) - `selector` <[string]> A selector of an element to wait for - `options` <[Object]> - - `waitFor` <"attached"|"detached"|"visible"|"hidden"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`attached`) or not present in dom (`detached`). Defaults to `attached`. + - `state` <"attached"|"detached"|"visible"|"hidden"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`attached`) or not present in dom (`detached`). Defaults to `visible`. - `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [browserContext.setDefaultTimeout(timeout)](#browsercontextsetdefaulttimeouttimeout) or [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) methods. -- returns: <[Promise]> Promise which resolves when element specified by selector satisfies `waitFor` option. Resolves to `null` if waiting for `hidden` or `detached`. +- returns: <[Promise]> Promise which resolves when element specified by selector satisfies `state` option. Resolves to `null` if waiting for `hidden` or `detached`. -Wait for the `selector` to satisfy `waitFor` option (either appear/disappear from dom, or become visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. +Wait for the `selector` to satisfy `state` option (either appear/disappear from dom, or become visible/hidden). If at the moment of calling the method `selector` already satisfies the condition, the method will return immediately. If the selector doesn't satisfy the condition for the `timeout` milliseconds, the function will throw. Element is considered `visible` when it has non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible. Element is considired `hidden` when it is not `visible` as defined above. diff --git a/docs/core-concepts.md b/docs/core-concepts.md index 8fb46f72932ed..c360298c9c5fe 100644 --- a/docs/core-concepts.md +++ b/docs/core-concepts.md @@ -204,18 +204,18 @@ You can explicitly wait for an element to appear in the DOM or to become visible ```js // Wait for #search to appear in the DOM. -await page.waitForSelector('#search', { waitFor: 'attached' }); +await page.waitForSelector('#search', { state: 'attached' }); // Wait for #promo to become visible, for example with `visibility:visible`. -await page.waitForSelector('#promo', { waitFor: 'visible' }); +await page.waitForSelector('#promo'); ``` ... or to become hidden or detached ```js // Wait for #details to become hidden, for example with `display:none`. -await page.waitForSelector('#details', { waitFor: 'hidden' }); +await page.waitForSelector('#details', { state: 'hidden' }); // Wait for #promo to be removed from the DOM. -await page.waitForSelector('#promo', { waitFor: 'detached' }); +await page.waitForSelector('#promo', { state: 'detached' }); ``` #### API reference diff --git a/src/frames.ts b/src/frames.ts index f85253cd9ad4e..9d4b4343b4fc4 100644 --- a/src/frames.ts +++ b/src/frames.ts @@ -434,14 +434,16 @@ export class Frame { async waitForSelector(selector: string, options?: types.WaitForElementOptions): Promise | null> { if (options && (options as any).visibility) - throw new Error('options.visibility is not supported, did you mean options.waitFor?'); - const { waitFor = 'attached' } = (options || {}); - if (!['attached', 'detached', 'visible', 'hidden'].includes(waitFor)) - throw new Error(`Unsupported waitFor option "${waitFor}"`); + throw new Error('options.visibility is not supported, did you mean options.state?'); + if (options && (options as any).waitFor && (options as any).waitFor !== 'visible') + throw new Error('options.waitFor is not supported, did you mean options.state?'); + const { state = 'visible' } = (options || {}); + if (!['attached', 'detached', 'visible', 'hidden'].includes(state)) + throw new Error(`Unsupported waitFor option "${state}"`); const deadline = this._page._timeoutSettings.computeDeadline(options); - const { world, task } = selectors._waitForSelectorTask(selector, waitFor, deadline); - const result = await this._scheduleRerunnableTask(task, world, deadline, `selector "${selectorToString(selector, waitFor)}"`); + const { world, task } = selectors._waitForSelectorTask(selector, state, deadline); + const result = await this._scheduleRerunnableTask(task, world, deadline, `selector "${selectorToString(selector, state)}"`); if (!result.asElement()) { result.dispose(); return null; @@ -936,9 +938,9 @@ class RerunnableTask { } } -function selectorToString(selector: string, waitFor: 'attached' | 'detached' | 'visible' | 'hidden'): string { +function selectorToString(selector: string, state: 'attached' | 'detached' | 'visible' | 'hidden'): string { let label; - switch (waitFor) { + switch (state) { case 'visible': label = '[visible] '; break; case 'hidden': label = '[hidden] '; break; case 'attached': label = ''; break; diff --git a/src/selectors.ts b/src/selectors.ts index 0bef8dcb71405..2c00a50040886 100644 --- a/src/selectors.ts +++ b/src/selectors.ts @@ -142,12 +142,12 @@ export class Selectors { return result; } - _waitForSelectorTask(selector: string, waitFor: 'attached' | 'detached' | 'visible' | 'hidden', deadline: number): { world: 'main' | 'utility', task: (context: dom.FrameExecutionContext) => Promise } { + _waitForSelectorTask(selector: string, state: 'attached' | 'detached' | 'visible' | 'hidden', deadline: number): { world: 'main' | 'utility', task: (context: dom.FrameExecutionContext) => Promise } { const parsed = this._parseSelector(selector); - const task = async (context: dom.FrameExecutionContext) => context.evaluateHandleInternal(({ evaluator, parsed, waitFor, timeout }) => { + const task = async (context: dom.FrameExecutionContext) => context.evaluateHandleInternal(({ evaluator, parsed, state, timeout }) => { return evaluator.injected.poll('raf', timeout, () => { const element = evaluator.querySelector(parsed, document); - switch (waitFor) { + switch (state) { case 'attached': return element || false; case 'detached': @@ -158,7 +158,7 @@ export class Selectors { return !element || !evaluator.injected.isVisible(element); } }); - }, { evaluator: await this._prepareEvaluator(context), parsed, waitFor, timeout: helper.timeUntilDeadline(deadline) }); + }, { evaluator: await this._prepareEvaluator(context), parsed, state, timeout: helper.timeUntilDeadline(deadline) }); return { world: this._needsMainContext(parsed) ? 'main' : 'utility', task }; } diff --git a/src/types.ts b/src/types.ts index 10c1909e9a57c..ba731ac8150a2 100644 --- a/src/types.ts +++ b/src/types.ts @@ -37,7 +37,7 @@ export type Quad = [ Point, Point, Point, Point ]; export type TimeoutOptions = { timeout?: number }; -export type WaitForElementOptions = TimeoutOptions & { waitFor?: 'attached' | 'detached' | 'visible' | 'hidden' }; +export type WaitForElementOptions = TimeoutOptions & { state?: 'attached' | 'detached' | 'visible' | 'hidden' }; export type Polling = 'raf' | number; export type WaitForFunctionOptions = TimeoutOptions & { polling?: Polling }; diff --git a/test/launcher.spec.js b/test/launcher.spec.js index 606b73e0773ce..0e03f4cdbf302 100644 --- a/test/launcher.spec.js +++ b/test/launcher.spec.js @@ -171,10 +171,10 @@ describe('Browser.disconnect', function() { const browserServer = await browserType.launchServer(defaultBrowserOptions); const remote = await browserType.connect({ wsEndpoint: browserServer.wsEndpoint() }); const page = await remote.newPage(); - const watchdog = page.waitForSelector('div', { timeout: 60000 }).catch(e => e); + const watchdog = page.waitForSelector('div', { state: 'attached', timeout: 60000 }).catch(e => e); // Make sure the previous waitForSelector has time to make it to the browser before we disconnect. - await page.waitForSelector('body'); + await page.waitForSelector('body', { state: 'attached' }); await remote.close(); const error = await watchdog; diff --git a/test/waittask.spec.js b/test/waittask.spec.js index 6c3871b2d7870..baedeb115102c 100644 --- a/test/waittask.spec.js +++ b/test/waittask.spec.js @@ -162,12 +162,22 @@ describe('Frame.waitForFunction', function() { describe('Frame.waitForSelector', function() { const addElement = tag => document.body.appendChild(document.createElement(tag)); + it('should throw on waitFor', async({page, server}) => { + await page.goto(server.EMPTY_PAGE); + let error; + await page.waitForSelector('*', { waitFor: 'attached' }).catch(e => error = e); + expect(error.message).toBe('options.waitFor is not supported, did you mean options.state?'); + }); + it('should tolerate waitFor=visible', async({page, server}) => { + await page.goto(server.EMPTY_PAGE); + await page.waitForSelector('*', { waitFor: 'visible' }).catch(e => error = e); + }); it('should immediately resolve promise if node exists', async({page, server}) => { await page.goto(server.EMPTY_PAGE); const frame = page.mainFrame(); await frame.waitForSelector('*'); await frame.evaluate(addElement, 'div'); - await frame.waitForSelector('div'); + await frame.waitForSelector('div', { state: 'attached'}); }); it('should work with removed MutationObserver', async({page, server}) => { await page.evaluate(() => delete window.MutationObserver); @@ -180,7 +190,7 @@ describe('Frame.waitForSelector', function() { it('should resolve promise when node is added', async({page, server}) => { await page.goto(server.EMPTY_PAGE); const frame = page.mainFrame(); - const watchdog = frame.waitForSelector('div'); + const watchdog = frame.waitForSelector('div', { state: 'attached' }); await frame.evaluate(addElement, 'br'); await frame.evaluate(addElement, 'div'); const eHandle = await watchdog; @@ -206,7 +216,7 @@ describe('Frame.waitForSelector', function() { }); it('should work when node is added through innerHTML', async({page, server}) => { await page.goto(server.EMPTY_PAGE); - const watchdog = page.waitForSelector('h3 div'); + const watchdog = page.waitForSelector('h3 div', { state: 'attached'}); await page.evaluate(addElement, 'span'); await page.evaluate(() => document.querySelector('span').innerHTML = '

'); await watchdog; @@ -215,7 +225,7 @@ describe('Frame.waitForSelector', function() { await page.goto(server.EMPTY_PAGE); await utils.attachFrame(page, 'frame1', server.EMPTY_PAGE); const otherFrame = page.frames()[1]; - const watchdog = page.waitForSelector('div'); + const watchdog = page.waitForSelector('div', { state: 'attached' }); await otherFrame.evaluate(addElement, 'div'); await page.evaluate(addElement, 'div'); const eHandle = await watchdog; @@ -226,7 +236,7 @@ describe('Frame.waitForSelector', function() { await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE); const frame1 = page.frames()[1]; const frame2 = page.frames()[2]; - const waitForSelectorPromise = frame2.waitForSelector('div'); + const waitForSelectorPromise = frame2.waitForSelector('div', { state: 'attached' }); await frame1.evaluate(addElement, 'div'); await frame2.evaluate(addElement, 'div'); const eHandle = await waitForSelectorPromise; @@ -255,7 +265,7 @@ describe('Frame.waitForSelector', function() { }); it('should wait for visible', async({page, server}) => { let divFound = false; - const waitForSelector = page.waitForSelector('div', { waitFor: 'visible' }).then(() => divFound = true); + const waitForSelector = page.waitForSelector('div').then(() => divFound = true); await page.setContent(`
1
`); expect(divFound).toBe(false); await page.evaluate(() => document.querySelector('div').style.removeProperty('display')); @@ -266,17 +276,17 @@ describe('Frame.waitForSelector', function() { }); it('should not consider visible when zero-sized', async({page, server}) => { await page.setContent(`
1
`); - let error = await page.waitForSelector('div', { waitFor: 'visible', timeout: 1000 }).catch(e => e); + let error = await page.waitForSelector('div', { timeout: 1000 }).catch(e => e); expect(error.message).toContain('timeout exceeded'); await page.evaluate(() => document.querySelector('div').style.width = '10px'); - error = await page.waitForSelector('div', { waitFor: 'visible', timeout: 1000 }).catch(e => e); + error = await page.waitForSelector('div', { timeout: 1000 }).catch(e => e); expect(error.message).toContain('timeout exceeded'); await page.evaluate(() => document.querySelector('div').style.height = '10px'); - expect(await page.waitForSelector('div', { waitFor: 'visible', timeout: 1000 })).toBeTruthy(); + expect(await page.waitForSelector('div', { timeout: 1000 })).toBeTruthy(); }); it('should wait for visible recursively', async({page, server}) => { let divVisible = false; - const waitForSelector = page.waitForSelector('div#inner', { waitFor: 'visible' }).then(() => divVisible = true); + const waitForSelector = page.waitForSelector('div#inner').then(() => divVisible = true); await page.setContent(`
hi
`); expect(divVisible).toBe(false); await page.evaluate(() => document.querySelector('div').style.removeProperty('display')); @@ -288,7 +298,7 @@ describe('Frame.waitForSelector', function() { it('hidden should wait for hidden', async({page, server}) => { let divHidden = false; await page.setContent(`
content
`); - const waitForSelector = page.waitForSelector('div', { waitFor: 'hidden' }).then(() => divHidden = true); + const waitForSelector = page.waitForSelector('div', { state: 'hidden' }).then(() => divHidden = true); await page.waitForSelector('div'); // do a round trip expect(divHidden).toBe(false); await page.evaluate(() => document.querySelector('div').style.setProperty('visibility', 'hidden')); @@ -298,7 +308,7 @@ describe('Frame.waitForSelector', function() { it('hidden should wait for display: none', async({page, server}) => { let divHidden = false; await page.setContent(`
content
`); - const waitForSelector = page.waitForSelector('div', { waitFor: 'hidden' }).then(() => divHidden = true); + const waitForSelector = page.waitForSelector('div', { state: 'hidden' }).then(() => divHidden = true); await page.waitForSelector('div'); // do a round trip expect(divHidden).toBe(false); await page.evaluate(() => document.querySelector('div').style.setProperty('display', 'none')); @@ -308,7 +318,7 @@ describe('Frame.waitForSelector', function() { it('hidden should wait for removal', async({page, server}) => { await page.setContent(`
content
`); let divRemoved = false; - const waitForSelector = page.waitForSelector('div', { waitFor: 'hidden' }).then(() => divRemoved = true); + const waitForSelector = page.waitForSelector('div', { state: 'hidden' }).then(() => divRemoved = true); await page.waitForSelector('div'); // do a round trip expect(divRemoved).toBe(false); await page.evaluate(() => document.querySelector('div').remove()); @@ -316,12 +326,12 @@ describe('Frame.waitForSelector', function() { expect(divRemoved).toBe(true); }); it('should return null if waiting to hide non-existing element', async({page, server}) => { - const handle = await page.waitForSelector('non-existing', { waitFor: 'hidden' }); + const handle = await page.waitForSelector('non-existing', { state: 'hidden' }); expect(handle).toBe(null); }); it('should respect timeout', async({page, server}) => { let error = null; - await page.waitForSelector('div', { timeout: 10 }).catch(e => error = e); + await page.waitForSelector('div', { timeout: 10, state: 'attached' }).catch(e => error = e); expect(error).toBeTruthy(); expect(error.message).toContain('waiting for selector "div" failed: timeout'); expect(error).toBeInstanceOf(playwright.errors.TimeoutError); @@ -329,13 +339,13 @@ describe('Frame.waitForSelector', function() { it('should have an error message specifically for awaiting an element to be hidden', async({page, server}) => { await page.setContent(`
content
`); let error = null; - await page.waitForSelector('div', { waitFor: 'hidden', timeout: 1000 }).catch(e => error = e); + await page.waitForSelector('div', { state: 'hidden', timeout: 1000 }).catch(e => error = e); expect(error).toBeTruthy(); expect(error.message).toContain('waiting for selector "[hidden] div" failed: timeout'); }); it('should respond to node attribute mutation', async({page, server}) => { let divFound = false; - const waitForSelector = page.waitForSelector('.zombo').then(() => divFound = true); + const waitForSelector = page.waitForSelector('.zombo', { state: 'attached'}).then(() => divFound = true); await page.setContent(`
`); expect(divFound).toBe(false); await page.evaluate(() => document.querySelector('div').className = 'zombo'); @@ -353,28 +363,28 @@ describe('Frame.waitForSelector', function() { }); it('should throw for unknown waitFor option', async({page, server}) => { await page.setContent('
test
'); - const error = await page.waitForSelector('section', { waitFor: 'foo' }).catch(e => e); + const error = await page.waitForSelector('section', { state: 'foo' }).catch(e => e); expect(error.message).toContain('Unsupported waitFor option'); }); it('should throw for visibility option', async({page, server}) => { await page.setContent('
test
'); const error = await page.waitForSelector('section', { visibility: 'hidden' }).catch(e => e); - expect(error.message).toBe('options.visibility is not supported, did you mean options.waitFor?'); + expect(error.message).toBe('options.visibility is not supported, did you mean options.state?'); }); it('should throw for true waitFor option', async({page, server}) => { await page.setContent('
test
'); - const error = await page.waitForSelector('section', { waitFor: true }).catch(e => e); + const error = await page.waitForSelector('section', { state: true }).catch(e => e); expect(error.message).toContain('Unsupported waitFor option'); }); it('should throw for false waitFor option', async({page, server}) => { await page.setContent('
test
'); - const error = await page.waitForSelector('section', { waitFor: false }).catch(e => e); + const error = await page.waitForSelector('section', { state: false }).catch(e => e); expect(error.message).toContain('Unsupported waitFor option'); }); it('should support >> selector syntax', async({page, server}) => { await page.goto(server.EMPTY_PAGE); const frame = page.mainFrame(); - const watchdog = frame.waitForSelector('css=div >> css=span'); + const watchdog = frame.waitForSelector('css=div >> css=span', { state: 'attached'}); await frame.evaluate(addElement, 'br'); await frame.evaluate(addElement, 'div'); await frame.evaluate(() => document.querySelector('div').appendChild(document.createElement('span'))); @@ -384,12 +394,12 @@ describe('Frame.waitForSelector', function() { }); it('should wait for detached if already detached', async({page, server}) => { await page.setContent('
43543
'); - expect(await page.waitForSelector('css=div', { waitFor: 'detached'})).toBe(null); + expect(await page.waitForSelector('css=div', { state: 'detached'})).toBe(null); }); it('should wait for detached', async({page, server}) => { await page.setContent('
43543
'); let done = false; - const waitFor = page.waitForSelector('css=div', { waitFor: 'detached'}).then(() => done = true); + const waitFor = page.waitForSelector('css=div', { state: 'detached'}).then(() => done = true); expect(done).toBe(false); await page.waitForSelector('css=section'); expect(done).toBe(false); @@ -409,7 +419,7 @@ describe('Frame.waitForSelector xpath', function() { }); it('should respect timeout', async({page}) => { let error = null; - await page.waitForSelector('//div', { timeout: 10 }).catch(e => error = e); + await page.waitForSelector('//div', { state: 'attached', timeout: 10 }).catch(e => error = e); expect(error).toBeTruthy(); expect(error.message).toContain('waiting for selector "//div" failed: timeout'); expect(error).toBeInstanceOf(playwright.errors.TimeoutError); @@ -419,7 +429,7 @@ describe('Frame.waitForSelector xpath', function() { await utils.attachFrame(page, 'frame2', server.EMPTY_PAGE); const frame1 = page.frames()[1]; const frame2 = page.frames()[2]; - const waitForXPathPromise = frame2.waitForSelector('//div'); + const waitForXPathPromise = frame2.waitForSelector('//div', { state: 'attached' }); await frame1.evaluate(addElement, 'div'); await frame2.evaluate(addElement, 'div'); const eHandle = await waitForXPathPromise; diff --git a/utils/generate_types/overrides.d.ts b/utils/generate_types/overrides.d.ts index 69c70f0eb21a3..47c5b3ed713a9 100644 --- a/utils/generate_types/overrides.d.ts +++ b/utils/generate_types/overrides.d.ts @@ -39,7 +39,7 @@ type HTMLOrSVGElement = SVGElement | HTMLElement; type HTMLOrSVGElementHandle = ElementHandle; type WaitForSelectorOptionsNotHidden = PageWaitForSelectorOptions & { - waitFor: 'visible'|'attached'; + state: 'visible'|'attached'; } export interface Page { diff --git a/utils/generate_types/test/test.ts b/utils/generate_types/test/test.ts index 0bfb326e03f68..d70ae9876eca3 100644 --- a/utils/generate_types/test/test.ts +++ b/utils/generate_types/test/test.ts @@ -155,7 +155,7 @@ playwright.chromium.launch().then(async browser => { let currentURL: string; page - .waitForSelector('img', { waitFor: 'visible' }) + .waitForSelector('img') .then(() => console.log('First URL with image: ' + currentURL)); for (currentURL of [ 'https://example.com', @@ -594,7 +594,7 @@ playwright.chromium.launch().then(async browser => { }, 5); const something = Math.random() > .5 ? 'visible' : 'attached'; - const handle = await page.waitForSelector('a', {waitFor: something}); + const handle = await page.waitForSelector('a', {state: something}); await handle.$eval('span', (element, { x, y }) => { const spanAssertion: AssertType = true; const numberAssertion: AssertType = true; @@ -654,19 +654,19 @@ playwright.chromium.launch().then(async browser => { const canBeNull: AssertType = false; } { - const waitFor = Math.random() > .5 ? 'attached' : 'visible'; - const handle = await frameLike.waitForSelector('body', {waitFor}); + const state = Math.random() > .5 ? 'attached' : 'visible'; + const handle = await frameLike.waitForSelector('body', {state}); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = false; } { - const handle = await frameLike.waitForSelector('body', {waitFor: 'hidden'}); + const handle = await frameLike.waitForSelector('body', {state: 'hidden'}); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = true; } { - const waitFor = Math.random() > .5 ? 'hidden' : 'visible'; - const handle = await frameLike.waitForSelector('body', {waitFor}); + const state = Math.random() > .5 ? 'hidden' : 'visible'; + const handle = await frameLike.waitForSelector('body', {state}); const bodyAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = true; } @@ -677,14 +677,14 @@ playwright.chromium.launch().then(async browser => { const canBeNull: AssertType = false; } { - const waitFor = Math.random() > .5 ? 'attached' : 'visible'; - const handle = await frameLike.waitForSelector('something-strange', {waitFor}); + const state = Math.random() > .5 ? 'attached' : 'visible'; + const handle = await frameLike.waitForSelector('something-strange', {state}); const elementAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = false; } { - const waitFor = Math.random() > .5 ? 'hidden' : 'visible'; - const handle = await frameLike.waitForSelector('something-strange', {waitFor}); + const state = Math.random() > .5 ? 'hidden' : 'visible'; + const handle = await frameLike.waitForSelector('something-strange', {state}); const elementAssertion: AssertType, typeof handle> = true; const canBeNull: AssertType = true; }