chore: add custom rule for formatting comments (#8777)

This commit is contained in:
jrandolf 2022-08-12 14:15:26 +02:00 committed by GitHub
parent 73221042db
commit ddbe88b887
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 2613 additions and 2318 deletions

95
.eslintplugin.js Normal file
View File

@ -0,0 +1,95 @@
const prettier = require('prettier');
const cleanupBlockComment = value => {
return value
.trim()
.split('\n')
.map(value => {
value = value.trim();
if (value.startsWith('*')) {
value = value.slice(1);
if (value.startsWith(' ')) {
value = value.slice(1);
}
}
return value.trimEnd();
})
.join('\n')
.trim();
};
const format = (value, offset, prettierOptions) => {
return prettier
.format(value, {
...prettierOptions,
// This is the print width minus 3 (the length of ` * `) and the offset.
printWidth: prettierOptions.printWidth - (offset + 3),
})
.trim();
};
const buildBlockComment = (value, offset) => {
const spaces = ' '.repeat(offset);
const lines = value.split('\n').map(line => {
return ` * ${line}`;
});
lines.unshift('/**');
lines.push(' */');
lines.forEach((line, i) => {
lines[i] = `${spaces}${line}`;
});
return lines.join('\n');
};
/**
* @type import("eslint").Rule.RuleModule
*/
const rule = {
meta: {
type: 'suggestion',
docs: {
description: 'Enforce Prettier formatting on comments',
recommended: false,
},
fixable: 'code',
schema: [],
messages: {},
},
create(context) {
const prettierOptions = {
printWidth: 80,
...prettier.resolveConfig.sync(context.getPhysicalFilename()),
parser: 'markdown',
};
for (const comment of context.getSourceCode().getAllComments()) {
switch (comment.type) {
case 'Block': {
const offset = comment.loc.start.column;
const value = cleanupBlockComment(comment.value);
const formattedValue = format(value, offset, prettierOptions);
if (formattedValue !== value) {
context.report({
node: comment,
message: `Comment is not formatted correctly.`,
fix(fixer) {
return fixer.replaceText(
comment,
buildBlockComment(formattedValue, offset).trimStart()
);
},
});
}
break;
}
}
}
return {};
},
};
module.exports = {
rules: {
'prettier-comments': rule,
},
};

View File

@ -1,12 +1,3 @@
// TODO: Enable this at some point.
// const RESTRICTED_UNDERSCORED_IDENTIFIERS = [
// 'PropertyDefinition > Identifier[name=/^_[a-z].*$/]',
// ].map((selector) => ({
// selector,
// message:
// 'Use private fields (fields prefixed with #) and an appropriate getter/setter.',
// }));
module.exports = { module.exports = {
root: true, root: true,
env: { env: {
@ -132,8 +123,10 @@ module.exports = {
'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/eslint-recommended',
'plugin:@typescript-eslint/recommended', 'plugin:@typescript-eslint/recommended',
], ],
plugins: ['eslint-plugin-tsdoc'], plugins: ['eslint-plugin-tsdoc', 'local'],
rules: { rules: {
// Keeps comments formatted.
'local/prettier-comments': 2,
// Brackets keep code readable. // Brackets keep code readable.
curly: [2, 'all'], curly: [2, 'all'],
// Brackets keep code readable and `return` intentions clear. // Brackets keep code readable and `return` intentions clear.
@ -189,9 +182,6 @@ module.exports = {
selector: "CallExpression[callee.name='require']", selector: "CallExpression[callee.name='require']",
message: '`require` statements are not allowed. Use `import`.', message: '`require` statements are not allowed. Use `import`.',
}, },
// Don't allow underscored declarations on camelCased variables/properties.
// ...RESTRICTED_UNDERSCORED_IDENTIFIERS,
], ],
}, },
}, },

View File

@ -28,7 +28,7 @@ An AXNode object representing the snapshot.
## Remarks ## Remarks
\*\*NOTE\*\* The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers. Puppeteer will discard them as well for an easier to process tree, unless `interestingOnly` is set to `false`. **NOTE** The Chromium accessibility tree contains nodes that go unused on most platforms and by most screen readers. Puppeteer will discard them as well for an easier to process tree, unless `interestingOnly` is set to `false`.
## Example 1 ## Example 1

View File

@ -30,7 +30,7 @@ const browser = await puppeteer.launch({
}); });
``` ```
\*\*NOTE\*\* BrowserFetcher is not designed to work concurrently with other instances of BrowserFetcher that share the same downloads directory. **NOTE** BrowserFetcher is not designed to work concurrently with other instances of BrowserFetcher that share the same downloads directory.
## Methods ## Methods

View File

@ -29,4 +29,4 @@ Promise<void>
If `key` is a single character and no modifier keys besides `Shift` are being held down, a `keypress`/`input` event will also be generated. The `text` option can be specified to force an input event to be generated. If `key` is a single character and no modifier keys besides `Shift` are being held down, a `keypress`/`input` event will also be generated. The `text` option can be specified to force an input event to be generated.
\*\*NOTE\*\* Modifier keys DO affect `elementHandle.press`. Holding down `Shift` will type the text in upper case. **NOTE** Modifier keys DO affect `elementHandle.press`. Holding down `Shift` will type the text in upper case.

View File

@ -24,4 +24,4 @@ Throws if the object cannot be serialized due to circularity.
## Remarks ## Remarks
If the object has a `toJSON` function, it \*will not\* be called. If the object has a `toJSON` function, it **will not** be called.

View File

