diff --git a/lib/FrameManager.js b/lib/FrameManager.js index ced7edd70c0..3eb10641153 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -502,8 +502,16 @@ class Frame { if (!waitForVisible && !waitForHidden) return true; const style = window.getComputedStyle(node); - const isVisible = style && style.display !== 'none' && style.visibility !== 'hidden'; + const isVisible = style && style.visibility !== 'hidden' && hasVisibleBoundingBox(); return (waitForVisible === isVisible || waitForHidden === !isVisible); + + /** + * @return {boolean} + */ + function hasVisibleBoundingBox() { + const rect = node.getBoundingClientRect(); + return !!(rect.top || rect.bottom || rect.width || rect.height); + } } } diff --git a/test/test.js b/test/test.js index 4015dedeb20..bc66777e46c 100644 --- a/test/test.js +++ b/test/test.js @@ -752,7 +752,7 @@ describe('Page', function() { it('should wait for visible', SX(async function() { let divFound = false; const waitForSelector = page.waitForSelector('div', {visible: true}).then(() => divFound = true); - await page.setContent(`
`); + await page.setContent(` `); expect(divFound).toBe(false); await page.evaluate(() => document.querySelector('div').style.removeProperty('display')); expect(divFound).toBe(false); @@ -760,10 +760,23 @@ describe('Page', function() { expect(await waitForSelector).toBe(true); expect(divFound).toBe(true); })); + it('should wait for visible recursively', SX(async function() { + let divVisible = false; + const waitForSelector = page.waitForSelector('div#inner', {visible: true}).then(() => divVisible = true); + await page.setContent(` `); + expect(divVisible).toBe(false); + await page.evaluate(() => document.querySelector('div').style.removeProperty('display')); + expect(divVisible).toBe(false); + await page.evaluate(() => document.querySelector('div').style.removeProperty('visibility')); + expect(await waitForSelector).toBe(true); + expect(divVisible).toBe(true); + })); it('hidden should wait for visibility: hidden', SX(async function() { let divHidden = false; await page.setContent(``); const waitForSelector = page.waitForSelector('div', {hidden: true}).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')); expect(await waitForSelector).toBe(true); expect(divHidden).toBe(true); @@ -772,6 +785,8 @@ describe('Page', function() { let divHidden = false; await page.setContent(``); const waitForSelector = page.waitForSelector('div', {hidden: true}).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')); expect(await waitForSelector).toBe(true); expect(divHidden).toBe(true); @@ -780,6 +795,7 @@ describe('Page', function() { await page.setContent(``); let divRemoved = false; const waitForSelector = page.waitForSelector('div', {hidden: true}).then(() => divRemoved = true); + await page.waitForSelector('div'); // do a round trip expect(divRemoved).toBe(false); await page.evaluate(() => document.querySelector('div').remove()); expect(await waitForSelector).toBe(true);