Added frame.waitFor(selector) (#59)
This patch adds `frame.waitFor(selector)` method. Fixes #42.
This commit is contained in:
parent
a0eeb415f2
commit
090ecfa6b9
10
docs/api.md
10
docs/api.md
@ -36,6 +36,7 @@
|
||||
* [page.url()](#pageurl)
|
||||
* [page.userAgent()](#pageuseragent)
|
||||
* [page.viewportSize()](#pageviewportsize)
|
||||
* [page.waitFor(selector)](#pagewaitforselector)
|
||||
- [class: Dialog](#class-dialog)
|
||||
* [dialog.accept()](#dialogaccept)
|
||||
* [dialog.dismiss()](#dialogdismiss)
|
||||
@ -49,6 +50,7 @@
|
||||
* [frame.parentFrame()](#frameparentframe)
|
||||
* [frame.securityOrigin()](#framesecurityorigin)
|
||||
* [frame.url()](#frameurl)
|
||||
* [frame.waitFor(selector)](#framewaitforselector)
|
||||
- [class: Request](#class-request)
|
||||
* [request.response()](#requestresponse)
|
||||
- [class: Response](#class-response)
|
||||
@ -248,6 +250,9 @@ Pages could be closed by `page.close()` method.
|
||||
- `width` <[number]> Page's width in pixels.
|
||||
- `height` <[number]> Page's height in pixels.
|
||||
|
||||
#### page.waitFor(selector)
|
||||
|
||||
Shortcut for [page.mainFrame().waitFor(selector)](#framewaitforselector).
|
||||
|
||||
### class: Dialog
|
||||
#### dialog.accept()
|
||||
@ -268,6 +273,11 @@ Pages could be closed by `page.close()` method.
|
||||
#### frame.parentFrame()
|
||||
#### frame.securityOrigin()
|
||||
#### frame.url()
|
||||
#### frame.waitFor(selector)
|
||||
|
||||
- `selector` <[string]> CSS selector of awaited element,
|
||||
- returns: <[Promise]> Promise which resolves when element specified by selector string is added to DOM.
|
||||
|
||||
|
||||
### class: Request
|
||||
#### request.response()
|
||||
|
@ -197,6 +197,39 @@ class FrameManager extends EventEmitter {
|
||||
});
|
||||
return response.result.value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @param {!Frame} frame
|
||||
* @return {!Promise<undefined>}
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}).observe(document.documentElement, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
});
|
||||
await this._client.send('Runtime.evaluate', {
|
||||
expression: helper.evaluationString(code, selector),
|
||||
awaitPromise: true,
|
||||
returnByValue: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** @enum {string} */
|
||||
@ -287,6 +320,14 @@ class Frame {
|
||||
return this._detached;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @return {!Promise<undefined>}
|
||||
*/
|
||||
async waitFor(selector) {
|
||||
await this._frameManager._waitForInFrame(selector, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Object} framePayload
|
||||
*/
|
||||
|
@ -561,6 +561,14 @@ class Page extends EventEmitter {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} selector
|
||||
* @return {!Promise<undefined>}
|
||||
*/
|
||||
waitFor(selector) {
|
||||
return this.mainFrame().waitFor(selector);
|
||||
}
|
||||
}
|
||||
|
||||
/** @enum {string} */
|
||||
|
45
test/test.js
45
test/test.js
@ -131,6 +131,51 @@ describe('Puppeteer', function() {
|
||||
}));
|
||||
});
|
||||
|
||||
describe('Frame.waitFor', function() {
|
||||
let FrameUtils = require('./frame-utils');
|
||||
let addElement = tag => document.body.appendChild(document.createElement(tag));
|
||||
|
||||
it('should immediately resolve promise if node exists', SX(async function() {
|
||||
await page.navigate(EMPTY_PAGE);
|
||||
let frame = page.mainFrame();
|
||||
let added = false;
|
||||
await frame.waitFor('*').then(() => added = true);
|
||||
expect(added).toBe(true);
|
||||
|
||||
added = false;
|
||||
await frame.evaluate(addElement, 'div');
|
||||
await frame.waitFor('div').then(() => added = true);
|
||||
expect(added).toBe(true);
|
||||
}));
|
||||
|
||||
it('should resolve promise when node is added', SX(async function() {
|
||||
await page.navigate(EMPTY_PAGE);
|
||||
let frame = page.mainFrame();
|
||||
let added = false;
|
||||
frame.waitFor('div').then(() => added = true);
|
||||
// run nop function..
|
||||
await frame.evaluate(() => 42);
|
||||
// .. to be sure that waitFor promise is not resolved yet.
|
||||
expect(added).toBe(false);
|
||||
await frame.evaluate(addElement, 'br');
|
||||
expect(added).toBe(false);
|
||||
await frame.evaluate(addElement, 'div');
|
||||
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);
|
||||
let otherFrame = page.frames()[1];
|
||||
let added = false;
|
||||
page.waitFor('div').then(() => added = true);
|
||||
await otherFrame.evaluate(addElement, 'div');
|
||||
expect(added).toBe(false);
|
||||
await page.evaluate(addElement, 'div');
|
||||
expect(added).toBe(true);
|
||||
}));
|
||||
});
|
||||
|
||||
it('Page Events: ConsoleMessage', SX(async function() {
|
||||
let msgs = [];
|
||||
page.on('consolemessage', msg => msgs.push(msg));
|
||||
|
Loading…
Reference in New Issue
Block a user