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'); });