Implement function as a part of a page.waitFor shortcut

This patch adds a function as a possible argument to
page.waitFor shortcut.

Fixes #91.
This commit is contained in:
Andrey Lushnikov 2017-07-27 17:09:28 -07:00
parent ff5ed1c738
commit bd898b7f56
4 changed files with 34 additions and 25 deletions

View File

@ -58,7 +58,7 @@
+ [page.uploadFile(selector, ...filePaths)](#pageuploadfileselector-filepaths) + [page.uploadFile(selector, ...filePaths)](#pageuploadfileselector-filepaths)
+ [page.url()](#pageurl) + [page.url()](#pageurl)
+ [page.viewport()](#pageviewport) + [page.viewport()](#pageviewport)
+ [page.waitFor(selectorOrTimeout[, options])](#pagewaitforselectorortimeout-options) + [page.waitFor(selectorOrFunctionOrTimeout[, options])](#pagewaitforselectororfunctionortimeout-options)
+ [page.waitForFunction(pageFunction[, options], ...args)](#pagewaitforfunctionpagefunction-options-args) + [page.waitForFunction(pageFunction[, options], ...args)](#pagewaitforfunctionpagefunction-options-args)
+ [page.waitForNavigation(options)](#pagewaitfornavigationoptions) + [page.waitForNavigation(options)](#pagewaitfornavigationoptions)
+ [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options) + [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options)
@ -91,7 +91,7 @@
+ [frame.parentFrame()](#frameparentframe) + [frame.parentFrame()](#frameparentframe)
+ [frame.title()](#frametitle) + [frame.title()](#frametitle)
+ [frame.url()](#frameurl) + [frame.url()](#frameurl)
+ [frame.waitFor(selectorOrTimeout[, options])](#framewaitforselectorortimeout-options) + [frame.waitFor(selectorOrFunctionOrTimeout[, options])](#framewaitforselectororfunctionortimeout-options)
+ [frame.waitForFunction(pageFunction[, options], ...args)](#framewaitforfunctionpagefunction-options-args) + [frame.waitForFunction(pageFunction[, options], ...args)](#framewaitforfunctionpagefunction-options-args)
+ [frame.waitForSelector(selector[, options])](#framewaitforselectorselector-options) + [frame.waitForSelector(selector[, options])](#framewaitforselectorselector-options)
* [class: Request](#class-request) * [class: Request](#class-request)
@ -641,16 +641,17 @@ This is a shortcut for [page.mainFrame().url()](#frameurl)
#### page.viewport() #### page.viewport()
- returns: <[Object]> An object with the save fields as described in [page.setViewport](#pagesetviewportviewport) - returns: <[Object]> An object with the save fields as described in [page.setViewport](#pagesetviewportviewport)
#### page.waitFor(selectorOrTimeout[, options]) #### page.waitFor(selectorOrFunctionOrTimeout[, options])
- `selectorOrTimeout` <[string]|[number]> A [selector] or timeout to wait for - `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
- `options` <[Object]> Optional waiting parameters - `options` <[Object]> Optional waiting parameters
- `visible` <[boolean]> wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds).
- returns: <[Promise]> - returns: <[Promise]>
This is a shortcut method for [frame.waitForSelector](#framewaitforselectorselector-options) or [page.mainFrame().waitForFunction()](#framewaitforfunctionpagefunction-options-args).
This method behaves differently with respect to the type of the first parameter: This method behaves differently with respect to the type of the first parameter:
- if `selectorOrTimeout` is a `string`, than the first argument is treated as a [selector] to wait for and the method is a shortcut for [frame.waitForSelector](#framewaitforselectorselector-options) - if `selectorOrFunctionOrTimeout` is a `string`, than the first argument is treated as a [selector] to wait for and the method is a shortcut for [frame.waitForSelector](#framewaitforselectorselector-options)
- if `selectorOrTimeout` is a `number`, than the first argument is treated as a timeout in milliseconds and the method returns a promise which resolves after the timeout - if `selectorOrFunctionOrTimeout` is a `function`, than the first argument is treated as a predicate to wait for and the method is a shortcut for [frame.waitForFunction()](#framewaitforfunctionpagefunction-options-args).
- if `selectorOrFunctionOrTimeout` is a `number`, than the first argument is treated as a timeout in milliseconds and the method returns a promise which resolves after the timeout
- otherwise, an exception is thrown - otherwise, an exception is thrown
The method is a shortcut for [page.mainFrame().waitFor()](#framewaitforselectorortimeout-options). The method is a shortcut for [page.mainFrame().waitFor()](#framewaitforselectorortimeout-options).
@ -904,16 +905,17 @@ Note: This value is calculated once when the frame is created, and will not upda
Returns frame's url. Returns frame's url.
#### frame.waitFor(selectorOrTimeout[, options]) #### frame.waitFor(selectorOrFunctionOrTimeout[, options])
- `selectorOrTimeout` <[string]|[number]> A [selector] or timeout to wait for - `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
- `options` <[Object]> Optional waiting parameters - `options` <[Object]> Optional waiting parameters
- `visible` <[boolean]> wait for element to be present in DOM and to be visible, i.e. to not have `display: none` or `visibility: hidden` CSS properties. Defaults to `false`.
- `timeout` <[number]> maximum time to wait for in milliseconds. Defaults to `30000` (30 seconds).
- returns: <[Promise]> - returns: <[Promise]>
This is a shortcut method for [frame.waitForSelector](#framewaitforselectorselector-options) or [page.mainFrame().waitForFunction()](#framewaitforfunctionpagefunction-options-args).
This method behaves differently with respect to the type of the first parameter: This method behaves differently with respect to the type of the first parameter:
- if `selectorOrTimeout` is a `string`, than the first argument is treated as a [selector] to wait for and the method is a shortcut for [frame.waitForSelector](#framewaitforselectorselectoroptions) - if `selectorOrFunctionOrTimeout` is a `string`, than the first argument is treated as a [selector] to wait for and the method is a shortcut for [frame.waitForSelector](#framewaitforselectorselector-options)
- if `selectorOrTimeout` is a `number`, than the first argument is treated as a timeout in milliseconds and the method returns a promise which resolves after the timeout - if `selectorOrFunctionOrTimeout` is a `function`, than the first argument is treated as a predicate to wait for and the method is a shortcut for [frame.waitForFunction()](#framewaitforfunctionpagefunction-options-args).
- if `selectorOrFunctionOrTimeout` is a `number`, than the first argument is treated as a timeout in milliseconds and the method returns a promise which resolves after the timeout
- otherwise, an exception is thrown - otherwise, an exception is thrown
#### frame.waitForFunction(pageFunction[, options], ...args) #### frame.waitForFunction(pageFunction[, options], ...args)

View File

@ -270,16 +270,18 @@ class Frame {
} }
/** /**
* @param {(string|number)} selectorOrTimeout * @param {(string|number|function())} selectorOrTimeout
* @param {!Object=} options * @param {!Object=} options
* @return {!Promise} * @return {!Promise}
*/ */
waitFor(selectorOrTimeout, options = {}) { waitFor(selectorOrFunctionOrTimeout, options = {}) {
if (helper.isString(selectorOrTimeout)) if (helper.isString(selectorOrFunctionOrTimeout))
return this.waitForSelector(selectorOrTimeout, options); return this.waitForSelector(selectorOrFunctionOrTimeout, options);
if (helper.isNumber(selectorOrTimeout)) if (helper.isNumber(selectorOrFunctionOrTimeout))
return new Promise(fulfill => setTimeout(fulfill, selectorOrTimeout)); return new Promise(fulfill => setTimeout(fulfill, selectorOrFunctionOrTimeout));
return Promise.reject(new Error('Unsupported target type: ' + (typeof selectorOrTimeout))); if (typeof selectorOrFunctionOrTimeout === 'function')
return this.waitForFunction(selectorOrFunctionOrTimeout, options);
return Promise.reject(new Error('Unsupported target type: ' + (typeof selectorOrFunctionOrTimeout)));
} }
/** /**

View File

@ -554,12 +554,12 @@ class Page extends EventEmitter {
} }
/** /**
* @param {string} selectorOrTimeout * @param {(string|number|function())} selectorOrTimeout
* @param {!Object=} options * @param {!Object=} options
* @return {!Promise<undefined>} * @return {!Promise}
*/ */
waitFor(selectorOrTimeout, options) { waitFor(selectorOrFunctionOrTimeout, options = {}) {
return this.mainFrame().waitFor(selectorOrTimeout, options); return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options);
} }
/** /**

View File

@ -388,6 +388,11 @@ describe('Puppeteer', function() {
await page.waitFor(timeout); await page.waitFor(timeout);
expect(Date.now() - startTime).not.toBeLessThan(timeout / 2); expect(Date.now() - startTime).not.toBeLessThan(timeout / 2);
})); }));
it('should wait for predicate', SX(async function() {
const watchdog = page.waitFor(() => window.innerWidth < 100);
page.setViewport({width: 10, height: 10});
await watchdog;
}));
it('should throw when unknown type', SX(async function() { it('should throw when unknown type', SX(async function() {
try { try {
await page.waitFor({foo: 'bar'}); await page.waitFor({foo: 'bar'});