From ddbe88b887122632d48d97b8d537d36af5cf0f74 Mon Sep 17 00:00:00 2001 From: jrandolf <101637635+jrandolf@users.noreply.github.com> Date: Fri, 12 Aug 2022 14:15:26 +0200 Subject: [PATCH] chore: add custom rule for formatting comments (#8777) --- .eslintplugin.js | 95 + .eslintrc.js | 16 +- docs/api/puppeteer.accessibility.snapshot.md | 2 +- docs/api/puppeteer.browserfetcher.md | 2 +- docs/api/puppeteer.elementhandle.press.md | 2 +- docs/api/puppeteer.jshandle.jsonvalue.md | 2 +- docs/api/puppeteer.mouse.md | 4 +- docs/api/puppeteer.page.goto.md | 4 +- docs/api/puppeteer.page.waitforfunction.md | 10 +- docs/api/puppeteer.page.waitfornavigation.md | 4 +- docs/api/puppeteer.paperformat.md | 4 +- .../puppeteer.pdfoptions.headertemplate.md | 4 +- docs/api/puppeteer.pdfoptions.md | 34 +- .../puppeteer.puppeteernode.executablepath.md | 2 +- docs/api/puppeteer.puppeteernode.launch.md | 2 +- package-lock.json | 13 + package.json | 1 + src/common/Accessibility.ts | 5 +- src/common/AriaQueryHandler.ts | 3 +- src/common/Browser.ts | 25 +- src/common/Connection.ts | 7 +- src/common/Coverage.ts | 9 +- src/common/Debug.ts | 1 + src/common/Dialog.ts | 2 + src/common/ElementHandle.ts | 91 +- src/common/Errors.ts | 1 + src/common/EventEmitter.ts | 4 +- src/common/ExecutionContext.ts | 24 +- src/common/FileChooser.ts | 3 +- src/common/FirefoxTargetManager.ts | 3 +- src/common/FrameManager.ts | 29 +- src/common/HTTPRequest.ts | 19 +- src/common/HTTPResponse.ts | 2 +- src/common/Input.ts | 47 +- src/common/JSHandle.ts | 4 +- src/common/NetworkEventManager.ts | 34 +- src/common/PDFOptions.ts | 2 + src/common/Page.ts | 580 +-- src/common/Puppeteer.ts | 21 +- src/common/QueryHandler.ts | 1 + src/common/Tracing.ts | 1 + src/common/WebWorker.ts | 9 +- src/node/BrowserFetcher.ts | 4 +- src/node/Puppeteer.ts | 4 +- test/src/NetworkManager.spec.ts | 11 +- utils/internal/custom_markdown_documenter.ts | 3 +- website/package-lock.json | 3763 +++++++++-------- website/package.json | 18 +- 48 files changed, 2613 insertions(+), 2318 deletions(-) create mode 100644 .eslintplugin.js diff --git a/.eslintplugin.js b/.eslintplugin.js new file mode 100644 index 00000000..0e61040f --- /dev/null +++ b/.eslintplugin.js @@ -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, + }, +}; diff --git a/.eslintrc.js b/.eslintrc.js index 28664f2d..466d7ebe 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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 = { root: true, env: { @@ -132,8 +123,10 @@ module.exports = { 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended', ], - plugins: ['eslint-plugin-tsdoc'], + plugins: ['eslint-plugin-tsdoc', 'local'], rules: { + // Keeps comments formatted. + 'local/prettier-comments': 2, // Brackets keep code readable. curly: [2, 'all'], // Brackets keep code readable and `return` intentions clear. @@ -189,9 +182,6 @@ module.exports = { selector: "CallExpression[callee.name='require']", message: '`require` statements are not allowed. Use `import`.', }, - - // Don't allow underscored declarations on camelCased variables/properties. - // ...RESTRICTED_UNDERSCORED_IDENTIFIERS, ], }, }, diff --git a/docs/api/puppeteer.accessibility.snapshot.md b/docs/api/puppeteer.accessibility.snapshot.md index 9b0a2057..c8f7bf5b 100644 --- a/docs/api/puppeteer.accessibility.snapshot.md +++ b/docs/api/puppeteer.accessibility.snapshot.md @@ -28,7 +28,7 @@ An AXNode object representing the snapshot. ## 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 diff --git a/docs/api/puppeteer.browserfetcher.md b/docs/api/puppeteer.browserfetcher.md index 5c9c876f..ac001994 100644 --- a/docs/api/puppeteer.browserfetcher.md +++ b/docs/api/puppeteer.browserfetcher.md @@ -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 diff --git a/docs/api/puppeteer.elementhandle.press.md b/docs/api/puppeteer.elementhandle.press.md index 28f2928c..5b2b1e63 100644 --- a/docs/api/puppeteer.elementhandle.press.md +++ b/docs/api/puppeteer.elementhandle.press.md @@ -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. -\*\*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. diff --git a/docs/api/puppeteer.jshandle.jsonvalue.md b/docs/api/puppeteer.jshandle.jsonvalue.md index 4d6871d0..7a4264c8 100644 --- a/docs/api/puppeteer.jshandle.jsonvalue.md +++ b/docs/api/puppeteer.jshandle.jsonvalue.md @@ -24,4 +24,4 @@ Throws if the object cannot be serialized due to circularity. ## 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. diff --git a/docs/api/puppeteer.mouse.md b/docs/api/puppeteer.mouse.md index df6f9705..b024026e 100644 --- a/docs/api/puppeteer.mouse.md +++ b/docs/api/puppeteer.mouse.md @@ -31,7 +31,7 @@ await page.mouse.move(0, 0); 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. @@ -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 await browser diff --git a/docs/api/puppeteer.page.goto.md b/docs/api/puppeteer.page.goto.md index d77ef2a4..555ec9c8 100644 --- a/docs/api/puppeteer.page.goto.md +++ b/docs/api/puppeteer.page.goto.md @@ -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). -`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(). diff --git a/docs/api/puppeteer.page.waitforfunction.md b/docs/api/puppeteer.page.waitforfunction.md index 4937d605..3e49efc0 100644 --- a/docs/api/puppeteer.page.waitforfunction.md +++ b/docs/api/puppeteer.page.waitforfunction.md @@ -26,11 +26,11 @@ class Page { ## Parameters -| Parameter | Type | Description | -| ------------ | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| pageFunction | Func \| string | Function to be evaluated in browser context | -| options | { timeout?: number; polling?: string \| number; } | (Optional) Optional waiting parameters - 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 milliseconds at which the function would be executed. If polling is a string, then it can be one of the following values: - raf - to constantly execute pageFunction in requestAnimationFrame callback. This is the tightest polling mode which is suitable to observe styling changes. - mutation- to execute pageFunction on every DOM mutation. - timeout - maximum time to wait for in milliseconds. Defaults to 30000 (30 seconds). Pass 0 to disable timeout. The default value can be changed by using the [Page.setDefaultTimeout()](./puppeteer.page.setdefaulttimeout.md) method. | -| args | Params | Arguments to pass to pageFunction | +| Parameter | Type | Description | +| ------------ | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| pageFunction | Func \| string | Function to be evaluated in browser context | +| options | { timeout?: number; polling?: string \| number; } |

(Optional) Optional waiting parameters

- 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 milliseconds at which the function would be executed. If polling is a string, then it can be one of the following values: - raf - to constantly execute pageFunction in requestAnimationFrame callback. This is the tightest polling mode which is suitable to observe styling changes. - mutation- to execute pageFunction on every DOM mutation. - timeout - maximum time to wait for in milliseconds. Defaults to 30000 (30 seconds). Pass 0 to disable timeout. The default value can be changed by using the [Page.setDefaultTimeout()](./puppeteer.page.setdefaulttimeout.md) method.

| +| args | Params | Arguments to pass to pageFunction | **Returns:** diff --git a/docs/api/puppeteer.page.waitfornavigation.md b/docs/api/puppeteer.page.waitfornavigation.md index 72e4138a..c351f687 100644 --- a/docs/api/puppeteer.page.waitfornavigation.md +++ b/docs/api/puppeteer.page.waitfornavigation.md @@ -24,7 +24,9 @@ class Page { Promise<[HTTPResponse](./puppeteer.httpresponse.md) \| 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`. +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 diff --git a/docs/api/puppeteer.paperformat.md b/docs/api/puppeteer.paperformat.md index 7b529add..7f2250c0 100644 --- a/docs/api/puppeteer.paperformat.md +++ b/docs/api/puppeteer.paperformat.md @@ -19,7 +19,9 @@ export declare type PaperFormat = ## 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 diff --git a/docs/api/puppeteer.pdfoptions.headertemplate.md b/docs/api/puppeteer.pdfoptions.headertemplate.md index 7fd5ee6e..189db329 100644 --- a/docs/api/puppeteer.pdfoptions.headertemplate.md +++ b/docs/api/puppeteer.pdfoptions.headertemplate.md @@ -4,7 +4,9 @@ sidebar_label: PDFOptions.headerTemplate # 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 diff --git a/docs/api/puppeteer.pdfoptions.md b/docs/api/puppeteer.pdfoptions.md index f6c83e27..5e7efdd9 100644 --- a/docs/api/puppeteer.pdfoptions.md +++ b/docs/api/puppeteer.pdfoptions.md @@ -14,20 +14,20 @@ export interface PDFOptions ## Properties -| Property | Modifiers | Type | Description | -| --------------------------------------------------------------------- | --------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [displayHeaderFooter?](./puppeteer.pdfoptions.displayheaderfooter.md) | | boolean | (Optional) Whether to show the header and footer. | -| [footerTemplate?](./puppeteer.pdfoptions.footertemplate.md) | | string | (Optional) 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) | (Optional) | -| [headerTemplate?](./puppeteer.pdfoptions.headertemplate.md) | | string |

(Optional) 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

- url document location

- pageNumber current page number

- totalPages total pages in the document

| -| [height?](./puppeteer.pdfoptions.height.md) | | string \| number | (Optional) Sets the height of paper. You can pass in a number or a string with a unit. | -| [landscape?](./puppeteer.pdfoptions.landscape.md) | | boolean | (Optional) Whether to print in landscape orientation. | -| [margin?](./puppeteer.pdfoptions.margin.md) | | [PDFMargin](./puppeteer.pdfmargin.md) | (Optional) Set the PDF margins. | -| [omitBackground?](./puppeteer.pdfoptions.omitbackground.md) | | boolean | (Optional) Hides default white background and allows generating pdfs with transparency. | -| [pageRanges?](./puppeteer.pdfoptions.pageranges.md) | | string | (Optional) Paper ranges to print, e.g. 1-5, 8, 11-13. | -| [path?](./puppeteer.pdfoptions.path.md) | | string | (Optional) The path to save the file to. | -| [preferCSSPageSize?](./puppeteer.pdfoptions.prefercsspagesize.md) | | boolean | (Optional) Give any CSS @page size declared in the page priority over what is declared in the width or height or format option. | -| [printBackground?](./puppeteer.pdfoptions.printbackground.md) | | boolean | (Optional) Set to true to print background graphics. | -| [scale?](./puppeteer.pdfoptions.scale.md) | | number | (Optional) Scales the rendering of the web page. Amount must be between 0.1 and 2. | -| [timeout?](./puppeteer.pdfoptions.timeout.md) | | number | (Optional) Timeout in milliseconds | -| [width?](./puppeteer.pdfoptions.width.md) | | string \| number | (Optional) Sets the width of paper. You can pass in a number or a string with a unit. | +| Property | Modifiers | Type | Description | +| --------------------------------------------------------------------- | --------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| [displayHeaderFooter?](./puppeteer.pdfoptions.displayheaderfooter.md) | | boolean | (Optional) Whether to show the header and footer. | +| [footerTemplate?](./puppeteer.pdfoptions.footertemplate.md) | | string | (Optional) 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) | (Optional) | +| [headerTemplate?](./puppeteer.pdfoptions.headertemplate.md) | | string |

(Optional) 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

- url document location

- pageNumber current page number

- totalPages total pages in the document

| +| [height?](./puppeteer.pdfoptions.height.md) | | string \| number | (Optional) Sets the height of paper. You can pass in a number or a string with a unit. | +| [landscape?](./puppeteer.pdfoptions.landscape.md) | | boolean | (Optional) Whether to print in landscape orientation. | +| [margin?](./puppeteer.pdfoptions.margin.md) | | [PDFMargin](./puppeteer.pdfmargin.md) | (Optional) Set the PDF margins. | +| [omitBackground?](./puppeteer.pdfoptions.omitbackground.md) | | boolean | (Optional) Hides default white background and allows generating pdfs with transparency. | +| [pageRanges?](./puppeteer.pdfoptions.pageranges.md) | | string | (Optional) Paper ranges to print, e.g. 1-5, 8, 11-13. | +| [path?](./puppeteer.pdfoptions.path.md) | | string | (Optional) The path to save the file to. | +| [preferCSSPageSize?](./puppeteer.pdfoptions.prefercsspagesize.md) | | boolean | (Optional) Give any CSS @page size declared in the page priority over what is declared in the width or height or format option. | +| [printBackground?](./puppeteer.pdfoptions.printbackground.md) | | boolean | (Optional) Set to true to print background graphics. | +| [scale?](./puppeteer.pdfoptions.scale.md) | | number | (Optional) Scales the rendering of the web page. Amount must be between 0.1 and 2. | +| [timeout?](./puppeteer.pdfoptions.timeout.md) | | number | (Optional) Timeout in milliseconds | +| [width?](./puppeteer.pdfoptions.width.md) | | string \| number | (Optional) Sets the width of paper. You can pass in a number or a string with a unit. | diff --git a/docs/api/puppeteer.puppeteernode.executablepath.md b/docs/api/puppeteer.puppeteernode.executablepath.md index 9fba867b..05340450 100644 --- a/docs/api/puppeteer.puppeteernode.executablepath.md +++ b/docs/api/puppeteer.puppeteernode.executablepath.md @@ -26,4 +26,4 @@ A path where Puppeteer expects to find the bundled browser. The browser binary m ## 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. diff --git a/docs/api/puppeteer.puppeteernode.launch.md b/docs/api/puppeteer.puppeteernode.launch.md index b954040a..2c72d334 100644 --- a/docs/api/puppeteer.puppeteernode.launch.md +++ b/docs/api/puppeteer.puppeteernode.launch.md @@ -28,7 +28,7 @@ Promise which resolves to browser instance. ## 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 diff --git a/package-lock.json b/package-lock.json index 93c0fbdb..e9d763b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -54,6 +54,7 @@ "eslint-config-prettier": "8.5.0", "eslint-formatter-codeframe": "7.32.1", "eslint-plugin-import": "2.26.0", + "eslint-plugin-local": "^1.0.0", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-tsdoc": "0.2.16", @@ -2624,6 +2625,12 @@ "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": { "version": "10.1.0", "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": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.1.0.tgz", diff --git a/package.json b/package.json index b1b37b22..149d2836 100644 --- a/package.json +++ b/package.json @@ -113,6 +113,7 @@ "eslint-config-prettier": "8.5.0", "eslint-formatter-codeframe": "7.32.1", "eslint-plugin-import": "2.26.0", + "eslint-plugin-local": "1.0.0", "eslint-plugin-mocha": "10.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-tsdoc": "0.2.16", diff --git a/src/common/Accessibility.ts b/src/common/Accessibility.ts index e1f13e82..ea540c01 100644 --- a/src/common/Accessibility.ts +++ b/src/common/Accessibility.ts @@ -152,6 +152,7 @@ export class Accessibility { * * @example * An example of dumping the entire accessibility tree: + * * ```ts * const snapshot = await page.accessibility.snapshot(); * console.log(snapshot); @@ -159,14 +160,14 @@ export class Accessibility { * * @example * An example of logging the focused node's name: + * * ```ts * const snapshot = await page.accessibility.snapshot(); * const node = findFocusedNode(snapshot); * console.log(node && node.name); * * function findFocusedNode(node) { - * if (node.focused) - * return node; + * if (node.focused) return node; * for (const child of node.children || []) { * const foundNode = findFocusedNode(child); * return foundNode; diff --git a/src/common/AriaQueryHandler.ts b/src/common/AriaQueryHandler.ts index a8239557..774ea53a 100644 --- a/src/common/AriaQueryHandler.ts +++ b/src/common/AriaQueryHandler.ts @@ -59,11 +59,12 @@ function isKnownAttribute( return knownAttributes.has(attribute); } -/* +/** * The selectors consist of an accessible name to query for and optionally * further aria attributes on the form `[=]`. * Currently, we only support the `name` and `role` attribute. * The following examples showcase how the syntax works wrt. querying: + * * - 'title[role="heading"]' queries for elements with name 'title' and role 'heading'. * - '[role="img"]' queries for elements with role 'img' and any name. * - 'label' queries for elements with name 'label' and any role. diff --git a/src/common/Browser.ts b/src/common/Browser.ts index c59534c1..74c15841 100644 --- a/src/common/Browser.ts +++ b/src/common/Browser.ts @@ -181,8 +181,8 @@ export const enum BrowserEmittedEvents { * emit various events which are documented in the {@link BrowserEmittedEvents} enum. * * @example - * * An example of using a {@link Browser} to create a {@link Page}: + * * ```ts * const puppeteer = require('puppeteer'); * @@ -195,8 +195,8 @@ export const enum BrowserEmittedEvents { * ``` * * @example - * * An example of disconnecting from and reconnecting to a {@link Browser}: + * * ```ts * const puppeteer = require('puppeteer'); * @@ -411,9 +411,10 @@ export class Browser extends EventEmitter { * browser contexts. * * @example + * * ```ts * (async () => { - * const browser = await puppeteer.launch(); + * const browser = await puppeteer.launch(); * // Create a new incognito browser context. * const context = await browser.createIncognitoBrowserContext(); * // Create a new page in a pristine context. @@ -631,9 +632,12 @@ export class Browser extends EventEmitter { * @example * * An example of finding a target for a page opened via `window.open`: + * * ```ts * 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( @@ -788,6 +792,7 @@ export const enum BrowserContextEmittedEvents { * method. "Incognito" browser contexts don't write any browsing data to disk. * * @example + * * ```ts * // Create a new incognito browser context * const context = await browser.createIncognitoBrowserContext(); @@ -798,6 +803,7 @@ export const enum BrowserContextEmittedEvents { * // Dispose context once it's no longer needed. * await context.close(); * ``` + * * @public */ export class BrowserContext extends EventEmitter { @@ -829,9 +835,12 @@ export class BrowserContext extends EventEmitter { * * @example * An example of finding a target for a page opened via `window.open`: + * * ```ts * 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 @@ -891,9 +900,12 @@ export class BrowserContext extends EventEmitter { /** * @example + * * ```ts * 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". @@ -923,6 +935,7 @@ export class BrowserContext extends EventEmitter { * Clears all permission overrides for the browser context. * * @example + * * ```ts * const context = browser.defaultBrowserContext(); * context.overridePermissions('https://example.com', ['clipboard-read']); diff --git a/src/common/Connection.ts b/src/common/Connection.ts index 0f6db4d6..be319581 100644 --- a/src/common/Connection.ts +++ b/src/common/Connection.ts @@ -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}. * * @example + * * ```ts * const client = await page.target().createCDPSession(); * 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'); * console.log('playback rate is ' + response.playbackRate); * await client.send('Animation.setPlaybackRate', { - * playbackRate: response.playbackRate / 2 + * playbackRate: response.playbackRate / 2, * }); * ``` * diff --git a/src/common/Coverage.ts b/src/common/Coverage.ts index d1efde87..f130f4c8 100644 --- a/src/common/Coverage.ts +++ b/src/common/Coverage.ts @@ -98,11 +98,12 @@ export interface CSSCoverageOptions { * @example * An example of using JavaScript and CSS coverage to get percentage of initially * executed code: + * * ```ts * // Enable both JavaScript and CSS coverage * await Promise.all([ * page.coverage.startJSCoverage(), - * page.coverage.startCSSCoverage() + * page.coverage.startCSSCoverage(), * ]); * // Navigate to page * await page.goto('https://example.com'); @@ -116,11 +117,11 @@ export interface CSSCoverageOptions { * const coverage = [...jsCoverage, ...cssCoverage]; * for (const entry of coverage) { * totalBytes += entry.text.length; - * for (const range of entry.ranges) - * usedBytes += range.end - range.start - 1; + * for (const range of entry.ranges) usedBytes += range.end - range.start - 1; * } - * console.log(`Bytes used: ${usedBytes / totalBytes * 100}%`); + * console.log(`Bytes used: ${(usedBytes / totalBytes) * 100}%`); * ``` + * * @public */ export class Coverage { diff --git a/src/common/Debug.ts b/src/common/Debug.ts index 21db3566..425b7c30 100644 --- a/src/common/Debug.ts +++ b/src/common/Debug.ts @@ -60,6 +60,7 @@ export async function importDebug(): Promise { * ``` * * @example + * * ``` * const log = debug('Page'); * diff --git a/src/common/Dialog.ts b/src/common/Dialog.ts index b6dadc63..259c67aa 100644 --- a/src/common/Dialog.ts +++ b/src/common/Dialog.ts @@ -24,6 +24,7 @@ import {Protocol} from 'devtools-protocol'; * @remarks * * @example + * * ```ts * const puppeteer = require('puppeteer'); * @@ -38,6 +39,7 @@ import {Protocol} from 'devtools-protocol'; * page.evaluate(() => alert('1')); * })(); * ``` + * * @public */ export class Dialog { diff --git a/src/common/ElementHandle.ts b/src/common/ElementHandle.ts index 2d65453f..fc1e7b22 100644 --- a/src/common/ElementHandle.ts +++ b/src/common/ElementHandle.ts @@ -43,12 +43,12 @@ const applyOffsetsToQuad = ( * const puppeteer = require('puppeteer'); * * (async () => { - * const browser = await puppeteer.launch(); - * const page = await browser.newPage(); - * await page.goto('https://example.com'); - * const hrefElement = await page.$('a'); - * await hrefElement.click(); - * // ... + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * await page.goto('https://example.com'); + * const hrefElement = await page.$('a'); + * await hrefElement.click(); + * // ... * })(); * ``` * @@ -142,10 +142,15 @@ export class ElementHandle< * the promise resolves. * * @example + * * ```ts * const tweetHandle = await page.$('.tweet'); - * expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe('100'); - * expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe('10'); + * expect(await tweetHandle.$eval('.like', node => node.innerText)).toBe( + * '100' + * ); + * expect(await tweetHandle.$eval('.retweets', node => node.innerText)).toBe( + * '10' + * ); * ``` * * @param selector - The selector to query for. @@ -186,17 +191,21 @@ export class ElementHandle< * * @example * HTML: + * * ```html *
*
Hello!
*
Hi!
*
* ``` + * * JavaScript: + * * ```js * const feedHandle = await page.$('.feed'); - * expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))) - * .toEqual(['Hello!', 'Hi!']); + * expect( + * await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText)) + * ).toEqual(['Hello!', 'Hi!']); * ``` * * @param selector - The selector to query for. @@ -251,6 +260,7 @@ export class ElementHandle< * navigations or if the element is detached from DOM. * * @example + * * ```ts * const puppeteer = require('puppeteer'); * @@ -258,16 +268,22 @@ export class ElementHandle< * const browser = await puppeteer.launch(); * const page = await browser.newPage(); * let currentURL; - * page.mainFrame() - * .waitForSelector('img') - * .then(() => console.log('First URL with image: ' + currentURL)); + * page + * .mainFrame() + * .waitForSelector('img') + * .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 browser.close(); * })(); * ``` + * * @param selector - The selector to query and wait for. * @param options - Options for customizing waiting behavior. * @returns An element matching the given selector. @@ -311,25 +327,27 @@ export class ElementHandle< * automatically. * * This method works across navigation + * * ```ts * const puppeteer = require('puppeteer'); * (async () => { - * const browser = await puppeteer.launch(); - * const page = await browser.newPage(); - * let currentURL; - * page - * .waitForXPath('//img') - * .then(() => console.log('First URL with image: ' + currentURL)); - * for (currentURL of [ - * 'https://example.com', - * 'https://google.com', - * 'https://bbc.com', - * ]) { - * await page.goto(currentURL); - * } - * await browser.close(); + * const browser = await puppeteer.launch(); + * const page = await browser.newPage(); + * let currentURL; + * page + * .waitForXPath('//img') + * .then(() => console.log('First URL with image: ' + currentURL)); + * for (currentURL of [ + * 'https://example.com', + * 'https://google.com', + * 'https://bbc.com', + * ]) { + * await page.goto(currentURL); + * } + * await browser.close(); * })(); * ``` + * * @param xpath - A * {@link https://developer.mozilla.org/en-US/docs/Web/XPath | xpath} of an * element to wait for @@ -665,13 +683,15 @@ export class ElementHandle< * throws an error. * * @example + * * ```ts * handle.select('blue'); // single selection * handle.select('red', 'green', 'blue'); // multiple selections * ``` + * * @param values - Values of options to select. If the `