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.
This commit is contained in:
JoelEinbinder 2017-07-18 02:10:02 -07:00 committed by Andrey Lushnikov
parent 6c1c3a0c45
commit 28265fc313
2 changed files with 28 additions and 18 deletions

View File

@ -178,26 +178,25 @@ class FrameManager extends EventEmitter {
* @return {!Promise<undefined>} * @return {!Promise<undefined>}
*/ */
async _waitForInFrame(selector, frame) { async _waitForInFrame(selector, frame) {
let code = selector => new Promise((fulfill, reject) => { let code = selector => {
if (document.querySelector(selector)) { let promise = new Promise(fulfill => {
fulfill(); if (document.querySelector(selector)) {
return; 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;
}
}
} }
}).observe(document.documentElement, { new MutationObserver((mutations, observer) => {
childList: true, if (document.querySelector(selector)) {
subtree: true observer.disconnect();
fulfill();
return;
}
}).observe(document.documentElement, {
childList: true,
subtree: true
});
}); });
}); return promise;
};
let contextId = undefined; let contextId = undefined;
if (!frame.isMainFrame()) { if (!frame.isMainFrame()) {
contextId = this._frameIdToExecutionContextId.get(frame._id); contextId = this._frameIdToExecutionContextId.get(frame._id);

View File

@ -190,6 +190,17 @@ describe('Puppeteer', function() {
expect(added).toBe(true); 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 = '<h3><div></div></h3>');
expect(added).toBe(true);
}));
it('Page.waitFor is shortcut for main frame', SX(async function() { it('Page.waitFor is shortcut for main frame', SX(async function() {
await page.navigate(EMPTY_PAGE); await page.navigate(EMPTY_PAGE);
await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE); await FrameUtils.attachFrame(page, 'frame1', EMPTY_PAGE);