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 => {
let promise = new Promise(fulfill => {
if (document.querySelector(selector)) { if (document.querySelector(selector)) {
fulfill(); fulfill();
return; return;
} }
new MutationObserver((mutations, observer) => { new MutationObserver((mutations, observer) => {
for (let mutation of mutations) { if (document.querySelector(selector)) {
for (let node of mutation.addedNodes) {
if (node.matches(selector)) {
observer.disconnect(); observer.disconnect();
fulfill(); fulfill();
return; return;
} }
}
}
}).observe(document.documentElement, { }).observe(document.documentElement, {
childList: true, childList: true,
subtree: 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);