From 98f9f050a11fc032475280196f162e78f548a9d8 Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 5 Aug 2021 21:10:33 +0200 Subject: [PATCH] fix(isVisible): do not throw when element is not connected (#8012) --- src/server/dom.ts | 4 +++- tests/page/elementhandle-convenience.spec.ts | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/server/dom.ts b/src/server/dom.ts index 3dbf6f4833..dde2c6685d 100644 --- a/src/server/dom.ts +++ b/src/server/dom.ts @@ -697,7 +697,9 @@ export class ElementHandle extends js.JSHandle { async isVisible(): Promise { const result = await this.evaluateInUtility(([injected, node]) => injected.checkElementState(node, 'visible'), {}); - return throwRetargetableDOMError(throwFatalDOMError(result)); + if (result === 'error:notconnected') + return false; + return throwFatalDOMError(result); } async isHidden(): Promise { diff --git a/tests/page/elementhandle-convenience.spec.ts b/tests/page/elementhandle-convenience.spec.ts index 3ecd81be62..7422c98dcd 100644 --- a/tests/page/elementhandle-convenience.spec.ts +++ b/tests/page/elementhandle-convenience.spec.ts @@ -211,6 +211,25 @@ it('element state checks should work for label with zero-sized input', async ({p expect(await page.isDisabled('text=Click me')).toBe(true); }); +it('isVisible should not throw when the DOM element is not connected', async ({page}) => { + await page.setContent(`
`); + await page.evaluate(() => { + function insert() { + document.getElementById('root').innerHTML = '
Problem
'; + window.requestAnimationFrame(remove); + } + function remove() { + const node = document.getElementById('problem'); + node?.parentNode?.removeChild(node); + window.requestAnimationFrame(insert); + } + window.requestAnimationFrame(insert); + }); + + for (let i = 0; i < 10; i++) + await page.isVisible('#problem'); +}); + it('isEnabled and isDisabled should work', async ({ page }) => { await page.setContent(`