From ab323122d823d51a59276ba9b54fa545c26f2638 Mon Sep 17 00:00:00 2001 From: Joey Arhar Date: Thu, 22 Sep 2022 13:48:58 -0700 Subject: [PATCH] feat(chromium): use Element.checkVisibility in isElementVisible (#16592) Element.checkVisibility is a new browser API that was shipped in chromium 105: https://bugs.chromium.org/p/chromium/issues/detail?id=1309533 Using checkVisibility accounts for the content-visibility:hidden in the user-agent ShadowRoot of the details element, which means we can remove the usage of the AutoExpandDetailsElementFlag (I am trying to remove the flag in chromium). This behavior is covered by the existing "isVisible and isHidden should work with details" test in locator-convenience.spec.ts. --- .../playwright-core/src/server/injected/domUtils.ts | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/playwright-core/src/server/injected/domUtils.ts b/packages/playwright-core/src/server/injected/domUtils.ts index cb8a013274..8a7abe8b63 100644 --- a/packages/playwright-core/src/server/injected/domUtils.ts +++ b/packages/playwright-core/src/server/injected/domUtils.ts @@ -60,8 +60,6 @@ export function isElementVisible(element: Element): boolean { if (!element.ownerDocument || !element.ownerDocument.defaultView) return true; const style = element.ownerDocument.defaultView.getComputedStyle(element); - if (!style || style.visibility === 'hidden') - return false; if (style.display === 'contents') { // display:contents is not rendered itself, but its child nodes are. for (let child = element.firstChild; child; child = child.nextSibling) { @@ -72,6 +70,14 @@ export function isElementVisible(element: Element): boolean { } return false; } + // Element.checkVisibility checks for content-visibility and also looks at + // styles up the flat tree including user-agent ShadowRoots, such as the + // details element for example. + // @ts-ignore Typescript doesn't know that checkVisibility exists yet. + if (Element.prototype.checkVisibility && !element.checkVisibility({ checkOpacity: false, checkVisibilityCSS: false })) + return false; + if (!style || style.visibility === 'hidden') + return false; const rect = element.getBoundingClientRect(); return rect.width > 0 && rect.height > 0; }