@ -31,7 +31,7 @@ await page.mouse.move(0, 0);
await page.mouse.up(); await page.mouse.up();
``` ```
\*\*Note\*\*: The mouse events trigger synthetic `MouseEvent`s. This means that it does not fully replicate the functionality of what a normal user would be able to do with their mouse. **Note**: The mouse events trigger synthetic `MouseEvent`s. This means that it does not fully replicate the functionality of what a normal user would be able to do with their mouse.
For example, dragging and selecting text is not possible using `page.mouse`. Instead, you can use the [\`DocumentOrShadowRoot.getSelection()\`](https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/getSelection) functionality implemented in the platform. For example, dragging and selecting text is not possible using `page.mouse`. Instead, you can use the [\`DocumentOrShadowRoot.getSelection()\`](https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/getSelection) functionality implemented in the platform.
@ -67,7 +67,7 @@ await page.evaluate(() => {
}); });
``` ```
\*\*Note\*\*: If you want access to the clipboard API, you have to give it permission to do so: **Note**: If you want access to the clipboard API, you have to give it permission to do so:
```ts ```ts
await browser await browser

View File

@ -40,7 +40,9 @@ The argument `options` might have the following properties:
- `referer` : Referer header value. If provided it will take preference over the referer header value set by [page.setExtraHTTPHeaders()](./puppeteer.page.setextrahttpheaders.md). - `referer` : Referer header value. If provided it will take preference over the referer header value set by [page.setExtraHTTPHeaders()](./puppeteer.page.setextrahttpheaders.md).
`page.goto` will throw an error if: - there's an SSL error (e.g. in case of self-signed certificates). - target URL is invalid. - the timeout is exceeded during navigation. - the remote server does not respond or is unreachable. - the main resource failed to load. `page.goto` will throw an error if:
- there's an SSL error (e.g. in case of self-signed certificates). - target URL is invalid. - the timeout is exceeded during navigation. - the remote server does not respond or is unreachable. - the main resource failed to load.
`page.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling response.status(). `page.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling response.status().

View File

@ -27,9 +27,9 @@ class Page {
## Parameters ## Parameters
| Parameter | Type | Description | | Parameter | Type | Description |
| ------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| pageFunction | Func \| string | Function to be evaluated in browser context | | pageFunction | Func \| string | Function to be evaluated in browser context |
| options | { timeout?: number; polling?: string \| number; } | <i>(Optional)</i> Optional waiting parameters - <code>polling</code> - An interval at which the <code>pageFunction</code> is executed, defaults to <code>raf</code>. If <code>polling</code> is a number, then it is treated as an interval in milliseconds at which the function would be executed. If polling is a string, then it can be one of the following values: - <code>raf</code> - to constantly execute <code>pageFunction</code> in <code>requestAnimationFrame</code> callback. This is the tightest polling mode which is suitable to observe styling changes. - <code>mutation</code>- to execute pageFunction on every DOM mutation. - <code>timeout</code> - maximum time to wait for in milliseconds. Defaults to <code>30000</code> (30 seconds). Pass <code>0</code> to disable timeout. The default value can be changed by using the [Page.setDefaultTimeout()](./puppeteer.page.setdefaulttimeout.md) method. | | options | { timeout?: number; polling?: string \| number; } | <p><i>(Optional)</i> Optional waiting parameters</p><p>- <code>polling</code> - An interval at which the <code>pageFunction</code> is executed, defaults to <code>raf</code>. If <code>polling</code> is a number, then it is treated as an interval in milliseconds at which the function would be executed. If polling is a string, then it can be one of the following values: - <code>raf</code> - to constantly execute <code>pageFunction</code> in <code>requestAnimationFrame</code> callback. This is the tightest polling mode which is suitable to observe styling changes. - <code>mutation</code>- to execute pageFunction on every DOM mutation. - <code>timeout</code> - maximum time to wait for in milliseconds. Defaults to <code>30000</code> (30 seconds). Pass <code>0</code> to disable timeout. The default value can be changed by using the [Page.setDefaultTimeout()](./puppeteer.page.setdefaulttimeout.md) method.</p> |
| args | Params | Arguments to pass to <code>pageFunction</code> | | args | Params | Arguments to pass to <code>pageFunction</code> |
**Returns:** **Returns:**

View File

@ -24,7 +24,9 @@ class Page {
Promise&lt;[HTTPResponse](./puppeteer.httpresponse.md) \| null&gt; Promise&lt;[HTTPResponse](./puppeteer.httpresponse.md) \| null&gt;
A `Promise` which resolves to the main resource response. - In case of multiple redirects, the navigation will resolve with the response of the last redirect. - In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`. A `Promise` which resolves to the main resource response.
- In case of multiple redirects, the navigation will resolve with the response of the last redirect. - In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with `null`.
## Remarks ## Remarks

View File

@ -19,7 +19,9 @@ export declare type PaperFormat =
## Remarks ## Remarks
The sizes of each format are as follows: - `Letter`: 8.5in x 11in The sizes of each format are as follows:
- `Letter`: 8.5in x 11in
- `Legal`: 8.5in x 14in - `Legal`: 8.5in x 14in

View File

@ -4,7 +4,9 @@ sidebar_label: PDFOptions.headerTemplate
# PDFOptions.headerTemplate property # PDFOptions.headerTemplate property
HTML template for the print header. Should be valid HTML with the following classes used to inject values into them: - `date` formatted print date HTML template for the print header. Should be valid HTML with the following classes used to inject values into them:
- `date` formatted print date
- `title` document title - `title` document title

View File

@ -15,11 +15,11 @@ export interface PDFOptions
## Properties ## Properties
| Property | Modifiers | Type | Description | | Property | Modifiers | Type | Description |
| --------------------------------------------------------------------- | --------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | --------------------------------------------------------------------- | --------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [displayHeaderFooter?](./puppeteer.pdfoptions.displayheaderfooter.md) | | boolean | <i>(Optional)</i> Whether to show the header and footer. | | [displayHeaderFooter?](./puppeteer.pdfoptions.displayheaderfooter.md) | | boolean | <i>(Optional)</i> Whether to show the header and footer. |
| [footerTemplate?](./puppeteer.pdfoptions.footertemplate.md) | | string | <i>(Optional)</i> HTML template for the print footer. Has the same constraints and support for special classes as [PDFOptions.headerTemplate](./puppeteer.pdfoptions.headertemplate.md). | | [footerTemplate?](./puppeteer.pdfoptions.footertemplate.md) | | string | <i>(Optional)</i> HTML template for the print footer. Has the same constraints and support for special classes as [PDFOptions.headerTemplate](./puppeteer.pdfoptions.headertemplate.md). |
| [format?](./puppeteer.pdfoptions.format.md) | | [PaperFormat](./puppeteer.paperformat.md) | <i>(Optional)</i> | | [format?](./puppeteer.pdfoptions.format.md) | | [PaperFormat](./puppeteer.paperformat.md) | <i>(Optional)</i> |
| [headerTemplate?](./puppeteer.pdfoptions.headertemplate.md) | | string | <p><i>(Optional)</i> HTML template for the print header. Should be valid HTML with the following classes used to inject values into them: - <code>date</code> formatted print date</p><p>- <code>title</code> document title</p><p>- <code>url</code> document location</p><p>- <code>pageNumber</code> current page number</p><p>- <code>totalPages</code> total pages in the document</p> | | [headerTemplate?](./puppeteer.pdfoptions.headertemplate.md) | | string | <p><i>(Optional)</i> HTML template for the print header. Should be valid HTML with the following classes used to inject values into them:</p><p>- <code>date</code> formatted print date</p><p>- <code>title</code> document title</p><p>- <code>url</code> document location</p><p>- <code>pageNumber</code> current page number</p><p>- <code>totalPages</code> total pages in the document</p> |
| [height?](./puppeteer.pdfoptions.height.md) | | string \| number | <i>(Optional)</i> Sets the height of paper. You can pass in a number or a string with a unit. | | [height?](./puppeteer.pdfoptions.height.md) | | string \| number | <i>(Optional)</i> Sets the height of paper. You can pass in a number or a string with a unit. |
| [landscape?](./puppeteer.pdfoptions.landscape.md) | | boolean | <i>(Optional)</i> Whether to print in landscape orientation. | | [landscape?](./puppeteer.pdfoptions.landscape.md) | | boolean | <i>(Optional)</i> Whether to print in landscape orientation. |
| [margin?](./puppeteer.pdfoptions.margin.md) | | [PDFMargin](./puppeteer.pdfmargin.md) | <i>(Optional)</i> Set the PDF margins. | | [margin?](./puppeteer.pdfoptions.margin.md) | | [PDFMargin](./puppeteer.pdfmargin.md) | <i>(Optional)</i> Set the PDF margins. |

View File

@ -26,4 +26,4 @@ A path where Puppeteer expects to find the bundled browser. The browser binary m
## Remarks ## Remarks
\*\*NOTE\*\* `puppeteer.executablePath()` is affected by the `PUPPETEER_EXECUTABLE_PATH` and `PUPPETEER_CHROMIUM_REVISION` environment variables. **NOTE** `puppeteer.executablePath()` is affected by the `PUPPETEER_EXECUTABLE_PATH` and `PUPPETEER_CHROMIUM_REVISION` environment variables.

View File

@ -28,7 +28,7 @@ Promise which resolves to browser instance.
## Remarks ## Remarks
\*\*NOTE\*\* Puppeteer can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested. In `puppeteer.launch([options])`, any mention of Chromium also applies to Chrome. See [this article](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [This article](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users. **NOTE** Puppeteer can also be used to control the Chrome browser, but it works best with the version of Chromium it is bundled with. There is no guarantee it will work with any other version. Use `executablePath` option with extreme caution. If Google Chrome (rather than Chromium) is preferred, a [Chrome Canary](https://www.google.com/chrome/browser/canary.html) or [Dev Channel](https://www.chromium.org/getting-involved/dev-channel) build is suggested. In `puppeteer.launch([options])`, any mention of Chromium also applies to Chrome. See [this article](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/) for a description of the differences between Chromium and Chrome. [This article](https://chromium.googlesource.com/chromium/src/+/lkgr/docs/chromium_browser_vs_google_chrome.md) describes some differences for Linux users.
## Example ## Example

13
package-lock.json generated
View File

@ -54,6 +54,7 @@
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",
"eslint-formatter-codeframe": "7.32.1", "eslint-formatter-codeframe": "7.32.1",
"eslint-plugin-import": "2.26.0", "eslint-plugin-import": "2.26.0",
"eslint-plugin-local": "^1.0.0",
"eslint-plugin-mocha": "10.1.0", "eslint-plugin-mocha": "10.1.0",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-prettier": "4.2.1",
"eslint-plugin-tsdoc": "0.2.16", "eslint-plugin-tsdoc": "0.2.16",
@ -2624,6 +2625,12 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/eslint-plugin-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-1.0.0.tgz",
"integrity": "sha512-bcwcQnKL/Iw5Vi/F2lG1he5oKD2OGjhsLmrcctkWrWq5TujgiaYb0cj3pZgr3XI54inNVnneOFdAx1daLoYLJQ==",
"dev": true
},
"node_modules/eslint-plugin-mocha": { "node_modules/eslint-plugin-mocha": {
"version": "10.1.0", "version": "10.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz",
@ -9061,6 +9068,12 @@
} }
} }
}, },
"eslint-plugin-local": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-local/-/eslint-plugin-local-1.0.0.tgz",
"integrity": "sha512-bcwcQnKL/Iw5Vi/F2lG1he5oKD2OGjhsLmrcctkWrWq5TujgiaYb0cj3pZgr3XI54inNVnneOFdAx1daLoYLJQ==",
"dev": true
},
"eslint-plugin-mocha": { "eslint-plugin-mocha": {
"version": "10.1.0", "version": "10.1.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz",

View File

@ -113,6 +113,7 @@
"eslint-config-prettier": "8.5.0", "eslint-config-prettier": "8.5.0",
"eslint-formatter-codeframe": "7.32.1", "eslint-formatter-codeframe": "7.32.1",
"eslint-plugin-import": "2.26.0", "eslint-plugin-import": "2.26.0",
"eslint-plugin-local": "1.0.0",
"eslint-plugin-mocha": "10.1.0", "eslint-plugin-mocha": "10.1.0",
"eslint-plugin-prettier": "4.2.1", "eslint-plugin-prettier": "4.2.1",
"eslint-plugin-tsdoc": "0.2.16", "eslint-plugin-tsdoc": "0.2.16",

View File

@ -152,6 +152,7 @@ export class Accessibility {
* *
* @example * @example
* An example of dumping the entire accessibility tree: * An example of dumping the entire accessibility tree:
*
* ```ts * ```ts
* const snapshot = await page.accessibility.snapshot(); * const snapshot = await page.accessibility.snapshot();
* console.log(snapshot); * console.log(snapshot);
@ -159,14 +160,14 @@ export class Accessibility {
* *
* @example * @example
* An example of logging the focused node's name: * An example of logging the focused node's name:
*
* ```ts * ```ts
* const snapshot = await page.accessibility.snapshot(); * const snapshot = await page.accessibility.snapshot();
* const node = findFocusedNode(snapshot); * const node = findFocusedNode(snapshot);
* console.log(node && node.name); * console.log(node && node.name);
* *
* function findFocusedNode(node) { * function findFocusedNode(node) {
* if (node.focused) * if (node.focused) return node;
* return node;
* for (const child of node.children || []) { * for (const child of node.children || []) {
* const foundNode = findFocusedNode(child); * const foundNode = findFocusedNode(child);
* return foundNode; * return foundNode;

View File

@ -59,11 +59,12 @@ function isKnownAttribute(
return knownAttributes.has(attribute); return knownAttributes.has(attribute);
} }
/* /**
* The selectors consist of an accessible name to query for and optionally * The selectors consist of an accessible name to query for and optionally
* further aria attributes on the form `[<attribute>=<value>]`. * further aria attributes on the form `[<attribute>=<value>]`.
* Currently, we only support the `name` and `role` attribute. * Currently, we only support the `name` and `role` attribute.
* The following examples showcase how the syntax works wrt. querying: * The following examples showcase how the syntax works wrt. querying:
*
* - 'title[role="heading"]' queries for elements with name 'title' and role 'heading'. * - 'title[role="heading"]' queries for elements with name 'title' and role 'heading'.
* - '[role="img"]' queries for elements with role 'img' and any name. * - '[role="img"]' queries for elements with role 'img' and any name.
* - 'label' queries for elements with name 'label' and any role. * - 'label' queries for elements with name 'label' and any role.

View File

@ -181,8 +181,8 @@ export const enum BrowserEmittedEvents {
* emit various events which are documented in the {@link BrowserEmittedEvents} enum. * emit various events which are documented in the {@link BrowserEmittedEvents} enum.
* *
* @example * @example
*
* An example of using a {@link Browser} to create a {@link Page}: * An example of using a {@link Browser} to create a {@link Page}:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -195,8 +195,8 @@ export const enum BrowserEmittedEvents {
* ``` * ```
* *
* @example * @example
*
* An example of disconnecting from and reconnecting to a {@link Browser}: * An example of disconnecting from and reconnecting to a {@link Browser}:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -411,6 +411,7 @@ export class Browser extends EventEmitter {
* browser contexts. * browser contexts.
* *
* @example * @example
*
* ```ts * ```ts
* (async () => { * (async () => {
* const browser = await puppeteer.launch(); * const browser = await puppeteer.launch();
@ -631,9 +632,12 @@ export class Browser extends EventEmitter {
* @example * @example
* *
* An example of finding a target for a page opened via `window.open`: * An example of finding a target for a page opened via `window.open`:
*
* ```ts * ```ts
* await page.evaluate(() => window.open('https://www.example.com/')); * await page.evaluate(() => window.open('https://www.example.com/'));
* const newWindowTarget = await browser.waitForTarget(target => target.url() === 'https://www.example.com/'); * const newWindowTarget = await browser.waitForTarget(
* target => target.url() === 'https://www.example.com/'
* );
* ``` * ```
*/ */
async waitForTarget( async waitForTarget(
@ -788,6 +792,7 @@ export const enum BrowserContextEmittedEvents {
* method. "Incognito" browser contexts don't write any browsing data to disk. * method. "Incognito" browser contexts don't write any browsing data to disk.
* *
* @example * @example
*
* ```ts * ```ts
* // Create a new incognito browser context * // Create a new incognito browser context
* const context = await browser.createIncognitoBrowserContext(); * const context = await browser.createIncognitoBrowserContext();
@ -798,6 +803,7 @@ export const enum BrowserContextEmittedEvents {
* // Dispose context once it's no longer needed. * // Dispose context once it's no longer needed.
* await context.close(); * await context.close();
* ``` * ```
*
* @public * @public
*/ */
export class BrowserContext extends EventEmitter { export class BrowserContext extends EventEmitter {
@ -829,9 +835,12 @@ export class BrowserContext extends EventEmitter {
* *
* @example * @example
* An example of finding a target for a page opened via `window.open`: * An example of finding a target for a page opened via `window.open`:
*
* ```ts * ```ts
* await page.evaluate(() => window.open('https://www.example.com/')); * await page.evaluate(() => window.open('https://www.example.com/'));
* const newWindowTarget = await browserContext.waitForTarget(target => target.url() === 'https://www.example.com/'); * const newWindowTarget = await browserContext.waitForTarget(
* target => target.url() === 'https://www.example.com/'
* );
* ``` * ```
* *
* @param predicate - A function to be run for every target * @param predicate - A function to be run for every target
@ -891,9 +900,12 @@ export class BrowserContext extends EventEmitter {
/** /**
* @example * @example
*
* ```ts * ```ts
* const context = browser.defaultBrowserContext(); * const context = browser.defaultBrowserContext();
* await context.overridePermissions('https://html5demos.com', ['geolocation']); * await context.overridePermissions('https://html5demos.com', [
* 'geolocation',
* ]);
* ``` * ```
* *
* @param origin - The origin to grant permissions to, e.g. "https://example.com". * @param origin - The origin to grant permissions to, e.g. "https://example.com".
@ -923,6 +935,7 @@ export class BrowserContext extends EventEmitter {
* Clears all permission overrides for the browser context. * Clears all permission overrides for the browser context.
* *
* @example * @example
*
* ```ts * ```ts
* const context = browser.defaultBrowserContext(); * const context = browser.defaultBrowserContext();
* context.overridePermissions('https://example.com', ['clipboard-read']); * context.overridePermissions('https://example.com', ['clipboard-read']);

View File

@ -280,14 +280,17 @@ export const CDPSessionEmittedEvents = {
* and {@link https://github.com/aslushnikov/getting-started-with-cdp/blob/HEAD/README.md | Getting Started with DevTools Protocol}. * and {@link https://github.com/aslushnikov/getting-started-with-cdp/blob/HEAD/README.md | Getting Started with DevTools Protocol}.
* *
* @example * @example
*
* ```ts * ```ts
* const client = await page.target().createCDPSession(); * const client = await page.target().createCDPSession();
* await client.send('Animation.enable'); * await client.send('Animation.enable');
* client.on('Animation.animationCreated', () => console.log('Animation created!')); * client.on('Animation.animationCreated', () =>
* console.log('Animation created!')
* );
* const response = await client.send('Animation.getPlaybackRate'); * const response = await client.send('Animation.getPlaybackRate');
* console.log('playback rate is ' + response.playbackRate); * console.log('playback rate is ' + response.playbackRate);
* await client.send('Animation.setPlaybackRate', { * await client.send('Animation.setPlaybackRate', {
* playbackRate: response.playbackRate / 2 * playbackRate: response.playbackRate / 2,
* }); * });
* ``` * ```
* *

View File

@ -98,11 +98,12 @@ export interface CSSCoverageOptions {
* @example * @example
* An example of using JavaScript and CSS coverage to get percentage of initially * An example of using JavaScript and CSS coverage to get percentage of initially
* executed code: * executed code:
*
* ```ts * ```ts
* // Enable both JavaScript and CSS coverage * // Enable both JavaScript and CSS coverage
* await Promise.all([ * await Promise.all([
* page.coverage.startJSCoverage(), * page.coverage.startJSCoverage(),
* page.coverage.startCSSCoverage() * page.coverage.startCSSCoverage(),
* ]); * ]);
* // Navigate to page * // Navigate to page
* await page.goto('https://example.com'); * await page.goto('https://example.com');
@ -116,11 +117,11 @@ export interface CSSCoverageOptions {
* const coverage = [...jsCoverage, ...cssCoverage]; * const coverage = [...jsCoverage, ...cssCoverage];
* for (const entry of coverage) { * for (const entry of coverage) {
* totalBytes += entry.text.length; * totalBytes += entry.text.length;
* for (const range of entry.ranges) * for (const range of entry.ranges) usedBytes += range.end - range.start - 1;
* usedBytes += range.end - range.start - 1;
* } * }
* console.log(`Bytes used: ${usedBytes / totalBytes * 100}%`); * console.log(`Bytes used: ${(usedBytes / totalBytes) * 100}%`);
* ``` * ```
*
* @public * @public
*/ */
export class Coverage { export class Coverage {

View File

@ -60,6 +60,7 @@ export async function importDebug(): Promise<typeof import('debug')> {
* ``` * ```
* *
* @example * @example
*
* ``` * ```
* const log = debug('Page'); * const log = debug('Page');
* *

View File

@ -24,6 +24,7 @@ import {Protocol} from 'devtools-protocol';
* @remarks * @remarks
* *
* @example * @example
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -38,6 +39,7 @@ import {Protocol} from 'devtools-protocol';
* page.evaluate(() => alert('1')); * page.evaluate(() => alert('1'));
* })(); * })();
* ``` * ```
*
* @public * @public
*/ */
export class Dialog { export class Dialog {

View File

@ -142,10 +142,15 @@ export class ElementHandle<
* the promise resolves. * the promise resolves.
* *
* @example * @example
*
* ```ts * ```ts
* const tweetHandle = await page.$('.tweet'); * const tweetHandle = await page.$('.tweet');
* expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100'); * expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe(
* expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10'); * '100'
* );
* expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe(
* '10'
* );
* ``` * ```
* *
* @param selector - The selector to query for. * @param selector - The selector to query for.
@ -186,17 +191,21 @@ export class ElementHandle<
* *
* @example * @example
* HTML: * HTML:
*
* ```html * ```html
* <div class="feed"> * <div class="feed">
* <div class="tweet">Hello!</div> * <div class="tweet">Hello!</div>
* <div class="tweet">Hi!</div> * <div class="tweet">Hi!</div>
* </div> * </div>
* ``` * ```
*
* JavaScript: * JavaScript:
*
* ```js * ```js
* const feedHandle = await page.$('.feed'); * const feedHandle = await page.$('.feed');
* expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))) * expect(
* .toEqual(['Hello!', 'Hi!']); * await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))
* ).toEqual(['Hello!', 'Hi!']);
* ``` * ```
* *
* @param selector - The selector to query for. * @param selector - The selector to query for.
@ -251,6 +260,7 @@ export class ElementHandle<
* navigations or if the element is detached from DOM. * navigations or if the element is detached from DOM.
* *
* @example * @example
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -258,16 +268,22 @@ export class ElementHandle<
* const browser = await puppeteer.launch(); * const browser = await puppeteer.launch();
* const page = await browser.newPage(); * const page = await browser.newPage();
* let currentURL; * let currentURL;
* page.mainFrame() * page
* .mainFrame()
* .waitForSelector('img') * .waitForSelector('img')
* .then(() => console.log('First URL with image: ' + currentURL)); * .then(() => console.log('First URL with image: ' + currentURL));
* *
* for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com']) { * for (currentURL of [
* 'https://example.com',
* 'https://google.com',
* 'https://bbc.com',
* ]) {
* await page.goto(currentURL); * await page.goto(currentURL);
* } * }
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @param selector - The selector to query and wait for. * @param selector - The selector to query and wait for.
* @param options - Options for customizing waiting behavior. * @param options - Options for customizing waiting behavior.
* @returns An element matching the given selector. * @returns An element matching the given selector.
@ -311,6 +327,7 @@ export class ElementHandle<
* automatically. * automatically.
* *
* This method works across navigation * This method works across navigation
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* (async () => { * (async () => {
@ -330,6 +347,7 @@ export class ElementHandle<
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @param xpath - A * @param xpath - A
* {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an * {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an
* element to wait for * element to wait for
@ -665,10 +683,12 @@ export class ElementHandle<
* throws an error. * throws an error.
* *
* @example * @example
*
* ```ts * ```ts
* handle.select('blue'); // single selection * handle.select('blue'); // single selection
* handle.select('red', 'green', 'blue'); // multiple selections * handle.select('red', 'green', 'blue'); // multiple selections
* ``` * ```
*
* @param values - Values of options to select. If the `<select>` has the * @param values - Values of options to select. If the `<select>` has the
* `multiple` attribute, all values are considered, otherwise only the first * `multiple` attribute, all values are considered, otherwise only the first
* one is taken into account. * one is taken into account.
@ -814,6 +834,7 @@ export class ElementHandle<
* use {@link ElementHandle.press}. * use {@link ElementHandle.press}.
* *
* @example * @example
*
* ```ts * ```ts
* await elementHandle.type('Hello'); // Types instantly * await elementHandle.type('Hello'); // Types instantly
* await elementHandle.type('World', {delay: 100}); // Types slower, like a user * await elementHandle.type('World', {delay: 100}); // Types slower, like a user

View File

@ -65,6 +65,7 @@ export interface PuppeteerErrors {
* *
* @example * @example
* An example of handling a timeout error: * An example of handling a timeout error:
*
* ```ts * ```ts
* try { * try {
* await page.waitForSelector('.foo'); * await page.waitForSelector('.foo');

View File

@ -102,6 +102,7 @@ export class ExecutionContext {
* Evaluates the given function. * Evaluates the given function.
* *
* @example * @example
*
* ```ts * ```ts
* const executionContext = await page.mainFrame().executionContext(); * const executionContext = await page.mainFrame().executionContext();
* const result = await executionContext.evaluate(() => Promise.resolve(8 * 7))* ; * const result = await executionContext.evaluate(() => Promise.resolve(8 * 7))* ;
@ -110,17 +111,21 @@ export class ExecutionContext {
* *
* @example * @example
* A string can also be passed in instead of a function: * A string can also be passed in instead of a function:
*
* ```ts * ```ts
* console.log(await executionContext.evaluate('1 + 2')); // prints "3" * console.log(await executionContext.evaluate('1 + 2')); // prints "3"
* ``` * ```
* *
* @example * @example
* Handles can also be passed as `args`. They resolve to their referenced object: * Handles can also be passed as `args`. They resolve to their referenced object:
*
* ```ts * ```ts
* const oneHandle = await executionContext.evaluateHandle(() => 1); * const oneHandle = await executionContext.evaluateHandle(() => 1);
* const twoHandle = await executionContext.evaluateHandle(() => 2); * const twoHandle = await executionContext.evaluateHandle(() => 2);
* const result = await executionContext.evaluate( * const result = await executionContext.evaluate(
* (a, b) => a + b, oneHandle, twoHandle * (a, b) => a + b,
* oneHandle,
* twoHandle
* ); * );
* await oneHandle.dispose(); * await oneHandle.dispose();
* await twoHandle.dispose(); * await twoHandle.dispose();
@ -153,27 +158,29 @@ export class ExecutionContext {
* `Map`) and requires further manipulation. * `Map`) and requires further manipulation.
* *
* @example * @example
*
* ```ts * ```ts
* const context = await page.mainFrame().executionContext(); * const context = await page.mainFrame().executionContext();
* const handle: JSHandle<typeof globalThis> = await context.evaluateHandle(() => * const handle: JSHandle<typeof globalThis> = await context.evaluateHandle(
* Promise.resolve(self) * () => Promise.resolve(self)
* ); * );
* ``` * ```
* *
* @example * @example
* A string can also be passed in instead of a function. * A string can also be passed in instead of a function.
*
* ```ts * ```ts
* const handle: JSHandle<number> = await context.evaluateHandle('1 + 2'); * const handle: JSHandle<number> = await context.evaluateHandle('1 + 2');
* ``` * ```
* *
* @example * @example
* Handles can also be passed as `args`. They resolve to their referenced object: * Handles can also be passed as `args`. They resolve to their referenced object:
*
* ```ts * ```ts
* const bodyHandle: ElementHandle<HTMLBodyElement> = await context.evaluateHandle( * const bodyHandle: ElementHandle<HTMLBodyElement> =
* () => { * await context.evaluateHandle(() => {
* return document.body; * return document.body;
* } * });
* );
* const stringHandle: JSHandle<string> = await context.evaluateHandle( * const stringHandle: JSHandle<string> = await context.evaluateHandle(
* body => body.innerHTML, * body => body.innerHTML,
* body * body
@ -372,9 +379,10 @@ export class ExecutionContext {
* given prototype. * given prototype.
* *
* @example * @example
*
* ```ts * ```ts
* // Create a Map object * // Create a Map object
* await page.evaluate(() => window.map = new Map()); * await page.evaluate(() => (window.map = new Map()));
* // Get a handle to the Map object prototype * // Get a handle to the Map object prototype
* const mapPrototype = await page.evaluateHandle(() => Map.prototype); * const mapPrototype = await page.evaluateHandle(() => Map.prototype);
* // Query all map instances into an array * // Query all map instances into an array

View File

@ -29,6 +29,7 @@ import {ElementHandle} from './ElementHandle.js';
* subsequent file choosers from appearing. * subsequent file choosers from appearing.
* *
* @example * @example
*
* ```ts * ```ts
* const [fileChooser] = await Promise.all([ * const [fileChooser] = await Promise.all([
* page.waitForFileChooser(), * page.waitForFileChooser(),

View File

@ -36,6 +36,7 @@ import {EventEmitter} from './EventEmitter.js';
* because Firefox's CDP implementation does not support auto-attach. * because Firefox's CDP implementation does not support auto-attach.
* *
* Firefox does not support targetInfoChanged and detachedFromTarget events: * Firefox does not support targetInfoChanged and detachedFromTarget events:
*
* - https://bugzilla.mozilla.org/show_bug.cgi?id=1610855 * - https://bugzilla.mozilla.org/show_bug.cgi?id=1610855
* - https://bugzilla.mozilla.org/show_bug.cgi?id=1636979 * - https://bugzilla.mozilla.org/show_bug.cgi?id=1636979
* @internal * @internal

View File

@ -861,6 +861,7 @@ export class Frame {
* to change the URL is considered a navigation. * to change the URL is considered a navigation.
* *
* @example * @example
*
* ```ts * ```ts
* const [response] = await Promise.all([ * const [response] = await Promise.all([
* // The navigation promise resolves after navigation has finished * // The navigation promise resolves after navigation has finished
@ -988,6 +989,7 @@ export class Frame {
* the promise resolves. * the promise resolves.
* *
* @example * @example
*
* ```ts * ```ts
* const searchValue = await frame.$eval('#search', el => el.value); * const searchValue = await frame.$eval('#search', el => el.value);
* ``` * ```
@ -1021,6 +1023,7 @@ export class Frame {
* the promise resolves. * the promise resolves.
* *
* @example * @example
*
* ```js * ```js
* const divsCounts = await frame.$$eval('div', divs => divs.length); * const divsCounts = await frame.$$eval('div', divs => divs.length);
* ``` * ```
@ -1062,6 +1065,7 @@ export class Frame {
* This method works across navigations. * This method works across navigations.
* *
* @example * @example
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -1069,16 +1073,22 @@ export class Frame {
* const browser = await puppeteer.launch(); * const browser = await puppeteer.launch();
* const page = await browser.newPage(); * const page = await browser.newPage();
* let currentURL; * let currentURL;
* page.mainFrame() * page
* .mainFrame()
* .waitForSelector('img') * .waitForSelector('img')
* .then(() => console.log('First URL with image: ' + currentURL)); * .then(() => console.log('First URL with image: ' + currentURL));
* *
* for (currentURL of ['https://example.com', 'https://google.com', 'https://bbc.com']) { * for (currentURL of [
* 'https://example.com',
* 'https://google.com',
* 'https://bbc.com',
* ]) {
* await page.goto(currentURL); * await page.goto(currentURL);
* } * }
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @param selector - The selector to query and wait for. * @param selector - The selector to query and wait for.
* @param options - Options for customizing waiting behavior. * @param options - Options for customizing waiting behavior.
* @returns An element matching the given selector. * @returns An element matching the given selector.
@ -1131,6 +1141,7 @@ export class Frame {
/** /**
* @example * @example
* The `waitForFunction` can be used to observe viewport size change: * The `waitForFunction` can be used to observe viewport size change:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -1326,6 +1337,7 @@ export class Frame {
* `selector`. * `selector`.
* *
* @example * @example
*
* ```ts * ```ts
* frame.select('select#colors', 'blue'); // single selection * frame.select('select#colors', 'blue'); // single selection
* frame.select('select#colors', 'red', 'green', 'blue'); // multiple selections * frame.select('select#colors', 'red', 'green', 'blue'); // multiple selections
@ -1361,6 +1373,7 @@ export class Frame {
* {@link Keyboard.press}. * {@link Keyboard.press}.
* *
* @example * @example
*
* ```ts * ```ts
* await frame.type('#mytextarea', 'Hello'); // Types instantly * await frame.type('#mytextarea', 'Hello'); // Types instantly
* await frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user * await frame.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user

View File

@ -80,7 +80,6 @@ interface CDPSession extends EventEmitter {
} }
/** /**
*
* Represents an HTTP request sent by a page. * Represents an HTTP request sent by a page.
* @remarks * @remarks
* *
@ -426,6 +425,7 @@ export class HTTPRequest {
* Exception is immediately thrown if the request interception is not enabled. * Exception is immediately thrown if the request interception is not enabled.
* *
* @example * @example
*
* ```ts * ```ts
* await page.setRequestInterception(true); * await page.setRequestInterception(true);
* page.on('request', request => { * page.on('request', request => {
@ -519,13 +519,14 @@ export class HTTPRequest {
* *
* @example * @example
* An example of fulfilling all requests with 404 responses: * An example of fulfilling all requests with 404 responses:
*
* ```ts * ```ts
* await page.setRequestInterception(true); * await page.setRequestInterception(true);
* page.on('request', request => { * page.on('request', request => {
* request.respond({ * request.respond({
* status: 404, * status: 404,
* contentType: 'text/plain', * contentType: 'text/plain',
* body: 'Not Found!' * body: 'Not Found!',
* }); * });
* }); * });
* ``` * ```

View File

@ -40,6 +40,7 @@ type KeyDescription = Required<
* *
* @example * @example
* An example of holding down `Shift` in order to select and delete some text: * An example of holding down `Shift` in order to select and delete some text:
*
* ```ts * ```ts
* await page.keyboard.type('Hello World!'); * await page.keyboard.type('Hello World!');
* await page.keyboard.press('ArrowLeft'); * await page.keyboard.press('ArrowLeft');
@ -55,6 +56,7 @@ type KeyDescription = Required<
* *
* @example * @example
* An example of pressing `A` * An example of pressing `A`
*
* ```ts * ```ts
* await page.keyboard.down('Shift'); * await page.keyboard.down('Shift');
* await page.keyboard.press('KeyA'); * await page.keyboard.press('KeyA');
@ -230,6 +232,7 @@ export class Keyboard {
* Holding down `Shift` will not type the text in upper case. * Holding down `Shift` will not type the text in upper case.
* *
* @example * @example
*
* ```ts * ```ts
* page.keyboard.sendCharacter('嗨'); * page.keyboard.sendCharacter('嗨');
* ``` * ```
@ -256,6 +259,7 @@ export class Keyboard {
* Holding down `Shift` will not type the text in upper case. * Holding down `Shift` will not type the text in upper case.
* *
* @example * @example
*
* ```ts * ```ts
* await page.keyboard.type('Hello'); // Types instantly * await page.keyboard.type('Hello'); // Types instantly
* await page.keyboard.type('World', {delay: 100}); // Types slower, like a user * await page.keyboard.type('World', {delay: 100}); // Types slower, like a user
@ -345,6 +349,7 @@ export interface MouseWheelOptions {
* Every `page` object has its own Mouse, accessible with [`page.mouse`](#pagemouse). * Every `page` object has its own Mouse, accessible with [`page.mouse`](#pagemouse).
* *
* @example * @example
*
* ```ts * ```ts
* // Using page.mouse to trace a 100x100 square. * // Using page.mouse to trace a 100x100 square.
* await page.mouse.move(0, 0); * await page.mouse.move(0, 0);
@ -365,17 +370,24 @@ export interface MouseWheelOptions {
* *
* @example * @example
* For example, if you want to select all content between nodes: * For example, if you want to select all content between nodes:
*
* ```ts * ```ts
* await page.evaluate((from, to) => { * await page.evaluate(
* (from, to) => {
* const selection = from.getRootNode().getSelection(); * const selection = from.getRootNode().getSelection();
* const range = document.createRange(); * const range = document.createRange();
* range.setStartBefore(from); * range.setStartBefore(from);
* range.setEndAfter(to); * range.setEndAfter(to);
* selection.removeAllRanges(); * selection.removeAllRanges();
* selection.addRange(range); * selection.addRange(range);
* }, fromJSHandle, toJSHandle); * },
* fromJSHandle,
* toJSHandle
* );
* ``` * ```
*
* If you then would want to copy-paste your selection, you can use the clipboard api: * If you then would want to copy-paste your selection, you can use the clipboard api:
*
* ```ts * ```ts
* // The clipboard api does not allow you to copy, unless the tab is focused. * // The clipboard api does not allow you to copy, unless the tab is focused.
* await page.bringToFront(); * await page.bringToFront();
@ -386,13 +398,19 @@ export interface MouseWheelOptions {
* return navigator.clipboard.readText(); * return navigator.clipboard.readText();
* }); * });
* ``` * ```
*
* **Note**: If you want access to the clipboard API, * **Note**: If you want access to the clipboard API,
* you have to give it permission to do so: * you have to give it permission to do so:
*
* ```ts * ```ts
* await browser.defaultBrowserContext().overridePermissions( * await browser
* '<your origin>', ['clipboard-read', 'clipboard-write'] * .defaultBrowserContext()
* ); * .overridePermissions('<your origin>', [
* 'clipboard-read',
* 'clipboard-write',
* ]);
* ``` * ```
*
* @public * @public
*/ */
export class Mouse { export class Mouse {
@ -504,8 +522,11 @@ export class Mouse {
* *
* @example * @example
* An example of zooming into an element: * An example of zooming into an element:
*
* ```ts * ```ts
* await page.goto('https://mdn.mozillademos.org/en-US/docs/Web/API/Element/wheel_event$samples/Scaling_an_element_via_the_wheel?revision=1587366'); * await page.goto(
* 'https://mdn.mozillademos.org/en-US/docs/Web/API/Element/wheel_event$samples/Scaling_an_element_via_the_wheel?revision=1587366'
* );
* *
* const elem = await page.$('div'); * const elem = await page.$('div');
* const boundingBox = await elem.boundingBox(); * const boundingBox = await elem.boundingBox();
@ -514,7 +535,7 @@ export class Mouse {
* boundingBox.y + boundingBox.height / 2 * boundingBox.y + boundingBox.height / 2
* ); * );
* *
* await page.mouse.wheel({ deltaY: -100 }) * await page.mouse.wheel({deltaY: -100});
* ``` * ```
*/ */
async wheel(options: MouseWheelOptions = {}): Promise<void> { async wheel(options: MouseWheelOptions = {}): Promise<void> {

View File

@ -65,6 +65,7 @@ export interface BoundingBox extends Point {
* They are resolved to their referenced object. * They are resolved to their referenced object.
* *
* @example * @example
*
* ```ts * ```ts
* const windowHandle = await page.evaluateHandle(() => window); * const windowHandle = await page.evaluateHandle(() => window);
* ``` * ```
@ -177,6 +178,7 @@ export class JSHandle<T = unknown> {
* Gets a map of handles representing the properties of the current handle. * Gets a map of handles representing the properties of the current handle.
* *
* @example * @example
*
* ```ts * ```ts
* const listHandle = await page.evaluateHandle(() => document.body.children); * const listHandle = await page.evaluateHandle(() => document.body.children);
* const properties = await listHandle.getProperties(); * const properties = await listHandle.getProperties();
@ -214,7 +216,7 @@ export class JSHandle<T = unknown> {
* @throws Throws if the object cannot be serialized due to circularity. * @throws Throws if the object cannot be serialized due to circularity.
* *
* @remarks * @remarks
* If the object has a `toJSON` function, it *will not* be called. * If the object has a `toJSON` function, it **will not** be called.
*/ */
async jsonValue(): Promise<T> { async jsonValue(): Promise<T> {
if (!this.#remoteObject.objectId) { if (!this.#remoteObject.objectId) {

View File

@ -35,7 +35,7 @@ export type NetworkRequestId = string;
* @internal * @internal
*/ */
export class NetworkEventManager { export class NetworkEventManager {
/* /**
* There are four possible orders of events: * There are four possible orders of events:
* A. `_onRequestWillBeSent` * A. `_onRequestWillBeSent`
* B. `_onRequestWillBeSent`, `_onRequestPaused` * B. `_onRequestWillBeSent`, `_onRequestPaused`

View File

@ -46,6 +46,7 @@ export type LowerCasePaperFormat =
* @remarks * @remarks
* *
* The sizes of each format are as follows: * The sizes of each format are as follows:
*
* - `Letter`: 8.5in x 11in * - `Letter`: 8.5in x 11in
* *
* - `Legal`: 8.5in x 14in * - `Legal`: 8.5in x 14in
@ -93,6 +94,7 @@ export interface PDFOptions {
/** /**
* HTML template for the print header. Should be valid HTML with the following * HTML template for the print header. Should be valid HTML with the following
* classes used to inject values into them: * classes used to inject values into them:
*
* - `date` formatted print date * - `date` formatted print date
* *
* - `title` document title * - `title` document title

View File

@ -234,6 +234,7 @@ export const enum PageEmittedEvents {
* *
* @example * @example
* An example of handling `console` event: * An example of handling `console` event:
*
* ```ts * ```ts
* page.on('console', msg => { * page.on('console', msg => {
* for (let i = 0; i < msg.args().length; ++i) * for (let i = 0; i < msg.args().length; ++i)
@ -280,6 +281,7 @@ export const enum PageEmittedEvents {
* *
* @remarks * @remarks
* Contains an object with two properties: * Contains an object with two properties:
*
* - `title`: the title passed to `console.timeStamp` * - `title`: the title passed to `console.timeStamp`
* - `metrics`: objec containing metrics as key/value pairs. The values will * - `metrics`: objec containing metrics as key/value pairs. The values will
* be `number`s. * be `number`s.
@ -406,6 +408,7 @@ export interface PageEventObject {
* *
* @example * @example
* This example creates a page, navigates it to a URL, and then saves a screenshot: * This example creates a page, navigates it to a URL, and then saves a screenshot:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -423,6 +426,7 @@ export interface PageEventObject {
* *
* @example * @example
* This example logs a message for a single page `load` event: * This example logs a message for a single page `load` event:
*
* ```ts * ```ts
* page.once('load', () => console.log('Page loaded!')); * page.once('load', () => console.log('Page loaded!'));
* ``` * ```
@ -784,6 +788,7 @@ export class Page extends EventEmitter {
* permissions for the page to read its geolocation. * permissions for the page to read its geolocation.
* *
* @example * @example
*
* ```ts * ```ts
* await page.setGeolocation({latitude: 59.95, longitude: 30.31667}); * await page.setGeolocation({latitude: 59.95, longitude: 30.31667});
* ``` * ```
@ -924,6 +929,7 @@ export class Page extends EventEmitter {
* *
* @example * @example
* An example of a naïve request interceptor that aborts all image requests: * An example of a naïve request interceptor that aborts all image requests:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* (async () => { * (async () => {
@ -931,11 +937,12 @@ export class Page extends EventEmitter {
* const page = await browser.newPage(); * const page = await browser.newPage();
* await page.setRequestInterception(true); * await page.setRequestInterception(true);
* page.on('request', interceptedRequest => { * page.on('request', interceptedRequest => {
* if (interceptedRequest.url().endsWith('.png') || * if (
* interceptedRequest.url().endsWith('.jpg')) * interceptedRequest.url().endsWith('.png') ||
* interceptedRequest.url().endsWith('.jpg')
* )
* interceptedRequest.abort(); * interceptedRequest.abort();
* else * else interceptedRequest.continue();
* interceptedRequest.continue();
* }); * });
* await page.goto('https://example.com'); * await page.goto('https://example.com');
* await browser.close(); * await browser.close();
@ -975,6 +982,7 @@ export class Page extends EventEmitter {
/** /**
* @param networkConditions - Passing `null` disables network condition emulation. * @param networkConditions - Passing `null` disables network condition emulation.
* @example * @example
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* const slow3G = puppeteer.networkConditions['Slow 3G']; * const slow3G = puppeteer.networkConditions['Slow 3G'];
@ -988,6 +996,7 @@ export class Page extends EventEmitter {
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @remarks * @remarks
* NOTE: This does not affect WebSockets and WebRTC PeerConnections (see * NOTE: This does not affect WebSockets and WebRTC PeerConnections (see
* https://crbug.com/563644). To set the page offline, you can use * https://crbug.com/563644). To set the page offline, you can use
@ -1070,15 +1079,20 @@ export class Page extends EventEmitter {
* recommended as they are easier to debug and use with TypeScript): * recommended as they are easier to debug and use with TypeScript):
* *
* @example * @example
*
* ```ts * ```ts
* const aHandle = await page.evaluateHandle('document') * const aHandle = await page.evaluateHandle('document');
* ``` * ```
* *
* @example * @example
* {@link JSHandle} instances can be passed as arguments to the `pageFunction`: * {@link JSHandle} instances can be passed as arguments to the `pageFunction`:
*
* ```ts * ```ts
* const aHandle = await page.evaluateHandle(() => document.body); * const aHandle = await page.evaluateHandle(() => document.body);
* const resultHandle = await page.evaluateHandle(body => body.innerHTML, aHandle); * const resultHandle = await page.evaluateHandle(
* body => body.innerHTML,
* aHandle
* );
* console.log(await resultHandle.jsonValue()); * console.log(await resultHandle.jsonValue());
* await resultHandle.dispose(); * await resultHandle.dispose();
* ``` * ```
@ -1088,8 +1102,11 @@ export class Page extends EventEmitter {
* you instead get an {@link ElementHandle} back: * you instead get an {@link ElementHandle} back:
* *
* @example * @example
*
* ```ts * ```ts
* const button = await page.evaluateHandle(() => document.querySelector('button')); * const button = await page.evaluateHandle(() =>
* document.querySelector('button')
* );
* // can call `click` because `button` is an `ElementHandle` * // can call `click` because `button` is an `ElementHandle`
* await button.click(); * await button.click();
* ``` * ```
@ -1129,7 +1146,7 @@ export class Page extends EventEmitter {
* *
* ```ts * ```ts
* // Create a Map object * // Create a Map object
* await page.evaluate(() => window.map = new Map()); * await page.evaluate(() => (window.map = new Map()));
* // Get a handle to the Map object prototype * // Get a handle to the Map object prototype
* const mapPrototype = await page.evaluateHandle(() => Map.prototype); * const mapPrototype = await page.evaluateHandle(() => Map.prototype);
* // Query all map instances into an array * // Query all map instances into an array
@ -1139,6 +1156,7 @@ export class Page extends EventEmitter {
* await mapInstances.dispose(); * await mapInstances.dispose();
* await mapPrototype.dispose(); * await mapPrototype.dispose();
* ``` * ```
*
* @param prototypeHandle - a handle to the object prototype. * @param prototypeHandle - a handle to the object prototype.
* @returns Promise which resolves to a handle to an array of objects with * @returns Promise which resolves to a handle to an array of objects with
* this prototype. * this prototype.
@ -1179,7 +1197,10 @@ export class Page extends EventEmitter {
* ```ts * ```ts
* // if you don't provide HTMLInputElement here, TS will error * // if you don't provide HTMLInputElement here, TS will error
* // as `value` is not on `Element` * // as `value` is not on `Element`
* const searchValue = await page.$eval('#search', (el: HTMLInputElement) => el.value); * const searchValue = await page.$eval(
* '#search',
* (el: HTMLInputElement) => el.value
* );
* ``` * ```
* *
* The compiler should be able to infer the return type * The compiler should be able to infer the return type
@ -1192,7 +1213,8 @@ export class Page extends EventEmitter {
* // The compiler can infer the return type in this case, but if it can't * // The compiler can infer the return type in this case, but if it can't
* // or if you want to be more explicit, provide it as the generic type. * // or if you want to be more explicit, provide it as the generic type.
* const searchValue = await page.$eval<string>( * const searchValue = await page.$eval<string>(
* '#search', (el: HTMLInputElement) => el.value * '#search',
* (el: HTMLInputElement) => el.value
* ); * );
* ``` * ```
* *
@ -1231,13 +1253,14 @@ export class Page extends EventEmitter {
* resolve and then return its value. * resolve and then return its value.
* *
* @example * @example
*
* ```ts * ```ts
* // get the amount of divs on the page * // get the amount of divs on the page
* const divCount = await page.$$eval('div', divs => divs.length); * const divCount = await page.$$eval('div', divs => divs.length);
* *
* // get the text content of all the `.options` elements: * // get the text content of all the `.options` elements:
* const options = await page.$$eval('div > span.options', options => { * const options = await page.$$eval('div > span.options', options => {
* return options.map(option => option.textContent) * return options.map(option => option.textContent);
* }); * });
* ``` * ```
* *
@ -1247,6 +1270,7 @@ export class Page extends EventEmitter {
* specific sub-type: * specific sub-type:
* *
* @example * @example
*
* ```ts * ```ts
* // if you don't provide HTMLInputElement here, TS will error * // if you don't provide HTMLInputElement here, TS will error
* // as `value` is not on `Element` * // as `value` is not on `Element`
@ -1260,11 +1284,13 @@ export class Page extends EventEmitter {
* type to tell the compiler what return type you expect from `$$eval`: * type to tell the compiler what return type you expect from `$$eval`:
* *
* @example * @example
*
* ```ts * ```ts
* // The compiler can infer the return type in this case, but if it can't * // The compiler can infer the return type in this case, but if it can't
* // or if you want to be more explicit, provide it as the generic type. * // or if you want to be more explicit, provide it as the generic type.
* const allInputValues = await page.$$eval<string[]>( * const allInputValues = await page.$$eval<string[]>(
* 'input', (elements: HTMLInputElement[]) => elements.map(e => e.textContent) * 'input',
* (elements: HTMLInputElement[]) => elements.map(e => e.textContent)
* ); * );
* ``` * ```
* *
@ -1346,6 +1372,7 @@ export class Page extends EventEmitter {
/** /**
* @example * @example
*
* ```ts * ```ts
* await page.setCookie(cookieObject1, cookieObject2); * await page.setCookie(cookieObject1, cookieObject2);
* ``` * ```
@ -1424,6 +1451,7 @@ export class Page extends EventEmitter {
* *
* @example * @example
* An example of adding an `md5` function into the page: * An example of adding an `md5` function into the page:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* const crypto = require('crypto'); * const crypto = require('crypto');
@ -1431,8 +1459,8 @@ export class Page extends EventEmitter {
* (async () => { * (async () => {
* const browser = await puppeteer.launch(); * const browser = await puppeteer.launch();
* const page = await browser.newPage(); * const page = await browser.newPage();
* page.on('console', (msg) => console.log(msg.text())); * page.on('console', msg => console.log(msg.text()));
* await page.exposeFunction('md5', (text) => * await page.exposeFunction('md5', text =>
* crypto.createHash('md5').update(text).digest('hex') * crypto.createHash('md5').update(text).digest('hex')
* ); * );
* await page.evaluate(async () => { * await page.evaluate(async () => {
@ -1447,6 +1475,7 @@ export class Page extends EventEmitter {
* *
* @example * @example
* An example of adding a `window.readfile` function into the page: * An example of adding a `window.readfile` function into the page:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* const fs = require('fs'); * const fs = require('fs');
@ -1454,8 +1483,8 @@ export class Page extends EventEmitter {
* (async () => { * (async () => {
* const browser = await puppeteer.launch(); * const browser = await puppeteer.launch();
* const page = await browser.newPage(); * const page = await browser.newPage();
* page.on('console', (msg) => console.log(msg.text())); * page.on('console', msg => console.log(msg.text()));
* await page.exposeFunction('readfile', async (filePath) => { * await page.exposeFunction('readfile', async filePath => {
* return new Promise((resolve, reject) => { * return new Promise((resolve, reject) => {
* fs.readFile(filePath, 'utf8', (err, text) => { * fs.readFile(filePath, 'utf8', (err, text) => {
* if (err) reject(err); * if (err) reject(err);
@ -1586,7 +1615,6 @@ export class Page extends EventEmitter {
* *
* - `TaskDuration` : Combined duration of all tasks performed by the browser. * - `TaskDuration` : Combined duration of all tasks performed by the browser.
* *
*
* - `JSHeapUsedSize` : Used JavaScript heap size. * - `JSHeapUsedSize` : Used JavaScript heap size.
* *
* - `JSHeapTotalSize` : Total JavaScript heap size. * - `JSHeapTotalSize` : Total JavaScript heap size.
@ -1849,6 +1877,7 @@ export class Page extends EventEmitter {
* {@link Page.setExtraHTTPHeaders |page.setExtraHTTPHeaders()}. * {@link Page.setExtraHTTPHeaders |page.setExtraHTTPHeaders()}.
* *
* `page.goto` will throw an error if: * `page.goto` will throw an error if:
*
* - there's an SSL error (e.g. in case of self-signed certificates). * - there's an SSL error (e.g. in case of self-signed certificates).
* - target URL is invalid. * - target URL is invalid.
* - the timeout is exceeded during navigation. * - the timeout is exceeded during navigation.
@ -1917,6 +1946,7 @@ export class Page extends EventEmitter {
* you run code that will indirectly cause the page to navigate. * you run code that will indirectly cause the page to navigate.
* *
* @example * @example
*
* ```ts * ```ts
* const [response] = await Promise.all([ * const [response] = await Promise.all([
* page.waitForNavigation(), // The promise resolves after navigation has finished * page.waitForNavigation(), // The promise resolves after navigation has finished
@ -1932,6 +1962,7 @@ export class Page extends EventEmitter {
* @param options - Navigation parameters which might have the following * @param options - Navigation parameters which might have the following
* properties: * properties:
* @returns A `Promise` which resolves to the main resource response. * @returns A `Promise` which resolves to the main resource response.
*
* - In case of multiple redirects, the navigation will resolve with the * - In case of multiple redirects, the navigation will resolve with the
* response of the last redirect. * response of the last redirect.
* - In case of navigation to a different anchor or navigation due to History * - In case of navigation to a different anchor or navigation due to History
@ -1959,19 +1990,21 @@ export class Page extends EventEmitter {
* @param options - Optional waiting parameters * @param options - Optional waiting parameters
* @returns Promise which resolves to the matched response * @returns Promise which resolves to the matched response
* @example * @example
*
* ```ts * ```ts
* const firstResponse = await page.waitForResponse( * const firstResponse = await page.waitForResponse(
* 'https://example.com/resource' * 'https://example.com/resource'
* ); * );
* const finalResponse = await page.waitForResponse( * const finalResponse = await page.waitForResponse(
* (response) => * response =>
* response.url() === 'https://example.com' && response.status() === 200 * response.url() === 'https://example.com' && response.status() === 200
* ); * );
* const finalResponse = await page.waitForResponse(async (response) => { * const finalResponse = await page.waitForResponse(async response => {
* return (await response.text()).includes('<html>'); * return (await response.text()).includes('<html>');
* }); * });
* return finalResponse.ok(); * return finalResponse.ok();
* ``` * ```
*
* @remarks * @remarks
* Optional Waiting Parameters have: * Optional Waiting Parameters have:
* *
@ -2006,19 +2039,21 @@ export class Page extends EventEmitter {
* @param options - Optional waiting parameters * @param options - Optional waiting parameters
* @returns Promise which resolves to the matched response. * @returns Promise which resolves to the matched response.
* @example * @example
*
* ```ts * ```ts
* const firstResponse = await page.waitForResponse( * const firstResponse = await page.waitForResponse(
* 'https://example.com/resource' * 'https://example.com/resource'
* ); * );
* const finalResponse = await page.waitForResponse( * const finalResponse = await page.waitForResponse(
* (response) => * response =>
* response.url() === 'https://example.com' && response.status() === 200 * response.url() === 'https://example.com' && response.status() === 200
* ); * );
* const finalResponse = await page.waitForResponse(async (response) => { * const finalResponse = await page.waitForResponse(async response => {
* return (await response.text()).includes('<html>'); * return (await response.text()).includes('<html>');
* }); * });
* return finalResponse.ok(); * return finalResponse.ok();
* ``` * ```
*
* @remarks * @remarks
* Optional Parameter have: * Optional Parameter have:
* *
@ -2131,11 +2166,13 @@ export class Page extends EventEmitter {
* @param options - Optional waiting parameters * @param options - Optional waiting parameters
* @returns Promise which resolves to the matched frame. * @returns Promise which resolves to the matched frame.
* @example * @example
*
* ```ts * ```ts
* const frame = await page.waitForFrame(async (frame) => { * const frame = await page.waitForFrame(async frame => {
* return frame.name() === 'Test'; * return frame.name() === 'Test';
* }); * });
* ``` * ```
*
* @remarks * @remarks
* Optional Parameter have: * Optional Parameter have:
* *
@ -2284,6 +2321,7 @@ export class Page extends EventEmitter {
* don't expect phones to change size, so you should emulate before navigating * don't expect phones to change size, so you should emulate before navigating
* to the page. * to the page.
* @example * @example
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* const iPhone = puppeteer.devices['iPhone 6']; * const iPhone = puppeteer.devices['iPhone 6'];
@ -2296,6 +2334,7 @@ export class Page extends EventEmitter {
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @remarks List of all available devices is available in the source code: * @remarks List of all available devices is available in the source code:
* {@link https://github.com/puppeteer/puppeteer/blob/main/src/common/DeviceDescriptors.ts | src/common/DeviceDescriptors.ts}. * {@link https://github.com/puppeteer/puppeteer/blob/main/src/common/DeviceDescriptors.ts | src/common/DeviceDescriptors.ts}.
*/ */
@ -2343,6 +2382,7 @@ export class Page extends EventEmitter {
* values are `screen`, `print` and `null`. Passing `null` disables CSS media * values are `screen`, `print` and `null`. Passing `null` disables CSS media
* emulation. * emulation.
* @example * @example
*
* ```ts * ```ts
* await page.evaluate(() => matchMedia('screen').matches); * await page.evaluate(() => matchMedia('screen').matches);
* // → true * // → true
@ -2393,13 +2433,18 @@ export class Page extends EventEmitter {
* objects, emulates CSS media features on the page. Each media feature object * objects, emulates CSS media features on the page. Each media feature object
* must have the following properties: * must have the following properties:
* @example * @example
*
* ```ts * ```ts
* await page.emulateMediaFeatures([ * await page.emulateMediaFeatures([
* {name: 'prefers-color-scheme', value: 'dark'}, * {name: 'prefers-color-scheme', value: 'dark'},
* ]); * ]);
* await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches); * await page.evaluate(
* () => matchMedia('(prefers-color-scheme: dark)').matches
* );
* // → true * // → true
* await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches); * await page.evaluate(
* () => matchMedia('(prefers-color-scheme: light)').matches
* );
* // → false * // → false
* *
* await page.emulateMediaFeatures([ * await page.emulateMediaFeatures([
@ -2418,9 +2463,13 @@ export class Page extends EventEmitter {
* {name: 'prefers-color-scheme', value: 'dark'}, * {name: 'prefers-color-scheme', value: 'dark'},
* {name: 'prefers-reduced-motion', value: 'reduce'}, * {name: 'prefers-reduced-motion', value: 'reduce'},
* ]); * ]);
* await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches); * await page.evaluate(
* () => matchMedia('(prefers-color-scheme: dark)').matches
* );
* // → true * // → true
* await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches); * await page.evaluate(
* () => matchMedia('(prefers-color-scheme: light)').matches
* );
* // → false * // → false
* await page.evaluate( * await page.evaluate(
* () => matchMedia('(prefers-reduced-motion: reduce)').matches * () => matchMedia('(prefers-reduced-motion: reduce)').matches
@ -2484,6 +2533,7 @@ export class Page extends EventEmitter {
* If no arguments set, clears idle state emulation. * If no arguments set, clears idle state emulation.
* *
* @example * @example
*
* ```ts * ```ts
* // set idle emulation * // set idle emulation
* await page.emulateIdleState({isUserActive: true, isScreenUnlocked: false}); * await page.emulateIdleState({isUserActive: true, isScreenUnlocked: false});
@ -2515,6 +2565,7 @@ export class Page extends EventEmitter {
* Simulates the given vision deficiency on the page. * Simulates the given vision deficiency on the page.
* *
* @example * @example
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -2572,6 +2623,7 @@ export class Page extends EventEmitter {
* In the case of multiple pages in a single browser, each page can have its * In the case of multiple pages in a single browser, each page can have its
* own viewport size. * own viewport size.
* @example * @example
*
* ```ts * ```ts
* const page = await browser.newPage(); * const page = await browser.newPage();
* await page.setViewport({ * await page.setViewport({
@ -2653,6 +2705,7 @@ export class Page extends EventEmitter {
* recommended as they are easier to debug and use with TypeScript): * recommended as they are easier to debug and use with TypeScript):
* *
* @example * @example
*
* ```ts * ```ts
* const aHandle = await page.evaluate('1 + 2'); * const aHandle = await page.evaluate('1 + 2');
* ``` * ```
@ -2705,6 +2758,7 @@ export class Page extends EventEmitter {
* @param args - Arguments to pass to `pageFunction` * @param args - Arguments to pass to `pageFunction`
* @example * @example
* An example of overriding the navigator.languages property before the page loads: * An example of overriding the navigator.languages property before the page loads:
*
* ```ts * ```ts
* // preload.js * // preload.js
* *
@ -2993,7 +3047,6 @@ export class Page extends EventEmitter {
* {@link https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust | `-webkit-print-color-adjust`} * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/-webkit-print-color-adjust | `-webkit-print-color-adjust`}
* property to force rendering of exact colors. * property to force rendering of exact colors.
* *
*
* @param options - options for generating the PDF. * @param options - options for generating the PDF.
*/ */
async createPDFStream(options: PDFOptions = {}): Promise<Readable> { async createPDFStream(options: PDFOptions = {}): Promise<Readable> {
@ -3127,12 +3180,14 @@ export class Page extends EventEmitter {
* there's a separate `page.waitForNavigation()` promise to be resolved, you * there's a separate `page.waitForNavigation()` promise to be resolved, you
* may end up with a race condition that yields unexpected results. The * may end up with a race condition that yields unexpected results. The
* correct pattern for click and wait for navigation is the following: * correct pattern for click and wait for navigation is the following:
*
* ```ts * ```ts
* const [response] = await Promise.all([ * const [response] = await Promise.all([
* page.waitForNavigation(waitOptions), * page.waitForNavigation(waitOptions),
* page.click(selector, clickOptions), * page.click(selector, clickOptions),
* ]); * ]);
* ``` * ```
*
* Shortcut for {@link Frame.click | page.mainFrame().click(selector[, options]) }. * Shortcut for {@link Frame.click | page.mainFrame().click(selector[, options]) }.
* @param selector - A `selector` to search for element to click. If there are * @param selector - A `selector` to search for element to click. If there are
* multiple elements satisfying the `selector`, the first will be clicked * multiple elements satisfying the `selector`, the first will be clicked
@ -3193,10 +3248,12 @@ export class Page extends EventEmitter {
* throws an error. * throws an error.
* *
* @example * @example
*
* ```ts * ```ts
* page.select('select#colors', 'blue'); // single selection * page.select('select#colors', 'blue'); // single selection
* page.select('select#colors', 'red', 'green', 'blue'); // multiple selections * page.select('select#colors', 'red', 'green', 'blue'); // multiple selections
* ``` * ```
*
* @param selector - A * @param selector - A
* {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | Selector} * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | Selector}
* to query the page for * to query the page for
@ -3234,12 +3291,14 @@ export class Page extends EventEmitter {
* *
* To press a special key, like `Control` or `ArrowDown`, use {@link Keyboard.press}. * To press a special key, like `Control` or `ArrowDown`, use {@link Keyboard.press}.
* @example * @example
*
* ```ts * ```ts
* await page.type('#mytextarea', 'Hello'); * await page.type('#mytextarea', 'Hello');
* // Types instantly * // Types instantly
* await page.type('#mytextarea', 'World', {delay: 100}); * await page.type('#mytextarea', 'World', {delay: 100});
* // Types slower, like a user * // Types slower, like a user
* ``` * ```
*
* @param selector - A * @param selector - A
* {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector} * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector}
* of an element to type into. If there are multiple elements satisfying the * of an element to type into. If there are multiple elements satisfying the
@ -3288,6 +3347,7 @@ export class Page extends EventEmitter {
* function will throw. * function will throw.
* *
* This method works across navigations: * This method works across navigations:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* (async () => { * (async () => {
@ -3307,6 +3367,7 @@ export class Page extends EventEmitter {
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @param selector - A * @param selector - A
* {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector} * {@link https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors | selector}
* of an element to wait for * of an element to wait for
@ -3343,6 +3404,7 @@ export class Page extends EventEmitter {
* function will throw. * function will throw.
* *
* This method works across navigation * This method works across navigation
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* (async () => { * (async () => {
@ -3362,6 +3424,7 @@ export class Page extends EventEmitter {
* await browser.close(); * await browser.close();
* })(); * })();
* ``` * ```
*
* @param xpath - A * @param xpath - A
* {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an * {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an
* element to wait for * element to wait for
@ -3416,10 +3479,11 @@ export class Page extends EventEmitter {
* @example * @example
* To pass arguments from node.js to the predicate of * To pass arguments from node.js to the predicate of
* {@link Page.waitForFunction} function: * {@link Page.waitForFunction} function:
*
* ```ts * ```ts
* const selector = '.foo'; * const selector = '.foo';
* await page.waitForFunction( * await page.waitForFunction(
* (selector) => !!document.querySelector(selector), * selector => !!document.querySelector(selector),
* {}, * {},
* selector * selector
* ); * );
@ -3427,10 +3491,11 @@ export class Page extends EventEmitter {
* *
* @example * @example
* The predicate of {@link Page.waitForFunction} can be asynchronous too: * The predicate of {@link Page.waitForFunction} can be asynchronous too:
*
* ```ts * ```ts
* const username = 'github-username'; * const username = 'github-username';
* await page.waitForFunction( * await page.waitForFunction(
* async (username) => { * async username => {
* const githubResponse = await fetch( * const githubResponse = await fetch(
* `https://api.github.com/users/${username}` * `https://api.github.com/users/${username}`
* ); * );
@ -3449,6 +3514,7 @@ export class Page extends EventEmitter {
* *
* @param pageFunction - Function to be evaluated in browser context * @param pageFunction - Function to be evaluated in browser context
* @param options - Optional waiting parameters * @param options - Optional waiting parameters
*
* - `polling` - An interval at which the `pageFunction` is executed, defaults * - `polling` - An interval at which the `pageFunction` is executed, defaults
* to `raf`. If `polling` is a number, then it is treated as an interval in * to `raf`. If `polling` is a number, then it is treated as an interval in
* milliseconds at which the function would be executed. If polling is a * milliseconds at which the function would be executed. If polling is a

View File

@ -81,6 +81,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {devices} from 'puppeteer'; * import {devices} from 'puppeteer';
* ``` * ```
@ -92,6 +93,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {errors} from 'puppeteer'; * import {errors} from 'puppeteer';
* ``` * ```
@ -103,6 +105,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {networkConditions} from 'puppeteer'; * import {networkConditions} from 'puppeteer';
* ``` * ```
@ -114,6 +117,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {registerCustomQueryHandler} from 'puppeteer'; * import {registerCustomQueryHandler} from 'puppeteer';
* ``` * ```
@ -128,6 +132,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {unregisterCustomQueryHandler} from 'puppeteer'; * import {unregisterCustomQueryHandler} from 'puppeteer';
* ``` * ```
@ -139,6 +144,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {customQueryHandlerNames} from 'puppeteer'; * import {customQueryHandlerNames} from 'puppeteer';
* ``` * ```
@ -150,6 +156,7 @@ export class Puppeteer {
/** /**
* @deprecated Import directly puppeteer. * @deprecated Import directly puppeteer.
* @example * @example
*
* ```ts * ```ts
* import {clearCustomQueryHandlers} from 'puppeteer'; * import {clearCustomQueryHandlers} from 'puppeteer';
* ``` * ```

View File

@ -261,6 +261,7 @@ const QUERY_HANDLERS = new Map<string, RegisteredQueryHandler>();
* allowed to consist of lower- and upper case latin letters. * allowed to consist of lower- and upper case latin letters.
* *
* @example * @example
*
* ``` * ```
* puppeteer.registerCustomQueryHandler('text', { }); * puppeteer.registerCustomQueryHandler('text', { });
* const aHandle = await page.$('text/…'); * const aHandle = await page.$('text/…');

View File

@ -37,6 +37,7 @@ export interface TracingOptions {
* which can be opened in Chrome DevTools or {@link https://chromedevtools.github.io/timeline-viewer/ | timeline viewer}. * which can be opened in Chrome DevTools or {@link https://chromedevtools.github.io/timeline-viewer/ | timeline viewer}.
* *
* @example * @example
*
* ```ts * ```ts
* await page.tracing.start({path: 'trace.json'}); * await page.tracing.start({path: 'trace.json'});
* await page.goto('https://www.google.com'); * await page.goto('https://www.google.com');

View File

@ -49,9 +49,14 @@ type JSHandleFactory = (obj: Protocol.Runtime.RemoteObject) => JSHandle;
* object to signal the worker lifecycle. * object to signal the worker lifecycle.
* *
* @example * @example
*
* ```ts * ```ts
* page.on('workercreated', worker => console.log('Worker created: ' + worker.url())); * page.on('workercreated', worker =>
* page.on('workerdestroyed', worker => console.log('Worker destroyed: ' + worker.url())); * console.log('Worker created: ' + worker.url())
* );
* page.on('workerdestroyed', worker =>
* console.log('Worker destroyed: ' + worker.url())
* );
* *
* console.log('Current workers:'); * console.log('Current workers:');
* for (const worker of page.workers()) { * for (const worker of page.workers()) {

View File

@ -183,7 +183,9 @@ export interface BrowserFetcherRevisionInfo {
* ```ts * ```ts
* const browserFetcher = puppeteer.createBrowserFetcher(); * const browserFetcher = puppeteer.createBrowserFetcher();
* const revisionInfo = await browserFetcher.download('533271'); * const revisionInfo = await browserFetcher.download('533271');
* const browser = await puppeteer.launch({executablePath: revisionInfo.executablePath}) * const browser = await puppeteer.launch({
* executablePath: revisionInfo.executablePath,
* });
* ``` * ```
* *
* **NOTE** BrowserFetcher is not designed to work concurrently with other * **NOTE** BrowserFetcher is not designed to work concurrently with other

View File

@ -54,6 +54,7 @@ export interface PuppeteerLaunchOptions
* *
* @example * @example
* The following is a typical example of using Puppeteer to drive automation: * The following is a typical example of using Puppeteer to drive automation:
*
* ```ts * ```ts
* const puppeteer = require('puppeteer'); * const puppeteer = require('puppeteer');
* *
@ -132,9 +133,10 @@ export class PuppeteerNode extends Puppeteer {
* *
* @example * @example
* You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments: * You can use `ignoreDefaultArgs` to filter out `--mute-audio` from default arguments:
*
* ```ts * ```ts
* const browser = await puppeteer.launch({ * const browser = await puppeteer.launch({
* ignoreDefaultArgs: ['--mute-audio'] * ignoreDefaultArgs: ['--mute-audio'],
* }); * });
* ``` * ```
* *

View File

@ -481,18 +481,19 @@ describeChromeOnly('NetworkManager', () => {
* This sequence was taken from an actual CDP session produced by the following * This sequence was taken from an actual CDP session produced by the following
* test script: * test script:
* *
* const browser = await puppeteer.launch(\{ headless: false \}); * ```ts
* const browser = await puppeteer.launch({headless: false});
* const page = await browser.newPage(); * const page = await browser.newPage();
* await page.setCacheEnabled(false); * await page.setCacheEnabled(false);
* *
* await page.setRequestInterception(true) * await page.setRequestInterception(true);
* page.on('request', (interceptedRequest) =\> \{ * page.on('request', interceptedRequest => {
* interceptedRequest.continue(); * interceptedRequest.continue();
* \}); * });
* *
* await page.goto('https://www.google.com'); * await page.goto('https://www.google.com');
* await browser.close(); * await browser.close();
* * ```
*/ */
mockCDPSession.emit('Network.requestWillBeSent', { mockCDPSession.emit('Network.requestWillBeSent', {
requestId: '11ACE9783588040D644B905E8B55285B', requestId: '11ACE9783588040D644B905E8B55285B',

View File

@ -392,6 +392,7 @@ export class MarkdownDocumenter {
pageContent; pageContent;
pageContent = pageContent.replace('##', '#'); pageContent = pageContent.replace('##', '#');
pageContent = pageContent.replace(/<!-- -->/g, ''); pageContent = pageContent.replace(/<!-- -->/g, '');
pageContent = pageContent.replace(/\\\*\\\*/g, '**');
pageContent = pageContent.replace(/<b>|<\/b>/g, '**'); pageContent = pageContent.replace(/<b>|<\/b>/g, '**');
FileSystem.writeFile(filename, pageContent, { FileSystem.writeFile(filename, pageContent, {
convertLineEndings: this._documenterConfig convertLineEndings: this._documenterConfig

3763
website/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,17 +15,17 @@
"archive": "node archive.js" "archive": "node archive.js"
}, },
"dependencies": { "dependencies": {
"@docusaurus/core": "2.0.0-beta.21", "@docusaurus/core": "2.0.1",
"@docusaurus/preset-classic": "2.0.0-beta.21", "@docusaurus/preset-classic": "2.0.1",
"@easyops-cn/docusaurus-search-local": "^0.28.0", "@easyops-cn/docusaurus-search-local": "0.26.1",
"@mdx-js/react": "^1.6.22", "@mdx-js/react": "1.6.22",
"clsx": "^1.1.1", "clsx": "^1.2.1",
"prism-react-renderer": "^1.3.3", "prism-react-renderer": "1.3.5",
"react": "^17.0.2", "react": "17.0.2",
"react-dom": "^17.0.2" "react-dom": "17.0.2"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "2.0.0-beta.21" "@docusaurus/module-type-aliases": "2.0.1"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [