From a95ced0fefab34412abd6342dc1bee71bd67ceba Mon Sep 17 00:00:00 2001 From: Dmitry Gozman Date: Fri, 31 Mar 2023 10:54:07 -0700 Subject: [PATCH] fix(waitFor): when frameLocator does not match, resolve hidden/detached states (#22119) Fixes #21879. --- packages/playwright-core/src/server/frames.ts | 5 ++++- tests/page/locator-frame.spec.ts | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/server/frames.ts b/packages/playwright-core/src/server/frames.ts index 43a0e1200c..c1a23f100f 100644 --- a/packages/playwright-core/src/server/frames.ts +++ b/packages/playwright-core/src/server/frames.ts @@ -787,8 +787,11 @@ export class Frame extends SdkObject { const promise = this.retryWithProgressAndTimeouts(progress, [0, 20, 50, 100, 100, 500], async continuePolling => { const resolved = await this.selectors.resolveInjectedForSelector(selector, options, scope); progress.throwIfAborted(); - if (!resolved) + if (!resolved) { + if (state === 'hidden' || state === 'detached') + return null; return continuePolling; + } const result = await resolved.injected.evaluateHandle((injected, { info, root }) => { const elements = injected.querySelectorAll(info.parsed, root || document); const element: Element | undefined = elements[0]; diff --git a/tests/page/locator-frame.spec.ts b/tests/page/locator-frame.spec.ts index 55b68864b1..040063acfa 100644 --- a/tests/page/locator-frame.spec.ts +++ b/tests/page/locator-frame.spec.ts @@ -260,9 +260,11 @@ it('getBy coverage', async ({ page, server }) => { it('wait for hidden should succeed when frame is not in dom', async ({ page }) => { it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/21879' }); - it.fixme(); await page.goto('about:blank'); const button = page.frameLocator('iframe1').locator('button'); expect(await button.isHidden()).toBeTruthy(); await button.waitFor({ state: 'hidden', timeout: 1000 }); + await button.waitFor({ state: 'detached', timeout: 1000 }); + const error = await button.waitFor({ state: 'attached', timeout: 1000 }).catch(e => e); + expect(error.message).toContain('Timeout 1000ms exceeded'); });