diff --git a/docs/api.md b/docs/api.md
index cd4a8238..abde2d16 100644
--- a/docs/api.md
+++ b/docs/api.md
@@ -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)
@@ -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)
@@ -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)
@@ -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
@@ -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)
@@ -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
diff --git a/new-docs/puppeteer.frame.md b/new-docs/puppeteer.frame.md
index 314181e4..49903e86 100644
--- a/new-docs/puppeteer.frame.md
+++ b/new-docs/puppeteer.frame.md
@@ -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) | | |
diff --git a/new-docs/puppeteer.frame.waitfor.md b/new-docs/puppeteer.frame.waitfor.md
index a38d2341..6e079601 100644
--- a/new-docs/puppeteer.frame.waitfor.md
+++ b/new-docs/puppeteer.frame.waitfor.md
@@ -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).
+>
+
Signature:
```typescript
diff --git a/new-docs/puppeteer.frame.waitfortimeout.md b/new-docs/puppeteer.frame.waitfortimeout.md
new file mode 100644
index 00000000..71dd1075
--- /dev/null
+++ b/new-docs/puppeteer.frame.waitfortimeout.md
@@ -0,0 +1,37 @@
+
+
+[Home](./index.md) > [puppeteer](./puppeteer.md) > [Frame](./puppeteer.frame.md) > [waitForTimeout](./puppeteer.frame.waitfortimeout.md)
+
+## Frame.waitForTimeout() method
+
+Causes your script to wait for the given number of milliseconds.
+
+Signature:
+
+```typescript
+waitForTimeout(milliseconds: number): Promise;
+```
+
+## Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| milliseconds | number | the number of milliseconds to wait. |
+
+Returns:
+
+Promise<void>
+
+## 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);
+
+```
+
diff --git a/new-docs/puppeteer.page.md b/new-docs/puppeteer.page.md
index 6b23980d..2530230a 100644
--- a/new-docs/puppeteer.page.md
+++ b/new-docs/puppeteer.page.md
@@ -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) | | |
diff --git a/new-docs/puppeteer.page.waitfor.md b/new-docs/puppeteer.page.waitfor.md
index e808df9a..8cd12e5a 100644
--- a/new-docs/puppeteer.page.waitfor.md
+++ b/new-docs/puppeteer.page.waitfor.md
@@ -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).
+>
+
Signature:
```typescript
@@ -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 pageFunction
. |
Returns:
Promise<[JSHandle](./puppeteer.jshandle.md)>
+## 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.
+
diff --git a/new-docs/puppeteer.page.waitfortimeout.md b/new-docs/puppeteer.page.waitfortimeout.md
new file mode 100644
index 00000000..1b74ebb6
--- /dev/null
+++ b/new-docs/puppeteer.page.waitfortimeout.md
@@ -0,0 +1,37 @@
+
+
+[Home](./index.md) > [puppeteer](./puppeteer.md) > [Page](./puppeteer.page.md) > [waitForTimeout](./puppeteer.page.waitfortimeout.md)
+
+## Page.waitForTimeout() method
+
+Causes your script to wait for the given number of milliseconds.
+
+Signature:
+
+```typescript
+waitForTimeout(milliseconds: number): Promise;
+```
+
+## Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| milliseconds | number | the number of milliseconds to wait. |
+
+Returns:
+
+Promise<void>
+
+## 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);
+
+```
+
diff --git a/package.json b/package.json
index 5ce4ed5a..7358a4c9 100644
--- a/package.json
+++ b/package.json
@@ -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",
diff --git a/src/common/FrameManager.ts b/src/common/FrameManager.ts
index 491b6bba..640b47a1 100644
--- a/src/common/FrameManager.ts
+++ b/src/common/FrameManager.ts
@@ -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,
@@ -1043,6 +1048,10 @@ export class Frame {
): Promise {
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))
@@ -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 {
+ return new Promise((resolve) => {
+ setTimeout(resolve, milliseconds);
+ });
+ }
+
/**
* @remarks
*
diff --git a/src/common/Page.ts b/src/common/Page.ts
index 4103862d..211b1bcb 100644
--- a/src/common/Page.ts
+++ b/src/common/Page.ts
@@ -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: {
@@ -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 {
+ return this.mainFrame().waitForTimeout(milliseconds);
+ }
+
waitForSelector(
selector: string,
options: {
diff --git a/test/elementhandle.spec.ts b/test/elementhandle.spec.ts
index 63f06535..424b71ac 100644
--- a/test/elementhandle.spec.ts
+++ b/test/elementhandle.spec.ts
@@ -15,6 +15,7 @@
*/
import expect from 'expect';
+import sinon from 'sinon';
import {
getTestState,
setupTestBrowserHooks,
@@ -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}`),
diff --git a/test/waittask.spec.ts b/test/waittask.spec.ts
index 73bfae40..d81875b9 100644
--- a/test/waittask.spec.ts
+++ b/test/waittask.spec.ts
@@ -15,6 +15,7 @@
*/
import utils from './utils.js';
+import sinon from 'sinon';
import expect from 'expect';
import {
getTestState,
@@ -28,6 +29,12 @@ describe('waittask specs', function () {
setupTestPageAndContextHooks();
describe('Page.waitFor', function () {
+ /* This method is deprecated but we don't want the warnings showing up in
+ * tests. Until we remove this method we still want to ensure we don't break
+ * it.
+ */
+ beforeEach(() => sinon.stub(console, 'warn').callsFake(() => {}));
+
it('should wait for selector', async () => {
const { page, server } = getTestState();
@@ -96,6 +103,22 @@ describe('waittask specs', function () {
await page.waitFor((arg1, arg2) => arg1 !== arg2, {}, 1, 2);
});
+
+ it('should log a deprecation warning', async () => {
+ const { page } = getTestState();
+
+ await page.waitFor(() => true);
+
+ const consoleWarnStub = console.warn as sinon.SinonSpy;
+
+ expect(consoleWarnStub.calledOnce).toBe(true);
+ expect(
+ consoleWarnStub.firstCall.calledWith(
+ '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.'
+ )
+ ).toBe(true);
+ expect((console.warn as sinon.SinonSpy).calledOnce).toBe(true);
+ });
});
describe('Frame.waitForFunction', function () {
@@ -329,6 +352,41 @@ describe('waittask specs', function () {
});
});
+ describe('Page.waitForTimeout', () => {
+ it('waits for the given timeout before resolving', async () => {
+ const { page, server } = getTestState();
+ await page.goto(server.EMPTY_PAGE);
+ const startTime = Date.now();
+ await page.waitForTimeout(1000);
+ const endTime = Date.now();
+ /* In a perfect world endTime - startTime would be exactly 1000 but we
+ * expect some fluctuations and for it to be off by a little bit. So to
+ * avoid a flaky test we'll make sure it waited for roughly 1 second by
+ * ensuring 900 < endTime - startTime < 1100
+ */
+ expect(endTime - startTime).toBeGreaterThan(900);
+ expect(endTime - startTime).toBeLessThan(1100);
+ });
+ });
+
+ describe('Frame.waitForTimeout', () => {
+ it('waits for the given timeout before resolving', async () => {
+ const { page, server } = getTestState();
+ await page.goto(server.EMPTY_PAGE);
+ const frame = page.mainFrame();
+ const startTime = Date.now();
+ await frame.waitForTimeout(1000);
+ const endTime = Date.now();
+ /* In a perfect world endTime - startTime would be exactly 1000 but we
+ * expect some fluctuations and for it to be off by a little bit. So to
+ * avoid a flaky test we'll make sure it waited for roughly 1 second by
+ * ensuring 900 < endTime - startTime < 1100
+ */
+ expect(endTime - startTime).toBeGreaterThan(900);
+ expect(endTime - startTime).toBeLessThan(1100);
+ });
+ });
+
describe('Frame.waitForSelector', function () {
const addElement = (tag) =>
document.body.appendChild(document.createElement(tag));