From 28265fc31346d15a06a73ab36bc74fe9adf539ff Mon Sep 17 00:00:00 2001 From: JoelEinbinder Date: Tue, 18 Jul 2017 02:10:02 -0700 Subject: [PATCH] Fix frame.waitFor to work with complex selectors (#90) The frame.waitFor didn't account for multi-level selectors. This patch fixes this, executing document.querySelector on every DOM mutation. --- lib/FrameManager.js | 35 +++++++++++++++++------------------ test/test.js | 11 +++++++++++ 2 files changed, 28 insertions(+), 18 deletions(-) diff --git a/lib/FrameManager.js b/lib/FrameManager.js index c7a2abc3..7a987aee 100644 --- a/lib/FrameManager.js +++ b/lib/FrameManager.js @@ -178,26 +178,25 @@ class FrameManager extends EventEmitter { * @return {!Promise} */ async _waitForInFrame(selector, frame) { - let code = selector => new Promise((fulfill, reject) => { - if (document.querySelector(selector)) { - fulfill(); - return; - } - new MutationObserver((mutations, observer) => { - for (let mutation of mutations) { - for (let node of mutation.addedNodes) { - if (node.matches(selector)) { - observer.disconnect(); - fulfill(); - return; - } - } + let code = selector => { + let promise = new Promise(fulfill => { + if (document.querySelector(selector)) { + fulfill(); + return; } - }).observe(document.documentElement, { - childList: true, - subtree: true + new MutationObserver((mutations, observer) => { + if (document.querySelector(selector)) { + observer.disconnect(); + fulfill(); + return; + } + }).observe(document.documentElement, { + childList: true, + subtree: true + }); }); - }); + return promise; + }; let contextId = undefined; if (!frame.isMainFrame()) { contextId = this._frameIdToExecutionContextId.get(frame._id); diff --git a/test/test.js b/test/test.js index 0cd9be95..7ce19159 100644 --- a/test/test.js +++ b/test/test.js @@ -190,6 +190,17 @@ describe('Puppeteer', function() { expect(added).toBe(true); })); + it('should work when node is added through innerHTML', SX(async function() { + await page.navigate(EMPTY_PAGE); + let frame = page.mainFrame(); + let added = false; + frame.waitFor('h3 div').then(() => added = true); + expect(added).toBe(false); + await frame.evaluate(addElement, 'span'); + await page.$('span', span => span.innerHTML = '

'); + expect(added).toBe(true); + })); + it('Page.waitFor is shortcut for main frame', SX(async function() { await page.navigate(EMPTY_PAGE); await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE);