docs: generate api.md off documentation model (#4832)

This commit is contained in:
Pavel Feldman 2020-12-28 07:03:09 -08:00 committed by GitHub
parent fee7dd7cc1
commit a446792c18
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 1657 additions and 1137 deletions

View File

@ -827,12 +827,12 @@ Emitted when a frame is navigated to a new url.
Emitted when the JavaScript [`load`](https://developer.mozilla.org/en-US/docs/Web/Events/load) event is dispatched.
## event: Page.pageerror
- type: <[Error]> The exception message
- type: <[Error]>
Emitted when an uncaught exception happens within the page.
## event: Page.popup
- type: <[Page]> Page corresponding to "popup" window
- type: <[Page]>
Emitted when the page opens a new tab or window. This event is emitted in addition to the [`event:
BrowserContext.page`](), but only for popups relevant to this page.
@ -879,7 +879,7 @@ Emitted when [response] status and headers are received for a request. For a suc
is `request`, `response` and `requestfinished`.
## event: Page.websocket
- type: <[WebSocket]> websocket
- type: <[WebSocket]>
Emitted when <[WebSocket]> request is sent.
@ -1046,7 +1046,7 @@ This method checks an element matching [`param: selector`]() by performing the f
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`property: Page.mouse`]() to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
1. Ensure that the element is now checked. If not, this method rejects.
@ -1069,7 +1069,7 @@ This method clicks an element matching [`param: selector`]() by performing the f
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to click in the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -1134,7 +1134,7 @@ This method double clicks an element matching [`param: selector`]() by performin
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to double click in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to double click in the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -1608,7 +1608,7 @@ This method hovers over an element matching [`param: selector`]() by performing
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to hover over the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to hover over the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -2075,7 +2075,7 @@ This method taps an element matching [`param: selector`]() by performing the fol
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.touchscreen](#pagetouchscreen#pagetouchscreen) to tap the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.touchscreen`]() to tap the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -2151,7 +2151,7 @@ This method unchecks an element matching [`param: selector`]() by performing the
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`property: Page.mouse`]() to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
1. Ensure that the element is now unchecked. If not, this method rejects.
@ -2602,7 +2602,7 @@ This method checks an element matching [`param: selector`]() by performing the f
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`property: Page.mouse`]() to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
1. Ensure that the element is now checked. If not, this method rejects.
@ -2626,7 +2626,7 @@ This method clicks an element matching [`param: selector`]() by performing the f
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to click in the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -2661,7 +2661,7 @@ This method double clicks an element matching [`param: selector`]() by performin
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to double click in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to double click in the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -2916,7 +2916,7 @@ This method hovers over an element matching [`param: selector`]() by performing
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to hover over the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to hover over the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -3079,7 +3079,7 @@ This method taps an element matching [`param: selector`]() by performing the fol
1. Find an element match matching [`param: selector`](). If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.touchscreen](#pagetouchscreen#pagetouchscreen) to tap the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.touchscreen`]() to tap the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
When all steps combined have not finished during the specified [`option: timeout`](), this method rejects with a
@ -3148,7 +3148,7 @@ This method checks an element matching [`param: selector`]() by performing the f
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless [`option: force`]() option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`property: Page.mouse`]() to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
1. Ensure that the element is now unchecked. If not, this method rejects.
@ -3460,7 +3460,7 @@ This method checks the element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`]() option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`property: Page.mouse`]() to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
1. Ensure that the element is now checked. If not, this method rejects.
@ -3480,7 +3480,7 @@ When all steps combined have not finished during the specified [`option: timeout
This method clicks the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`]() option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to click in the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3514,7 +3514,7 @@ Returns the content frame for element handles referencing iframe nodes, or `null
This method double clicks the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`]() option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to double click in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to double click in the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3613,7 +3613,7 @@ Attribute name to get the value for.
This method hovers over the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`]() option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to hover over the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.mouse`]() to hover over the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3786,7 +3786,7 @@ are resolved relative to the the current working directory. For empty array, cle
This method taps the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`]() option is set.
1. Scroll the element into view if needed.
1. Use [page.touchscreen](#pagetouchscreen) to tap in the center of the element, or the specified [`option: position`]().
1. Use [`property: Page.touchscreen`]() to tap the center of the element, or the specified [`option: position`]().
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3853,7 +3853,7 @@ This method checks the element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the element, unless [`option: force`]() option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`property: Page.mouse`]() to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless [`option: noWaitAfter`]() option is set.
1. Ensure that the element is now unchecked. If not, this method rejects.
@ -4399,7 +4399,7 @@ Name of the key to press or a character to generate, such as `ArrowLeft` or `a`.
The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport.
Every `page` object has its own Mouse, accessible with [page.mouse](#pagemouse).
Every `page` object has its own Mouse, accessible with [`property: Page.mouse`]().
```js
// Using page.mouse to trace a 100x100 square.
@ -4874,19 +4874,19 @@ The [WebSocket] class represents websocket connections in the page.
Fired when the websocket closes.
## event: WebSocket.framereceived
- type: <[Object]> web socket frame data
- type: <[Object]>
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket recieves a frame.
## event: WebSocket.framesent
- type: <[Object]> web socket frame data
- type: <[Object]>
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket sends a frame.
## event: WebSocket.socketerror
- type: <[String]> the error message
- type: <[String]>
Fired when the websocket has an error.
@ -4972,7 +4972,7 @@ assistive technologies themselves. By default, Playwright tries to approximate t
- `haspopup` <[string]> What kind of popup is currently being shown for a node, if applicable.
- `invalid` <[string]> Whether and in what way this node's value is invalid, if applicable.
- `orientation` <[string]> Whether the node is oriented horizontally or vertically, if applicable.
- `children` <[Array]<[Object]>> Child [AXNode]s of this node, if any, if applicable.
- `children` <[Array]<[Object]>> Child nodes, if any, if applicable.
Captures the current state of the accessibility tree. The returned object represents the root accessible node of the
page.

View File

@ -155,63 +155,3 @@ const { chromium } = require('playwright');
> **NOTE** It is not yet possible to test extension popups or content scripts.
[AXNode]: #accessibilitysnapshotoptions "AXNode"
[Accessibility]: #class-accessibility "Accessibility"
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
[Body]: #class-body "Body"
[BrowserServer]: #class-browserserver "BrowserServer"
[BrowserContext]: #class-browsercontext "BrowserContext"
[BrowserType]: #class-browsertype "BrowserType"
[Browser]: #class-browser "Browser"
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
[ChromiumBrowserContext]: #class-chromiumbrowsercontext "ChromiumBrowserContext"
[ChromiumCoverage]: #class-chromiumcoverage "ChromiumCoverage"
[CDPSession]: #class-cdpsession "CDPSession"
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
[Dialog]: #class-dialog "Dialog"
[Download]: #class-download "Download"
[ElementHandle]: #class-elementhandle "ElementHandle"
[Element]: https://developer.mozilla.org/en-US/docs/Web/API/element "Element"
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
[EvaluationArgument]: #evaluationargument "Evaluation Argument"
[File]: #class-file "https://developer.mozilla.org/en-US/docs/Web/API/File"
[FileChooser]: #class-filechooser "FileChooser"
[FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser"
[Frame]: #class-frame "Frame"
[JSHandle]: #class-jshandle "JSHandle"
[Keyboard]: #class-keyboard "Keyboard"
[Logger]: #class-logger "Logger"
[Map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map "Map"
[Mouse]: #class-mouse "Mouse"
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object"
[Page]: #class-page "Page"
[Playwright]: #class-playwright "Playwright"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
[Request]: #class-request "Request"
[Response]: #class-response "Response"
[Route]: #class-route "Route"
[Selectors]: #class-selectors "Selectors"
[Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable"
[TimeoutError]: #class-timeouterror "TimeoutError"
[Touchscreen]: #class-touchscreen "Touchscreen"
[UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail"
[URL]: https://nodejs.org/api/url.html
[USKeyboardLayout]: ../src/usKeyboardLayout.ts "USKeyboardLayout"
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
[Video]: #class-video "Video"
[WebKitBrowser]: #class-webkitbrowser "WebKitBrowser"
[WebSocket]: #class-websocket "WebSocket"
[Worker]: #class-worker "Worker"
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function "Function"
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
[null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin "Origin"
[selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors "selector"
[Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "Readable"
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[xpath]: https://developer.mozilla.org/en-US/docs/Web/XPath "xpath"

25
docs-src/api-links.md Normal file
View File

@ -0,0 +1,25 @@
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
[Element]: https://developer.mozilla.org/en-US/docs/Web/API/element "Element"
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
[EvaluationArgument]: #evaluationargument "Evaluation Argument"
[Map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map "Map"
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp "RegExp"
[Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable"
[UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail"
[URL]: https://nodejs.org/api/url.html "URL"
[USKeyboardLayout]: ../src/usKeyboardLayout.ts "USKeyboardLayout"
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function "Function"
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
[null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null "null"
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin "Origin"
[selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors "selector"
[Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "Readable"
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "string"
[xpath]: https://developer.mozilla.org/en-US/docs/Web/XPath "xpath"

View File

@ -170,7 +170,7 @@ Whether or not to enable JavaScript in the context. Defaults to `true`.
## context-option-timezoneid
- `timezoneId` <[string]>
Changes the timezone of the context. See [ICUs `metaZones.txt`](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1)
Changes the timezone of the context. See [ICU's metaZones.txt](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1)
for a list of supported timezone IDs.
## context-option-geolocation

View File

@ -132,6 +132,8 @@ Selectors can be used to install custom selector engines. See [Working with sele
This object can be used to launch or connect to WebKit, returning instances of [WebKitBrowser].
[Playwright]: #class-playwright "Playwright"
### class: Browser
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
@ -246,7 +248,7 @@ Indicates that the browser is connected.
- `localStorage` <[Array]<[Object]>>
- `name` <[string]>
- `value` <[string]>
- `timezoneId` <[string]> Changes the timezone of the context. See [ICUs `metaZones.txt`](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs.
- `timezoneId` <[string]> Changes the timezone of the context. See [ICU's metaZones.txt](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs.
- `userAgent` <[string]> Specific user agent to use in this context.
- `videoSize` <[Object]> **NOTE** Use `recordVideo` instead, it takes precedence over `videoSize`. Specifies dimensions of the automatically recorded video. Can only be used if `videosPath` is set. If not specified the size will be equal to `viewport`. If `viewport` is not configured explicitly the video size defaults to 1280x720. Actual picture of the page will be scaled down if necessary to fit specified size.
- `width` <[number]> Video frame width.
@ -321,7 +323,7 @@ Creates a new browser context. It won't share cookies/cache with other browser c
- `localStorage` <[Array]<[Object]>>
- `name` <[string]>
- `value` <[string]>
- `timezoneId` <[string]> Changes the timezone of the context. See [ICUs `metaZones.txt`](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs.
- `timezoneId` <[string]> Changes the timezone of the context. See [ICU's metaZones.txt](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs.
- `userAgent` <[string]> Specific user agent to use in this context.
- `videoSize` <[Object]> **NOTE** Use `recordVideo` instead, it takes precedence over `videoSize`. Specifies dimensions of the automatically recorded video. Can only be used if `videosPath` is set. If not specified the size will be equal to `viewport`. If `viewport` is not configured explicitly the video size defaults to 1280x720. Actual picture of the page will be scaled down if necessary to fit specified size.
- `width` <[number]> Video frame width.
@ -341,6 +343,8 @@ This is a convenience API that should only be used for the single-page scenarios
Returns the browser version.
[Browser]: #class-browser "Browser"
### class: BrowserContext
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
@ -397,7 +401,7 @@ Emitted when Browser context gets closed. This might happen because of one of th
#### browserContext.on('page')
- type: <[Page]>
The event is emitted when a new Page is created in the BrowserContext. The page may still be loading. The event will also fire for popup pages. See also [page.on('popup')](#pageonpopup) to receive events about popups relevant to a specific page.
The event is emitted when a new Page is created in the BrowserContext. The page may still be loading. The event will also fire for popup pages. See also [`page.on('popup')`](#pageonpopup) to receive events about popups relevant to a specific page.
The earliest moment that page is available is when it has navigated to the initial url. For example, when opening a popup with `window.open('http://example.com')`, this event will fire when the network request to "http://example.com" is done and its response has started loading in the popup.
@ -752,6 +756,8 @@ const context = await browser.newContext();
await context.grantPermissions(['geolocation']);
```
[BrowserContext]: #class-browsercontext "BrowserContext"
### class: Page
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
@ -979,14 +985,14 @@ Emitted when a frame is navigated to a new url.
Emitted when the JavaScript [`load`](https://developer.mozilla.org/en-US/docs/Web/Events/load) event is dispatched.
#### page.on('pageerror')
- type: <[Error]> The exception message
- type: <[Error]>
Emitted when an uncaught exception happens within the page.
#### page.on('popup')
- type: <[Page]> Page corresponding to "popup" window
- type: <[Page]>
Emitted when the page opens a new tab or window. This event is emitted in addition to the [browserContext.on('page')](#browsercontextonpage), but only for popups relevant to this page.
Emitted when the page opens a new tab or window. This event is emitted in addition to the [`browserContext.on('page')`](#browsercontextonpage), but only for popups relevant to this page.
The earliest moment that page is available is when it has navigated to the initial url. For example, when opening a popup with `window.open('http://example.com')`, this event will fire when the network request to "http://example.com" is done and its response has started loading in the popup.
@ -1010,7 +1016,7 @@ Emitted when a page issues a request. The [request] object is read-only. In orde
Emitted when a request fails, for example by timing out.
> **NOTE** HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will complete with [page.on('requestfinished')](#pageonrequestfinished) event and not with [page.on('requestfailed')](#pageonrequestfailed).
> **NOTE** HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will complete with [`page.on('requestfinished')`](#pageonrequestfinished) event and not with [`page.on('requestfailed')`](#pageonrequestfailed).
#### page.on('requestfinished')
- type: <[Request]>
@ -1023,7 +1029,7 @@ Emitted when a request finishes successfully after downloading the response body
Emitted when [response] status and headers are received for a request. For a successful response, the sequence of events is `request`, `response` and `requestfinished`.
#### page.on('websocket')
- type: <[WebSocket]> websocket
- type: <[WebSocket]>
Emitted when <[WebSocket]> request is sent.
@ -1154,7 +1160,7 @@ This method checks an element matching `selector` by performing the following st
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
1. Ensure that the element is now checked. If not, this method rejects.
@ -1181,7 +1187,7 @@ This method clicks an element matching `selector` by performing the following st
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -1198,7 +1204,7 @@ If `runBeforeUnload` is `false`, does not run any unload handlers and waits for
By default, `page.close()` **does not** run `beforeunload` handlers.
> **NOTE** if `runBeforeUnload` is passed as true, a `beforeunload` dialog might be summoned
> and should be handled manually via [page.on('dialog')](#pageondialog) event.
> and should be handled manually via [`page.on('dialog')`](#pageondialog) event.
#### page.content()
- returns: <[Promise]<[string]>>
@ -1233,7 +1239,7 @@ This method double clicks an element matching `selector` by performing the follo
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to double click in the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to double click in the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -1614,7 +1620,7 @@ This method hovers over an element matching `selector` by performing the followi
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to hover over the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to hover over the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -1943,7 +1949,7 @@ This method taps an element matching `selector` by performing the following step
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.touchscreen](#pagetouchscreen#pagetouchscreen) to tap the center of the element, or the specified `position`.
1. Use [`page.touchscreen`](#pagetouchscreen) to tap the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -2001,7 +2007,7 @@ This method unchecks an element matching `selector` by performing the following
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
1. Ensure that the element is now unchecked. If not, this method rejects.
@ -2218,14 +2224,16 @@ This method returns all of the dedicated [WebWorkers](https://developer.mozilla.
> **NOTE** This does not contain ServiceWorkers
[Page]: #class-page "Page"
### class: Frame
At every point of time, page exposes its current frame tree via the [`page.mainFrame()`](#pagemainframe) and [`frame.childFrames()`](#framechildframes) methods.
[Frame] object's lifecycle is controlled by three events, dispatched on the page object:
* [page.on('frameattached')](#pageonframeattached) - fired when the frame gets attached to the page. A Frame can be attached to the page only once.
* [page.on('framenavigated')](#pageonframenavigated) - fired when the frame commits navigation to a different URL.
* [page.on('framedetached')](#pageonframedetached) - fired when the frame gets detached from the page. A Frame can be detached from the page only once.
* [`page.on('frameattached')`](#pageonframeattached) - fired when the frame gets attached to the page. A Frame can be attached to the page only once.
* [`page.on('framenavigated')`](#pageonframenavigated) - fired when the frame commits navigation to a different URL.
* [`page.on('framedetached')`](#pageonframedetached) - fired when the frame gets detached from the page. A Frame can be detached from the page only once.
An example of dumping frame tree:
@ -2390,7 +2398,7 @@ This method checks an element matching `selector` by performing the following st
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
1. Ensure that the element is now checked. If not, this method rejects.
@ -2418,7 +2426,7 @@ This method clicks an element matching `selector` by performing the following st
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -2446,7 +2454,7 @@ This method double clicks an element matching `selector` by performing the follo
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to double click in the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to double click in the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -2633,7 +2641,7 @@ This method hovers over an element matching `selector` by performing the followi
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to hover over the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to hover over the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -2766,7 +2774,7 @@ This method taps an element matching `selector` by performing the following step
1. Find an element match matching `selector`. If there is none, wait until a matching element is attached to the DOM.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.touchscreen](#pagetouchscreen#pagetouchscreen) to tap the center of the element, or the specified `position`.
1. Use [`page.touchscreen`](#pagetouchscreen) to tap the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
When all steps combined have not finished during the specified `timeout`, this method rejects with a [TimeoutError]. Passing zero timeout disables this.
@ -2817,7 +2825,7 @@ This method checks an element matching `selector` by performing the following st
1. Ensure that matched element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the matched element, unless `force` option is set. If the element is detached during the checks, the whole action is retried.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
1. Ensure that the element is now unchecked. If not, this method rejects.
@ -2943,6 +2951,8 @@ Waits for the given `timeout` in milliseconds.
Note that `frame.waitForTimeout()` should only be used for debugging. Tests using the timer in production are going to be flaky. Use signals such as network events, selectors becoming visible and others instead.
[Frame]: #class-frame "Frame"
### class: ElementHandle
* extends: [JSHandle]
@ -3097,7 +3107,7 @@ This method checks the element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already checked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
1. Ensure that the element is now checked. If not, this method rejects.
@ -3122,7 +3132,7 @@ When all steps combined have not finished during the specified `timeout`, this m
This method clicks the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3150,7 +3160,7 @@ Returns the content frame for element handles referencing iframe nodes, or `null
This method double clicks the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to double click in the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to double click in the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set. Note that if the first click of the `dblclick()` triggers a navigation event, this method will reject.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3222,7 +3232,7 @@ Returns element attribute value.
This method hovers over the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to hover over the center of the element, or the specified `position`.
1. Use [`page.mouse`](#pagemouse) to hover over the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3351,7 +3361,7 @@ Sets the value of the file input to these file paths or files. If some of the `f
This method taps the element by performing the following steps:
1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
1. Scroll the element into view if needed.
1. Use [page.touchscreen](#pagetouchscreen) to tap in the center of the element, or the specified `position`.
1. Use [`page.touchscreen`](#pagetouchscreen) to tap the center of the element, or the specified `position`.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
If the element is detached from the DOM at any moment during the action, this method rejects.
@ -3404,7 +3414,7 @@ This method checks the element by performing the following steps:
1. Ensure that element is a checkbox or a radio input. If not, this method rejects. If the element is already unchecked, this method returns immediately.
1. Wait for [actionability](./actionability.md) checks on the element, unless `force` option is set.
1. Scroll the element into view if needed.
1. Use [page.mouse](#pagemouse) to click in the center of the element.
1. Use [`page.mouse`](#pagemouse) to click in the center of the element.
1. Wait for initiated navigations to either succeed or fail, unless `noWaitAfter` option is set.
1. Ensure that the element is now unchecked. If not, this method rejects.
@ -3453,6 +3463,8 @@ const span = await div.waitForSelector('span', { state: 'attached' });
> **NOTE** This method does not work across navigations, use [`page.waitForSelector(selector[, options])`](#pagewaitforselectorselector-options) instead.
[ElementHandle]: #class-elementhandle "ElementHandle"
### class: JSHandle
JSHandle represents an in-page JavaScript object. JSHandles can be created with the [`page.evaluateHandle(pageFunction[, arg])`](#pageevaluatehandlepagefunction-arg) method.
@ -3545,9 +3557,11 @@ Returns a JSON representation of the object. If the object has a `toJSON` functi
> **NOTE** The method will return an empty JSON object if the referenced object is not stringifiable. It will throw an error if the object has circular references.
[JSHandle]: #class-jshandle "JSHandle"
### class: ConsoleMessage
[ConsoleMessage] objects are dispatched by page via the [page.on('console')](#pageonconsole) event.
[ConsoleMessage] objects are dispatched by page via the [`page.on('console')`](#pageonconsole) event.
<!-- GEN:toc -->
- [consoleMessage.args()](#consolemessageargs)
@ -3573,9 +3587,11 @@ Returns a JSON representation of the object. If the object has a `toJSON` functi
One of the following values: `'log'`, `'debug'`, `'info'`, `'error'`, `'warning'`, `'dir'`, `'dirxml'`, `'table'`, `'trace'`, `'clear'`, `'startGroup'`, `'startGroupCollapsed'`, `'endGroup'`, `'assert'`, `'profile'`, `'profileEnd'`, `'count'`, `'timeEnd'`.
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
### class: Dialog
[Dialog] objects are dispatched by page via the [page.on('dialog')](#pageondialog) event.
[Dialog] objects are dispatched by page via the [`page.on('dialog')`](#pageondialog) event.
An example of using `Dialog` class:
@ -3628,9 +3644,11 @@ A message displayed in the dialog.
Returns dialog's type, can be one of `alert`, `beforeunload`, `confirm` or `prompt`.
[Dialog]: #class-dialog "Dialog"
### class: Download
[Download] objects are dispatched by page via the [page.on('download')](#pageondownload) event.
[Download] objects are dispatched by page via the [`page.on('download')`](#pageondownload) event.
All the downloaded files belonging to the browser context are deleted when the browser context is closed. All downloaded files are deleted when the browser closes.
@ -3694,6 +3712,8 @@ Returns suggested filename for this download. It is typically computed by the br
Returns downloaded url.
[Download]: #class-download "Download"
### class: Video
When browser context is created with the `videosPath` option, each page has a video object associated with it.
@ -3711,9 +3731,11 @@ console.log(await page.video().path());
Returns the file system path this video will be recorded to. The video is guaranteed to be written to the filesystem upon closing the browser context.
[Video]: #class-video "Video"
### class: FileChooser
[FileChooser] objects are dispatched by the page in the [page.on('filechooser')](#pageonfilechooser) event.
[FileChooser] objects are dispatched by the page in the [`page.on('filechooser')`](#pageonfilechooser) event.
```js
page.on('filechooser', async (fileChooser) => {
@ -3755,6 +3777,8 @@ Returns page this file chooser belongs to.
Sets the value of the file input this chooser is associated with. If some of the `filePaths` are relative paths, then they are resolved relative to the the current working directory. For empty array, clears the selected files.
[FileChooser]: #class-filechooser "FileChooser"
### class: Keyboard
Keyboard provides an api for managing a virtual keyboard. The high level api is [`keyboard.type(text[, options])`](#keyboardtypetext-options), which takes raw characters and generates proper keydown, keypress/input, and keyup events on your page.
@ -3890,11 +3914,13 @@ await page.keyboard.type('World', {delay: 100}); // Types slower, like a user
Dispatches a `keyup` event.
[Keyboard]: #class-keyboard "Keyboard"
### class: Mouse
The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport.
Every `page` object has its own Mouse, accessible with [page.mouse](#pagemouse).
Every `page` object has its own Mouse, accessible with [`page.mouse`](#pagemouse).
```js
// Using page.mouse to trace a 100x100 square.
@ -3961,6 +3987,8 @@ Dispatches a `mousemove` event.
Dispatches a `mouseup` event.
[Mouse]: #class-mouse "Mouse"
### class: Touchscreen
The Touchscreen class operates in main-frame CSS pixels relative to the top-left corner of the viewport. Methods on the touchscreen can only be used in browser contexts that have been intialized with `hasTouch` set to true.
@ -3972,14 +4000,16 @@ The Touchscreen class operates in main-frame CSS pixels relative to the top-left
Dispatches a `touchstart` and `touchend` event with a single touch at the position (`x`,`y`).
[Touchscreen]: #class-touchscreen "Touchscreen"
### class: Request
Whenever the page sends a request for a network resource the following sequence of events are emitted by [Page]:
* [page.on('request')](#pageonrequest) emitted when the request is issued by the page.
* [page.on('response')](#pageonresponse) emitted when/if the response status and headers are received for the request.
* [page.on('requestfinished')](#pageonrequestfinished) emitted when the response body is downloaded and the request is complete.
* [`page.on('request')`](#pageonrequest) emitted when the request is issued by the page.
* [`page.on('response')`](#pageonresponse) emitted when/if the response status and headers are received for the request.
* [`page.on('requestfinished')`](#pageonrequestfinished) emitted when the response body is downloaded and the request is complete.
If request fails at some point, then instead of `'requestfinished'` event (and possibly instead of 'response' event), the [page.on('requestfailed')](#pageonrequestfailed) event is emitted.
If request fails at some point, then instead of `'requestfinished'` event (and possibly instead of 'response' event), the [`page.on('requestfailed')`](#pageonrequestfailed) event is emitted.
> **NOTE** HTTP Error responses, such as 404 or 503, are still successful responses from HTTP standpoint, so request will complete with `'requestfinished'` event.
@ -4122,6 +4152,8 @@ console.log(request.timing());
URL of the request.
[Request]: #class-request "Request"
### class: Response
[Response] class represents responses which are received by page.
@ -4197,6 +4229,8 @@ Returns the text representation of response body.
Contains the URL of the response.
[Response]: #class-response "Response"
### class: Selectors
Selectors can be used to install custom selector engines. See [Working with selectors](#working-with-selectors) for more information.
@ -4251,6 +4285,8 @@ const { selectors, firefox } = require('playwright'); // Or 'chromium' or 'webk
})();
```
[Selectors]: #class-selectors "Selectors"
### class: Route
Whenever a network route is set up with [`page.route(url, handler)`](#pagerouteurl-handler) or [`browserContext.route(url, handler)`](#browsercontextrouteurl-handler), the `Route` object allows to handle the route.
@ -4338,6 +4374,8 @@ await page.route('**/xhr_endpoint', route => route.fulfill({ path: 'mock_data.js
A request to be routed.
[Route]: #class-route "Route"
### class: WebSocket
The [WebSocket] class represents websocket connections in the page.
@ -4357,19 +4395,19 @@ The [WebSocket] class represents websocket connections in the page.
Fired when the websocket closes.
#### webSocket.on('framereceived')
- type: <[Object]> web socket frame data
- type: <[Object]>
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket recieves a frame.
#### webSocket.on('framesent')
- type: <[Object]> web socket frame data
- type: <[Object]>
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket sends a frame.
#### webSocket.on('socketerror')
- type: <[String]> the error message
- type: <[String]>
Fired when the websocket has an error.
@ -4394,11 +4432,15 @@ Returns the event data value.
Waits for event to fire and passes its value into the predicate function. Returns when the predicate returns truthy value. Will throw an error if the webSocket is closed before the event is fired.
[WebSocket]: #class-websocket "WebSocket"
### class: TimeoutError
* extends: [Error]
TimeoutError is emitted whenever certain operations are terminated due to timeout, e.g. [`page.waitForSelector(selector[, options])`](#pagewaitforselectorselector-options) or [`browserType.launch([options])`](#browsertypelaunchoptions).
[TimeoutError]: #class-timeouterror "TimeoutError"
### class: Accessibility
The Accessibility class provides methods for inspecting Chromium's accessibility tree. The accessibility tree is used by assistive technology such as [screen readers](https://en.wikipedia.org/wiki/Screen_reader) or [switches](https://en.wikipedia.org/wiki/Switch_access).
@ -4434,8 +4476,8 @@ Most of the accessibility tree gets filtered out when converting from Blink AX T
- `readonly` <[boolean]> Whether the node is read only, if applicable.
- `required` <[boolean]> Whether the node is required, if applicable.
- `selected` <[boolean]> Whether the node is selected in its parent node, if applicable.
- `checked` <[boolean]|"mixed"> Whether the checkbox is checked, or "mixed", if applicable.
- `pressed` <[boolean]|"mixed"> Whether the toggle button is checked, or "mixed", if applicable.
- `checked` <boolean|"mixed"> Whether the checkbox is checked, or "mixed", if applicable.
- `pressed` <boolean|"mixed"> Whether the toggle button is checked, or "mixed", if applicable.
- `level` <[number]> The level of a heading, if applicable.
- `valuemin` <[number]> The minimum value in a node, if applicable.
- `valuemax` <[number]> The maximum value in a node, if applicable.
@ -4443,7 +4485,7 @@ Most of the accessibility tree gets filtered out when converting from Blink AX T
- `haspopup` <[string]> What kind of popup is currently being shown for a node, if applicable.
- `invalid` <[string]> Whether and in what way this node's value is invalid, if applicable.
- `orientation` <[string]> Whether the node is oriented horizontally or vertically, if applicable.
- `children` <[Array]<[Object]>> Child [AXNode]s of this node, if any, if applicable.
- `children` <[Array]<[Object]>> Child nodes, if any, if applicable.
Captures the current state of the accessibility tree. The returned object represents the root accessible node of the page.
@ -4474,6 +4516,8 @@ function findFocusedNode(node) {
}
```
[Accessibility]: #class-accessibility "Accessibility"
### class: Worker
The Worker class represents a [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API). `worker` event is emitted on the page object to signal a worker creation. `close` event is emitted on the worker object when the worker is gone.
@ -4526,6 +4570,8 @@ If the function passed to the `worker.evaluateHandle` returns a [Promise], then
#### worker.url()
- returns: <[string]>
[Worker]: #class-worker "Worker"
### class: BrowserServer
<!-- GEN:toc -->
@ -4562,6 +4608,8 @@ Browser websocket url.
Browser websocket endpoint which can be used as an argument to [`browserType.connect(params)`](#browsertypeconnectparams) to establish connection to the browser.
[BrowserServer]: #class-browserserver "BrowserServer"
### class: BrowserType
BrowserType provides methods to launch a specific browser instance or connect to an existing one. The following is a typical example of using Playwright to drive automation:
@ -4693,7 +4741,7 @@ const browser = await chromium.launch({ // Or 'firefox' or 'webkit'.
- `height` <[number]> Video frame height.
- `slowMo` <[number]> Slows down Playwright operations by the specified amount of milliseconds. Useful so that you can see what is going on. Defaults to 0.
- `timeout` <[number]> Maximum time in milliseconds to wait for the browser instance to start. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
- `timezoneId` <[string]> Changes the timezone of the context. See [ICUs `metaZones.txt`](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs.
- `timezoneId` <[string]> Changes the timezone of the context. See [ICU's metaZones.txt](https://cs.chromium.org/chromium/src/third_party/icu/source/data/misc/metaZones.txt?rcl=faee8bc70570192d82d2978a71e2a615788597d1) for a list of supported timezone IDs.
- `userAgent` <[string]> Specific user agent to use in this context.
- `videoSize` <[Object]> **NOTE** Use `recordVideo` instead, it takes precedence over `videoSize`. Specifies dimensions of the automatically recorded video. Can only be used if `videosPath` is set. If not specified the size will be equal to `viewport`. If `viewport` is not configured explicitly the video size defaults to 1280x720. Actual picture of the page will be scaled down if necessary to fit specified size.
- `width` <[number]> Video frame width.
@ -4754,6 +4802,8 @@ const { chromium } = require('playwright'); // Or 'webkit' or 'firefox'.
Returns browser name. For example: `'chromium'`, `'webkit'` or `'firefox'`.
[BrowserType]: #class-browsertype "BrowserType"
### class: Logger
Playwright generates a lot of logs and they are accessible via the pluggable logger sink.
@ -4792,6 +4842,8 @@ Determines whether sink is interested in the logger with the given name and seve
- `hints` <[Object]> optional formatting hints
- `color` <[string]> Optional preferred logger color.
[Logger]: #class-logger "Logger"
### class: ChromiumBrowser
* extends: [Browser]
@ -4839,6 +4891,8 @@ Only one trace can be active at a time per browser.
Returns the buffer with trace data.
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
### class: ChromiumBrowserContext
* extends: [BrowserContext]
@ -4911,6 +4965,8 @@ Returns the newly created session.
All existing service workers in the context.
[ChromiumBrowserContext]: #class-chromiumbrowsercontext "ChromiumBrowserContext"
### class: ChromiumCoverage
Coverage gathers information about parts of JavaScript and CSS that were used by the page.
@ -4990,6 +5046,8 @@ Returns the array of coverage reports for all scripts
> **NOTE** JavaScript Coverage doesn't include anonymous scripts by default. However, scripts with sourceURLs are reported.
[ChromiumCoverage]: #class-chromiumcoverage "ChromiumCoverage"
### class: CDPSession
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
@ -5027,6 +5085,8 @@ Detaches the CDPSession from the target. Once detached, the CDPSession object wo
- `params` <[Object]> Optional method parameters
- returns: <[Promise]<[Object]>>
[CDPSession]: #class-cdpsession "CDPSession"
### class: FirefoxBrowser
* extends: [Browser]
@ -5042,6 +5102,8 @@ Firefox browser instance does not expose Firefox-specific features.
- [browser.version()](#browserversion)
<!-- GEN:stop -->
[FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser"
### class: WebKitBrowser
* extends: [Browser]
@ -5057,6 +5119,34 @@ WebKit browser instance does not expose WebKit-specific features.
- [browser.version()](#browserversion)
<!-- GEN:stop -->
[WebKitBrowser]: #class-webkitbrowser "WebKitBrowser"
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
[Element]: https://developer.mozilla.org/en-US/docs/Web/API/element "Element"
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
[EvaluationArgument]: #evaluationargument "Evaluation Argument"
[Map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map "Map"
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp "RegExp"
[Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable"
[UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail"
[URL]: https://nodejs.org/api/url.html "URL"
[USKeyboardLayout]: ../src/usKeyboardLayout.ts "USKeyboardLayout"
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function "Function"
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
[null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null "null"
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin "Origin"
[selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors "selector"
[Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "Readable"
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "string"
[xpath]: https://developer.mozilla.org/en-US/docs/Web/XPath "xpath"
### EvaluationArgument
Playwright evaluation methods like [page.evaluate(pageFunction[, arg])](#pageevaluatepagefunction-arg) take a single optional argument. This argument can be a mix of [Serializable] values and [JSHandle] or [ElementHandle] instances. Handles are automatically converted to the value they represent.
@ -5214,63 +5304,3 @@ const { chromium } = require('playwright');
> **NOTE** It is not yet possible to test extension popups or content scripts.
[AXNode]: #accessibilitysnapshotoptions "AXNode"
[Accessibility]: #class-accessibility "Accessibility"
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
[Body]: #class-body "Body"
[BrowserServer]: #class-browserserver "BrowserServer"
[BrowserContext]: #class-browsercontext "BrowserContext"
[BrowserType]: #class-browsertype "BrowserType"
[Browser]: #class-browser "Browser"
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
[ChromiumBrowserContext]: #class-chromiumbrowsercontext "ChromiumBrowserContext"
[ChromiumCoverage]: #class-chromiumcoverage "ChromiumCoverage"
[CDPSession]: #class-cdpsession "CDPSession"
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
[Dialog]: #class-dialog "Dialog"
[Download]: #class-download "Download"
[ElementHandle]: #class-elementhandle "ElementHandle"
[Element]: https://developer.mozilla.org/en-US/docs/Web/API/element "Element"
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
[EvaluationArgument]: #evaluationargument "Evaluation Argument"
[File]: #class-file "https://developer.mozilla.org/en-US/docs/Web/API/File"
[FileChooser]: #class-filechooser "FileChooser"
[FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser"
[Frame]: #class-frame "Frame"
[JSHandle]: #class-jshandle "JSHandle"
[Keyboard]: #class-keyboard "Keyboard"
[Logger]: #class-logger "Logger"
[Map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map "Map"
[Mouse]: #class-mouse "Mouse"
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object"
[Page]: #class-page "Page"
[Playwright]: #class-playwright "Playwright"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
[Request]: #class-request "Request"
[Response]: #class-response "Response"
[Route]: #class-route "Route"
[Selectors]: #class-selectors "Selectors"
[Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable"
[TimeoutError]: #class-timeouterror "TimeoutError"
[Touchscreen]: #class-touchscreen "Touchscreen"
[UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail"
[URL]: https://nodejs.org/api/url.html
[USKeyboardLayout]: ../src/usKeyboardLayout.ts "USKeyboardLayout"
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
[Video]: #class-video "Video"
[WebKitBrowser]: #class-webkitbrowser "WebKitBrowser"
[WebSocket]: #class-websocket "WebSocket"
[Worker]: #class-worker "Worker"
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function "Function"
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
[null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin "Origin"
[selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors "selector"
[Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "Readable"
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[xpath]: https://developer.mozilla.org/en-US/docs/Web/XPath "xpath"

2033
types/types.d.ts vendored

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
// @ts-check
const { parseArgument } = require('../../parse_md');
const { parseArgument, renderMd, clone } = require('../../parse_md');
const Documentation = require('./Documentation');
/** @typedef {import('./Documentation').MarkdownNode} MarkdownNode */
@ -24,8 +24,9 @@ const Documentation = require('./Documentation');
class MDOutline {
/**
* @param {MarkdownNode[]} api
* @param {string=} links
*/
constructor(api) {
constructor(api, links = '') {
this.classesArray = /** @type {Documentation.Class[]} */ [];
this.classes = /** @type {Map<string, Documentation.Class>} */ new Map();
for (const clazz of api) {
@ -33,10 +34,20 @@ class MDOutline {
this.classesArray.push(c);
this.classes.set(c.name, c);
}
this.signatures = this._generateComments();
const linksMap = new Map();
for (const link of links.replace(/\r\n/g, '\n').split('\n')) {
if (!link)
continue;
const match = link.match(/\[([^\]]+)\]: ([^"]+) "([^"]+)"/);
linksMap.set(new RegExp('\\[' + match[1] + '\\]', 'g'), { href: match[2], label: match[3] });
}
this.signatures = this._generateComments(linksMap);
}
_generateComments() {
/**
* @param {Map<string, { href: string, label: string}>} linksMap
*/
_generateComments(linksMap) {
/**
* @type {Map<string, string>}
*/
@ -70,7 +81,9 @@ class MDOutline {
}
for (const clazz of this.classesArray)
clazz.visit(item => item.comment = renderComments(item.spec, signatures));
clazz.visit(item => patchSignatures(item.spec, signatures));
for (const clazz of this.classesArray)
clazz.visit(item => item.comment = renderCommentsForSourceCode(item.spec, linksMap));
return signatures;
}
}
@ -99,75 +112,79 @@ function parseClass(node) {
* @returns {MarkdownNode[]}
*/
function extractComments(item) {
return (item.children || []).filter(c => c.type !== 'gen' && !c.type.startsWith('h'));
return (item.children || []).filter(c => !c.type.startsWith('h') && (c.type !== 'li' || c.liType !== 'default'));
}
/**
* @param {MarkdownNode[]} spec
* @param {Map<string, { href: string, label: string}>} linksMap
*/
function renderCommentsForSourceCode(spec, linksMap) {
const comments = (spec || []).filter(n => n.type !== 'gen' && !n.type.startsWith('h') && (n.type !== 'li' || n.liType !== 'default')).map(c => clone(c));
const visit = node => {
if (node.text) {
for (const [regex, { href, label }] of linksMap)
node.text = node.text.replace(regex, `[${label}](${href})`);
// Those with in `` can have nested [], hence twice twice.
node.text = node.text.replace(/\[`([^`]+)`\]\(#([^\)]+)\)/g, '[`$1`](https://github.com/microsoft/playwright/blob/master/docs/api.md#$2)');
node.text = node.text.replace(/\[([^\]]+)\]\(#([^\)]+)\)/g, '[$1](https://github.com/microsoft/playwright/blob/master/docs/api.md#$2)');
node.text = node.text.replace(/\[`([^`]+)`\]\(\.\/([^\)]+)\)/g, '[`$1`](https://github.com/microsoft/playwright/blob/master/docs/$2)');
node.text = node.text.replace(/\[([^\]]+)\]\(\.\/([^\)]+)\)/g, '[$1](https://github.com/microsoft/playwright/blob/master/docs/$2)');
}
if (node.liType === 'bullet')
node.liType = 'default';
for (const child of node.children || [])
visit(child);
};
for (const node of comments)
visit(node);
return renderMd(comments, 10000);
// [`frame.waitForFunction(pageFunction[, arg, options])`](#framewaitforfunctionpagefunction-arg-options)
}
/**
* @param {MarkdownNode[]} spec
* @param {Map<string, string>} [signatures]
*/
function renderComments(spec, signatures) {
const result = [];
function patchSignatures(spec, signatures) {
for (const node of spec || []) {
if (node.type === 'text') {
const text = patchSignatures(node.text, signatures);
// Render comments as text.
if (text.startsWith('> ')) {
result.push('');
result.push(text);
} else {
result.push(text);
}
}
if (node.type === 'code') {
result.push('```' + node.codeLang);
for (const line of node.lines)
result.push(line);
result.push('```');
}
if (node.type === 'gen') {
// Skip
}
if (node.type === 'li' && node.liType !== 'default') {
if (node.text.startsWith('extends:'))
continue;
const visit = (node, indent) => {
result.push(`${indent}- ${patchSignatures(node.text, signatures)}`);
for (const child of node.children || [])
visit(child, indent + ' ');
};
visit(node, '');
if (node.type === 'text')
node.text = patchSignaturesInText(node.text, signatures);
if (node.type === 'li') {
node.text = patchSignaturesInText(node.text, signatures);
patchSignatures(node.children, signatures);
}
}
return result.join('\n');
}
/**
* @param {string} text
* @returns {string}
*/
function createLink(text) {
const anchor = text.toLowerCase().split(',').map(c => c.replace(/[^a-z]/g, '')).join('-');
return `[\`${text}\`](#${anchor})`;
}
/**
* @param {string} comment
* @param {Map<string, string>} signatures
*/
function patchSignatures(comment, signatures) {
function patchSignaturesInText(comment, signatures) {
if (!signatures)
return comment;
comment = comment.replace(/\[`(event|method|property):\s(JS|CDP|[A-Z])([^.]+)\.([^`]+)`\]\(\)/g, (match, type, clazzPrefix, clazz, name) => {
const className = `${clazzPrefix.toLowerCase()}${clazz}`;
if (type === 'event')
return `\`${className}.on('${name}')\``;
return createLink(`${className}.on('${name}')`);
if (type === 'method') {
const signature = signatures.get(`${clazzPrefix}${clazz}.${name}`) || '';
return `\`${className}.${name}(${signature})\``;
return createLink(`${className}.${name}(${signature})`);
}
return `\`${className}.${name}\``;
return createLink(`${className}.${name}`);
});
comment = comment.replace(/\[`(?:param|option):\s([^`]+)`\]\(\)/g, '`$1`');
comment = comment.replace(/\[([^\]]+)\]\([^\)]*\)/g, '$1');
for (const link of outgoingLinks)
comment = comment.replace(new RegExp('\\[' + link + '\\]', 'g'), link);
return comment;
return comment.replace(/\[`(?:param|option):\s([^`]+)`\]\(\)/g, '`$1`');
}
/**
@ -221,7 +238,7 @@ function parseProperty(spec) {
const text = param.text;
const name = text.substring(0, text.indexOf('<')).replace(/\`/g, '').trim();
const comments = extractComments(spec);
return Documentation.Member.createProperty(name, parseType(param), comments, guessRequired(renderComments(comments)));
return Documentation.Member.createProperty(name, parseType(param), comments, guessRequired(renderCommentsForSourceCode(comments, new Map())));
}
/**
@ -233,8 +250,8 @@ function parseType(spec) {
let typeName = type.replace(/[\[\]\\]/g, '');
const literals = typeName.match(/("[^"]+"(\|"[^"]+")*)/);
if (literals) {
const sorted = literals[1].split('|').sort((a, b) => a.localeCompare(b)).join('|');
typeName = typeName.substring(0, literals.index) + sorted + typeName.substring(literals.index + literals[0].length);
const assorted = literals[1];
typeName = typeName.substring(0, literals.index) + assorted + typeName.substring(literals.index + literals[0].length);
}
const properties = [];
const hasNonEnumProperties = typeName.split('|').some(part => {
@ -245,8 +262,7 @@ function parseType(spec) {
if (hasNonEnumProperties && spec) {
for (const child of spec.children || []) {
const { name, text } = parseArgument(child.text);
const patchedText = text.replace(/\. Optional\.$/, '.');
const comments = /** @type {MarkdownNode[]} */ ([{ type: 'text', text: patchedText }]);
const comments = /** @type {MarkdownNode[]} */ ([{ type: 'text', text }]);
properties.push(Documentation.Member.createProperty(name, parseType(child), comments, guessRequired(text)));
}
}
@ -278,11 +294,11 @@ function guessRequired(comment) {
module.exports =
/**
* @param {any} api
* @param {boolean} copyDocsFromSuperClasses
* @param {boolean=} copyDocsFromSuperClasses
*/
function(api, copyDocsFromSuperClasses) {
function(api, copyDocsFromSuperClasses = false, links = '') {
const errors = [];
const outline = new MDOutline(api);
const outline = new MDOutline(api, links);
const documentation = new Documentation(outline.classesArray);
if (copyDocsFromSuperClasses) {
@ -308,5 +324,3 @@ module.exports =
}
return { documentation, errors, outline };
};
const outgoingLinks = ['AXNode', 'Accessibility', 'Array', 'Body', 'BrowserServer', 'BrowserContext', 'BrowserType', 'Browser', 'Buffer', 'ChildProcess', 'ChromiumBrowser', 'ChromiumBrowserContext', 'ChromiumCoverage', 'CDPSession', 'ConsoleMessage', 'Dialog', 'Download', 'ElementHandle', 'Element', 'Error', 'EvaluationArgument', 'File', 'FileChooser', 'FirefoxBrowser', 'Frame', 'JSHandle', 'Keyboard', 'Logger', 'Map', 'Mouse', 'Object', 'Page', 'Playwright', 'Promise', 'RegExp', 'Request', 'Response', 'Route', 'Selectors', 'Serializable', 'TimeoutError', 'Touchscreen', 'UIEvent.detail', 'URL', 'USKeyboardLayout', 'UnixTime', 'Video', 'WebKitBrowser', 'WebSocket', 'Worker', 'boolean', 'function', 'iterator', 'null', 'number', 'origin', 'selector', 'Readable', 'string', 'xpath'];

View File

@ -24,7 +24,7 @@ const EXCLUDE_PROPERTIES = new Set([
]);
/**
* @return {!Promise<!Array<!Message>>}
* @return {!Array<!Message>}
*/
module.exports = function lint(api, jsSources) {
const mdResult = mdBuilder(api, true);

View File

@ -15,16 +15,21 @@
* limitations under the License.
*/
//@ts-check
const playwright = require('../../');
const fs = require('fs');
const path = require('path');
const Source = require('./Source');
const Message = require('./Message');
const { parseMd, renderMd, parseArgument, applyTemplates } = require('./../parse_md');
const { parseMd, renderMd, applyTemplates, clone } = require('./../parse_md');
const { spawnSync } = require('child_process');
const preprocessor = require('./preprocessor');
const mdBuilder = require('./check_public_api/MDBuilder');
/** @typedef {import('./check_public_api/Documentation').MarkdownNode} MarkdownNode */
/** @typedef {import('./check_public_api/Documentation').Type} Type */
const PROJECT_DIR = path.join(__dirname, '..', '..');
const VERSION = require(path.join(PROJECT_DIR, 'package.json')).version;
@ -51,110 +56,72 @@ async function run() {
const messages = [];
let changedFiles = false;
const header = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-header.md')).toString();
const body = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-body.md')).toString();
const footer = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-footer.md')).toString();
const links = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-links.md')).toString();
const params = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-params.md')).toString();
const apiSpec = applyTemplates(parseMd(body), parseMd(params));
// Produce api.md
{
const comment = '<!-- THIS FILE IS NOW GENERATED -->';
const header = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-header.md')).toString();
const body = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-body.md')).toString();
const footer = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-footer.md')).toString();
const params = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-params.md')).toString();
// Generate signatures
{
const nodes = applyTemplates(parseMd(body), parseMd(params));
const { outline } = mdBuilder(nodes);
const { outline } = mdBuilder(apiSpec, false);
const signatures = outline.signatures;
for (const clazz of nodes) {
clazz.type = 'h3';
for (const member of clazz.children) {
if (member.type !== 'h2')
continue;
member.type = 'h4';
const result = [];
for (const clazz of outline.classesArray) {
// Iterate over classes, create header node.
const classNode = { type: 'h3', text: `class: ${clazz.name}` };
const match = clazz.name.match(/(JS|CDP|[A-Z])(.*)/);
const varName = match[1].toLocaleLowerCase() + match[2];
result.push(classNode);
// Append link shortcut to resolve text like [Browser]
result.push({
type: 'text',
text: `[${clazz.name}]: #class-${clazz.name.toLowerCase()} "${clazz.name}"`
});
// Append class comments
classNode.children = (clazz.spec || []).map(c => clone(c));
let match = member.text.match(/(event|method|property|async method|): (JS|CDP|[A-Z])([^.]+)\.(.*)/);
if (!match)
continue;
if (match[1] === 'event') {
member.text = `${match[2].toLowerCase() + match[3]}.on('${match[4]}')`;
continue;
}
if (match[1] === 'method' || match[1] === 'async method') {
const args = [];
const argChildren = [];
const returnContainer = [];
const nonArgChildren = [];
const optionsContainer = [];
for (const item of member.children) {
if (item.type === 'li' && item.liType === 'default') {
const { type } = parseArgument(item.text);
if (match[1] === 'method')
item.text = `returns: <${type}>`;
else
item.text = `returns: <[Promise]<${type}>>`;
returnContainer.push(item);
continue;
}
if (item.type !== 'h3') {
nonArgChildren.push(item);
continue;
}
if (item.text.startsWith('param:')) {
const param = item.children[0];
if (item.children[1])
param.text += ' ' + item.children[1].text;
if (item.children.length > 2)
param.children = item.children.slice(2);
args.push(parseArgument(param.text));
argChildren.push(param);
}
if (item.text.startsWith('option:')) {
let optionsNode = optionsContainer[0];
if (!optionsNode) {
optionsNode = {
type: 'li',
text: '`options` <[Object]>',
liType: 'default',
children: [],
};
optionsContainer.push(optionsNode);
args.push(parseArgument(optionsNode.text));
}
const param = item.children[0];
if (item.children[1])
param.text += ' ' + item.children[1].text;
if (item.children.length > 2)
param.children = item.children.slice(2);
optionsNode.children.push(param);
}
for (const member of clazz.membersArray) {
// Iterate members
const memberNode = { type: 'h4', children: [] };
if (member.kind === 'event') {
memberNode.text = `${varName}.on('${member.name}')`;
} else if (member.kind === 'property') {
memberNode.text = `${varName}.${member.name}`;
} else if (member.kind === 'method') {
// Patch method signatures
const signature = signatures.get(clazz.name + '.' + member.name);
memberNode.text = `${varName}.${member.name}(${signature})`;
for (const arg of member.argsArray) {
if (arg.type)
memberNode.children.push(renderProperty(`\`${arg.name}\``, arg.type, arg.spec));
}
if (match[1] === 'async method' && !returnContainer[0]) {
returnContainer.push({
type: 'li',
text: 'returns: <[Promise]>',
liType: 'default'
});
}
if (optionsContainer[0])
optionsContainer[0].children.sort((o1, o2) => o1.text.localeCompare(o2.text));
member.children = [...argChildren, ...optionsContainer, ...returnContainer, ...nonArgChildren];
const signatureKey = match[2] + match[3] + '.' + match[4];
const methodName = match[2].toLowerCase() + match[3] + '.' + match[4];
const signature = signatures.get(signatureKey);
member.text = `${methodName}(${signature})`;
}
if (match[1] === 'property') {
member.text = `${match[2].toLowerCase() + match[3]}.${match[4]}`;
continue;
// Append type
if (member.type && member.type.name !== 'void') {
let name;
switch (member.kind) {
case 'event': name = 'type:'; break;
case 'property': name = 'type:'; break;
case 'method': name = 'returns:'; break;
}
memberNode.children.push(renderProperty(name, member.type));
}
// Append member doc
memberNode.children.push(...(member.spec || []).map(c => clone(c)));
classNode.children.push(memberNode);
}
}
api.setText([comment, header, renderMd(nodes, 10000), footer].join('\n'));
// Generate links
preprocessor.generateLinks(api, signatures, messages);
result.push({
type: 'text',
text: links
});
api.setText([comment, header, renderMd(result, 10000), footer].join('\n'));
}
}
@ -172,13 +139,10 @@ async function run() {
for (const source of mdSources.filter(source => source.hasUpdatedText()))
messages.push(Message.warning(`WARN: updated ${source.projectPath()}`));
const body = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-body.md')).toString();
const params = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-params.md')).toString();
const api = applyTemplates(parseMd(body), parseMd(params));
const checkPublicAPI = require('./check_public_api');
const jsSources = await Source.readdir(path.join(PROJECT_DIR, 'src', 'client'), '', []);
messages.push(...checkPublicAPI(api, jsSources));
messages.push(...checkPublicAPI(apiSpec, jsSources));
for (const source of mdSources) {
if (!source.hasUpdatedText())
@ -235,3 +199,39 @@ function getRepositoryFiles() {
const files = out.stdout.toString().trim().split('\n').filter(f => !f.startsWith('docs-src'));
return files.map(file => path.join(PROJECT_DIR, file));
}
/**
* @param {string} name
* @param {Type} type
* @param {MarkdownNode[]} [spec]
*/
function renderProperty(name, type, spec) {
let comment = '';
if (spec && spec.length)
comment = spec[0].text;
let children;
if (type.properties && type.properties.length)
children = type.properties.map(p => renderProperty(`\`${p.name}\``, p.type, p.spec))
else if (spec && spec.length > 1)
children = spec.slice(1).map(s => clone(s));
const result = {
type: 'li',
liType: 'default',
text: `${name} <${renderType(type.name)}>${comment ? ' ' + comment : ''}`,
children
};
return result;
}
/**
* @param {string} type
*/
function renderType(type) {
if (type.includes('"'))
return type.replace(/,/g, '|').replace(/Array/, "[Array]").replace(/null/, "[null]").replace(/number/, "[number]");
const result = type.replace(/([\w]+)/g, '[$1]');
if (result === '[Promise]<[void]>')
return '[Promise]';
return result.replace(/[(]/g, '\\(').replace(/[)]/g, '\\)');
}

View File

@ -180,49 +180,6 @@ function autocorrectInvalidLinks(projectRoot, sources, allowedFilePaths) {
}
}
function generateLinks(source, signatures, messages) {
const sourceEdits = new SourceEdits(source);
let offset = 0;
const lines = source.text().split('\n');
lines.forEach((line, lineNumber) => {
const linkRegex = /\[([^\]]+)\]\(\)/gm;
let match;
while (match = linkRegex.exec(line)) {
const [, name] = match;
const linkOffset = offset + lineNumber + match.index;
const hrefOffset = offset + lineNumber + match.index + 3 + name.length;
let replacement;
const memberMatch = name.match(/`(event|method|property):\s(JS|CDP|[A-Z])([^.]+)\.(.*)`/m);
const paramMatch = name.match(/`(?:param|option):\s(.*)`/m);
if (!memberMatch && !paramMatch) {
messages.push(Message.error(`Bad link: ${source.filePath()}:${lineNumber + 1}: ${name}`));
return;
}
if (memberMatch && memberMatch[1] === 'event') {
replacement = `${memberMatch[2].toLowerCase() + memberMatch[3]}.on('${memberMatch[4]}')`;
sourceEdits.edit(linkOffset + 1, hrefOffset - 2, replacement);
} else if (memberMatch && memberMatch[1] === 'method') {
const key = memberMatch[2] + memberMatch[3] + '.' + memberMatch[4];
const method = memberMatch[2].toLowerCase() + memberMatch[3] + '.' + memberMatch[4];
let signature = signatures.get(key);
if (signature === undefined) {
messages.push(Message.error(`Bad method link: ${source.filePath()}:${lineNumber + 1}: ${key}`));
signature = '(\u2026)';
}
replacement = method + '(' + signature + ')';
sourceEdits.edit(linkOffset + 2, hrefOffset - 3, replacement);
} else if (paramMatch) {
sourceEdits.edit(linkOffset, hrefOffset + 1, '`' + paramMatch[1] + '`');
}
if (replacement)
sourceEdits.edit(hrefOffset, hrefOffset, '#' + replacement.toLowerCase().replace(/[^a-z]/gm, ''));
}
offset += line.length;
});
sourceEdits.commit(messages);
}
class SourceEdits {
constructor(source) {
this._source = source;
@ -328,4 +285,4 @@ function generateTableOfContentsForSuperclass(text, name) {
return text;
}
module.exports = {autocorrectInvalidLinks, runCommands, generateLinks};
module.exports = {autocorrectInvalidLinks, runCommands};

View File

@ -158,7 +158,7 @@ function innerRenderMdNode(node, lastNode, result, maxColumns = 120) {
const depth = node.type.substring(1);
result.push(`${'#'.repeat(depth)} ${node.text}`);
let lastNode = node;
for (const child of node.children) {
for (const child of node.children || []) {
innerRenderMdNode(child, lastNode, result, maxColumns);
lastNode = child;
}
@ -255,9 +255,8 @@ function applyTemplates(body, params) {
throw new Error('Bad template: ' + key);
node.children.push(...template.children.map(c => clone(c)));
}
for (const child of node.children || []) {
for (const child of node.children || [])
visit(child, node);
}
if (node.children)
node.children = node.children.filter(child => !child.text || !child.text.includes('-inline- = %%'));
};