Skip to content

Commit

Permalink
feat: page.waitForTimeout (#6268)
Browse files Browse the repository at this point in the history
  • Loading branch information
jackfranklin committed Jul 28, 2020
1 parent 3a15c06 commit 21552f8
Show file tree
Hide file tree
Showing 12 changed files with 296 additions and 3 deletions.
55 changes: 55 additions & 0 deletions docs/api.md
Expand Up @@ -170,6 +170,7 @@
* [page.waitForRequest(urlOrPredicate[, options])](#pagewaitforrequesturlorpredicate-options)
* [page.waitForResponse(urlOrPredicate[, options])](#pagewaitforresponseurlorpredicate-options)
* [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options)
* [page.waitForTimeout(milliseconds)](#pagewaitfortimeoutmilliseconds)
* [page.waitForXPath(xpath[, options])](#pagewaitforxpathxpath-options)
* [page.workers()](#pageworkers)
* [GeolocationOptions](#geolocationoptions)
Expand Down Expand Up @@ -243,6 +244,7 @@
* [frame.waitForFunction(pageFunction[, options[, ...args]])](#framewaitforfunctionpagefunction-options-args)
* [frame.waitForNavigation([options])](#framewaitfornavigationoptions)
* [frame.waitForSelector(selector[, options])](#framewaitforselectorselector-options)
* [frame.waitForTimeout(milliseconds)](#framewaitfortimeoutmilliseconds)
* [frame.waitForXPath(xpath[, options])](#framewaitforxpathxpath-options)
- [class: ExecutionContext](#class-executioncontext)
* [executionContext.evaluate(pageFunction[, ...args])](#executioncontextevaluatepagefunction-args)
Expand Down Expand Up @@ -2061,6 +2063,13 @@ This is a shortcut for [page.mainFrame().url()](#frameurl)
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
- returns: <[Promise]<[JSHandle]>> Promise which resolves to a JSHandle of the success value

**This method is deprecated**. You should use the more explicit API methods available:

* `page.waitForSelector`
* `page.waitForXPath`
* `page.waitForFunction`
* `page.waitForTimeout`

This method behaves differently with respect to the type of the first parameter:
- if `selectorOrFunctionOrTimeout` is a `string`, then the first argument is treated as a [selector] or [xpath], depending on whether or not it starts with '//', and the method is a shortcut for
[page.waitForSelector](#pagewaitforselectorselector-options) or [page.waitForXPath](#pagewaitforxpathxpath-options)
Expand Down Expand Up @@ -2235,6 +2244,25 @@ const puppeteer = require('puppeteer');
```
Shortcut for [page.mainFrame().waitForSelector(selector[, options])](#framewaitforselectorselector-options).

#### page.waitForTimeout(milliseconds)
- `milliseconds` <[number]> The number of milliseconds to wait for.
- returns: <[Promise]> Promise which resolves after the timeout has completed.

Pauses script execution for the given number of seconds before continuing:

```js
const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.waitForTimeout(1000)
.then(() => console.log('Waited a second!'));

await browser.close();
})();
```

#### page.waitForXPath(xpath[, options])
- `xpath` <[string]> A [xpath] of an element to wait for
- `options` <[Object]> Optional waiting parameters
Expand Down Expand Up @@ -3041,6 +3069,13 @@ Returns frame's url.
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
- returns: <[Promise]<[JSHandle]>> Promise which resolves to a JSHandle of the success value

**This method is deprecated**. You should use the more explicit API methods available:

* `frame.waitForSelector`
* `frame.waitForXPath`
* `frame.waitForFunction`
* `frame.waitForTimeout`

This method behaves differently with respect to the type of the first parameter:
- if `selectorOrFunctionOrTimeout` is a `string`, then the first argument is treated as a [selector] or [xpath], depending on whether or not it starts with '//', and the method is a shortcut for
[frame.waitForSelector](#framewaitforselectorselector-options) or [frame.waitForXPath](#framewaitforxpathxpath-options)
Expand Down Expand Up @@ -3148,6 +3183,26 @@ const puppeteer = require('puppeteer');
})();
```

#### frame.waitForTimeout(milliseconds)
- `milliseconds` <[number]> The number of milliseconds to wait for.
- returns: <[Promise]> Promise which resolves after the timeout has completed.

Pauses script execution for the given number of seconds before continuing:

```js
const puppeteer = require('puppeteer');

(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
page.mainFrame()
.waitForTimeout(1000)
.then(() => console.log('Waited a second!'));

await browser.close();
})();
```

#### frame.waitForXPath(xpath[, options])
- `xpath` <[string]> A [xpath] of an element to wait for
- `options` <[Object]> Optional waiting parameters
Expand Down
1 change: 1 addition & 0 deletions new-docs/puppeteer.frame.md
Expand Up @@ -92,5 +92,6 @@ console.log(text);
| [waitForFunction(pageFunction, options, args)](./puppeteer.frame.waitforfunction.md) | | |
| [waitForNavigation(options)](./puppeteer.frame.waitfornavigation.md) | | |
| [waitForSelector(selector, options)](./puppeteer.frame.waitforselector.md) | | |
| [waitForTimeout(milliseconds)](./puppeteer.frame.waitfortimeout.md) | | Causes your script to wait for the given number of milliseconds. |
| [waitForXPath(xpath, options)](./puppeteer.frame.waitforxpath.md) | | |

5 changes: 5 additions & 0 deletions new-docs/puppeteer.frame.waitfor.md
Expand Up @@ -4,6 +4,11 @@

## Frame.waitFor() method

> Warning: This API is now obsolete.
>
> Don't use this method directly. Instead use the more explicit methods available: [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md)<!-- -->, [Frame.waitForXPath()](./puppeteer.frame.waitforxpath.md)<!-- -->, [Frame.waitForFunction()](./puppeteer.frame.waitforfunction.md) or [Frame.waitForTimeout()](./puppeteer.frame.waitfortimeout.md)<!-- -->.
>
<b>Signature:</b>

```typescript
Expand Down
37 changes: 37 additions & 0 deletions new-docs/puppeteer.frame.waitfortimeout.md
@@ -0,0 +1,37 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [Frame](./puppeteer.frame.md) &gt; [waitForTimeout](./puppeteer.frame.waitfortimeout.md)

## Frame.waitForTimeout() method

Causes your script to wait for the given number of milliseconds.

<b>Signature:</b>

```typescript
waitForTimeout(milliseconds: number): Promise<void>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| milliseconds | number | the number of milliseconds to wait. |

<b>Returns:</b>

Promise&lt;void&gt;

## Remarks

It's generally recommended to not wait for a number of seconds, but instead use [Frame.waitForSelector()](./puppeteer.frame.waitforselector.md)<!-- -->, [Frame.waitForXPath()](./puppeteer.frame.waitforxpath.md) or [Frame.waitForFunction()](./puppeteer.frame.waitforfunction.md) to wait for exactly the conditions you want.

## Example

Wait for 1 second:

```
await frame.waitForTimeout(1000);
```

1 change: 1 addition & 0 deletions new-docs/puppeteer.page.md
Expand Up @@ -138,6 +138,7 @@ page.off('request', logRequest);
| [waitForRequest(urlOrPredicate, options)](./puppeteer.page.waitforrequest.md) | | |
| [waitForResponse(urlOrPredicate, options)](./puppeteer.page.waitforresponse.md) | | |
| [waitForSelector(selector, options)](./puppeteer.page.waitforselector.md) | | |
| [waitForTimeout(milliseconds)](./puppeteer.page.waitfortimeout.md) | | Causes your script to wait for the given number of milliseconds. |
| [waitForXPath(xpath, options)](./puppeteer.page.waitforxpath.md) | | |
| [workers()](./puppeteer.page.workers.md) | | |
19 changes: 16 additions & 3 deletions new-docs/puppeteer.page.waitfor.md
Expand Up @@ -4,6 +4,11 @@

## Page.waitFor() method

> Warning: This API is now obsolete.
>
> Don't use this method directly. Instead use the more explicit methods available: [Page.waitForSelector()](./puppeteer.page.waitforselector.md)<!-- -->, [Page.waitForXPath()](./puppeteer.page.waitforxpath.md)<!-- -->, [Page.waitForFunction()](./puppeteer.page.waitforfunction.md) or [Page.waitForTimeout()](./puppeteer.page.waitfortimeout.md)<!-- -->.
>
<b>Signature:</b>

```typescript
Expand All @@ -19,11 +24,19 @@ waitFor(selectorOrFunctionOrTimeout: string | number | Function, options?: {

| Parameter | Type | Description |
| --- | --- | --- |
| selectorOrFunctionOrTimeout | string \| number \| Function | |
| options | { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string \| number; } | |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | |
| selectorOrFunctionOrTimeout | string \| number \| Function | a selector, predicate or timeout to wait for. |
| options | { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string \| number; } | optional waiting parameters. |
| args | [SerializableOrJSHandle](./puppeteer.serializableorjshandle.md)<!-- -->\[\] | arguments to pass to <code>pageFunction</code>. |

<b>Returns:</b>

Promise&lt;[JSHandle](./puppeteer.jshandle.md)<!-- -->&gt;

## Remarks

This method behaves differently depending on the first parameter. If it's a `string`<!-- -->, it will be treated as a `selector` or `xpath` (if the string starts with `//`<!-- -->). This method then is a shortcut for [Page.waitForSelector()](./puppeteer.page.waitforselector.md) or [Page.waitForXPath()](./puppeteer.page.waitforxpath.md)<!-- -->.

If the first argument is a function this method is a shortcut for [Page.waitForFunction()](./puppeteer.page.waitforfunction.md)<!-- -->.

If the first argument is a `number`<!-- -->, it's treated as a timeout in milliseconds and the method returns a promise which resolves after the timeout.

37 changes: 37 additions & 0 deletions new-docs/puppeteer.page.waitfortimeout.md
@@ -0,0 +1,37 @@
<!-- Do not edit this file. It is automatically generated by API Documenter. -->

[Home](./index.md) &gt; [puppeteer](./puppeteer.md) &gt; [Page](./puppeteer.page.md) &gt; [waitForTimeout](./puppeteer.page.waitfortimeout.md)

## Page.waitForTimeout() method

Causes your script to wait for the given number of milliseconds.

<b>Signature:</b>

```typescript
waitForTimeout(milliseconds: number): Promise<void>;
```

## Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| milliseconds | number | the number of milliseconds to wait. |

<b>Returns:</b>

Promise&lt;void&gt;

## Remarks

It's generally recommended to not wait for a number of seconds, but instead use [Page.waitForSelector()](./puppeteer.page.waitforselector.md)<!-- -->, [Page.waitForXPath()](./puppeteer.page.waitforxpath.md) or [Page.waitForFunction()](./puppeteer.page.waitforfunction.md) to wait for exactly the conditions you want.

## Example

Wait for 1 second:

```
await page.waitForTimeout(1000);
```

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -67,6 +67,7 @@
"@types/node": "^14.0.13",
"@types/proxy-from-env": "^1.0.1",
"@types/rimraf": "^2.0.2",
"@types/sinon": "^9.0.4",
"@types/tar-fs": "^1.16.2",
"@types/ws": "^7.2.4",
"@typescript-eslint/eslint-plugin": "^2.28.0",
Expand Down
33 changes: 33 additions & 0 deletions src/common/FrameManager.ts
Expand Up @@ -1035,6 +1035,11 @@ export class Frame {
* wait for.
* @param options - optional waiting parameters.
* @param args - arguments to pass to `pageFunction`.
*
* @deprecated Don't use this method directly. Instead use the more explicit
* methods available: {@link Frame.waitForSelector},
* {@link Frame.waitForXPath}, {@link Frame.waitForFunction} or
* {@link Frame.waitForTimeout}.
*/
waitFor(
selectorOrFunctionOrTimeout: string | number | Function,
Expand All @@ -1043,6 +1048,10 @@ export class Frame {
): Promise<JSHandle | null> {
const xPathPattern = '//';

console.warn(
'waitFor is deprecated and will be removed in a future release. See https://github.com/puppeteer/puppeteer/issues/6214 for details and how to migrate your code.'
);

if (helper.isString(selectorOrFunctionOrTimeout)) {
const string = selectorOrFunctionOrTimeout;
if (string.startsWith(xPathPattern))
Expand All @@ -1066,6 +1075,30 @@ export class Frame {
);
}

/**
* Causes your script to wait for the given number of milliseconds.
*
* @remarks
* It's generally recommended to not wait for a number of seconds, but instead
* use {@link Frame.waitForSelector}, {@link Frame.waitForXPath} or
* {@link Frame.waitForFunction} to wait for exactly the conditions you want.
*
* @example
*
* Wait for 1 second:
*
* ```
* await frame.waitForTimeout(1000);
* ```
*
* @param milliseconds - the number of milliseconds to wait.
*/
waitForTimeout(milliseconds: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, milliseconds);
});
}

/**
* @remarks
*
Expand Down
48 changes: 48 additions & 0 deletions src/common/Page.ts
Expand Up @@ -1857,6 +1857,31 @@ export class Page extends EventEmitter {
return this.mainFrame().type(selector, text, options);
}

/**
* @remarks
*
* This method behaves differently depending on the first parameter. If it's a
* `string`, it will be treated as a `selector` or `xpath` (if the string
* starts with `//`). This method then is a shortcut for
* {@link Page.waitForSelector} or {@link Page.waitForXPath}.
*
* If the first argument is a function this method is a shortcut for
* {@link Page.waitForFunction}.
*
* If the first argument is a `number`, it's treated as a timeout in
* milliseconds and the method returns a promise which resolves after the
* timeout.
*
* @param selectorOrFunctionOrTimeout - a selector, predicate or timeout to
* wait for.
* @param options - optional waiting parameters.
* @param args - arguments to pass to `pageFunction`.
*
* @deprecated Don't use this method directly. Instead use the more explicit
* methods available: {@link Page.waitForSelector},
* {@link Page.waitForXPath}, {@link Page.waitForFunction} or
* {@link Page.waitForTimeout}.
*/
waitFor(
selectorOrFunctionOrTimeout: string | number | Function,
options: {
Expand All @@ -1874,6 +1899,29 @@ export class Page extends EventEmitter {
);
}

/**
* Causes your script to wait for the given number of milliseconds.
*
* @remarks
*
* It's generally recommended to not wait for a number of seconds, but instead
* use {@link Page.waitForSelector}, {@link Page.waitForXPath} or
* {@link Page.waitForFunction} to wait for exactly the conditions you want.
*
* @example
*
* Wait for 1 second:
*
* ```
* await page.waitForTimeout(1000);
* ```
*
* @param milliseconds - the number of milliseconds to wait.
*/
waitForTimeout(milliseconds: number): Promise<void> {
return this.mainFrame().waitForTimeout(milliseconds);
}

waitForSelector(
selector: string,
options: {
Expand Down
4 changes: 4 additions & 0 deletions test/elementhandle.spec.ts
Expand Up @@ -15,6 +15,7 @@
*/

import expect from 'expect';
import sinon from 'sinon';
import {
getTestState,
setupTestBrowserHooks,
Expand Down Expand Up @@ -388,7 +389,10 @@ describe('ElementHandle specs', function () {

expect(element).toBeDefined();
});

it('should wait correctly with waitFor', async () => {
/* page.waitFor is deprecated so we silence the warning to avoid test noise */
sinon.stub(console, 'warn').callsFake(() => {});
const { page, puppeteer } = getTestState();
puppeteer.__experimental_registerCustomQueryHandler('getByClass', {
queryOne: (element, selector) => element.querySelector(`.${selector}`),
Expand Down

0 comments on commit 21552f8

Please sign in to comment.