chore: generate types, api.json off md rather than html (#4825)

This commit is contained in:
Pavel Feldman 2020-12-26 14:31:41 -08:00 committed by GitHub
parent 9dd982c508
commit 15cdfd1cc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 1302 additions and 1330 deletions

View File

@ -132,7 +132,7 @@ Emitted when Browser context gets closed. This might happen because of one of th
* The [`method: Browser.close`]() method was called.
## event: BrowserContext.page
- <[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 [`event: Page.popup`]() to receive events about popups relevant to a specific page.
@ -165,13 +165,13 @@ await browserContext.addCookies([cookieObject1, cookieObject2]);
- `cookies` <[Array]<[Object]>>
- `name` <[string]> **required**
- `value` <[string]> **required**
- `url` <[string]> either url or domain / path are required
- `domain` <[string]> either url or domain / path are required
- `path` <[string]> either url or domain / path are required
- `expires` <[number]> Unix time in seconds.
- `httpOnly` <[boolean]>
- `secure` <[boolean]>
- `sameSite` <"Strict"|"Lax"|"None">
- `url` <[string]> either url or domain / path are required. Optional.
- `domain` <[string]> either url or domain / path are required Optional.
- `path` <[string]> either url or domain / path are required Optional.
- `expires` <[number]> Unix time in seconds. Optional.
- `httpOnly` <[boolean]> Optional.
- `secure` <[boolean]> Optional.
- `sameSite` <"Strict"|"Lax"|"None"> Optional.
## async method: BrowserContext.addInitScript
@ -201,8 +201,8 @@ await browserContext.addInitScript({
### param: BrowserContext.addInitScript.script
- `script` <[function]|[string]|[Object]>
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw script content.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
Script to be evaluated in all pages in the browser context.
@ -372,24 +372,24 @@ specified.
### param: BrowserContext.grantPermissions.permissions
- `permissions` <[Array]<[string]>>
- `'geolocation'`
- `'midi'`
- `'midi-sysex'` (system-exclusive midi)
- `'notifications'`
- `'push'`
- `'camera'`
- `'microphone'`
- `'background-sync'`
- `'ambient-light-sensor'`
- `'accelerometer'`
- `'gyroscope'`
- `'magnetometer'`
- `'accessibility-events'`
- `'clipboard-read'`
- `'clipboard-write'`
- `'payment-handler'`
A permission or an array of permissions to grant. Permissions can be one of the following values:
* `'geolocation'`
* `'midi'`
* `'midi-sysex'` (system-exclusive midi)
* `'notifications'`
* `'push'`
* `'camera'`
* `'microphone'`
* `'background-sync'`
* `'ambient-light-sensor'`
* `'accelerometer'`
* `'gyroscope'`
* `'magnetometer'`
* `'accessibility-events'`
* `'clipboard-read'`
* `'clipboard-write'`
* `'payment-handler'`
### option: BrowserContext.grantPermissions.origin
- `origin` <[string]>
@ -643,7 +643,7 @@ page.removeListener('request', logRequest);
Emitted when the page closes.
## event: Page.console
- <[ConsoleMessage]>
- type: <[ConsoleMessage]>
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also
emitted if the page throws an error or a warning.
@ -692,7 +692,7 @@ await new Promise((resolve, reject) => {
```
## event: Page.dialog
- <[Dialog]>
- type: <[Dialog]>
Emitted when a JavaScript dialog appears, such as `alert`, `prompt`, `confirm` or `beforeunload`. Playwright can respond
to the dialog via [`method: Dialog.accept`]() or [`method: Dialog.dismiss`]() methods.
@ -703,7 +703,7 @@ Emitted when the JavaScript [`DOMContentLoaded`](https://developer.mozilla.org/e
event is dispatched.
## event: Page.download
- <[Download]>
- type: <[Download]>
Emitted when attachment download started. User can access basic file operations on downloaded content via the passed
[Download] instance.
@ -713,7 +713,7 @@ downloaded content. If `acceptDownloads` is not set or set to `false`, download
download is not performed and user has no access to the downloaded files.
## event: Page.filechooser
- <[FileChooser]>
- type: <[FileChooser]>
Emitted when a file chooser is supposed to appear, such as after clicking the `<input type=file>`. Playwright can
respond to it via setting the input files using [`method: FileChooser.setFiles`]() that can be uploaded after that.
@ -725,17 +725,17 @@ page.on('filechooser', async (fileChooser) => {
```
## event: Page.frameattached
- <[Frame]>
- type: <[Frame]>
Emitted when a frame is attached.
## event: Page.framedetached
- <[Frame]>
- type: <[Frame]>
Emitted when a frame is detached.
## event: Page.framenavigated
- <[Frame]>
- type: <[Frame]>
Emitted when a frame is navigated to a new url.
@ -744,12 +744,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
- <[Error]> The exception message
- type: <[Error]> The exception message
Emitted when an uncaught exception happens within the page.
## event: Page.popup
- <[Page]> Page corresponding to "popup" window
- type: <[Page]> Page corresponding to "popup" window
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.
@ -770,13 +770,13 @@ console.log(await popup.evaluate('location.href'));
need it in most cases).
## event: Page.request
- <[Request]>
- type: <[Request]>
Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see
[`method: Page.route`]() or [`method: BrowserContext.route`]().
## event: Page.requestfailed
- <[Request]>
- type: <[Request]>
Emitted when a request fails, for example by timing out.
@ -784,24 +784,24 @@ Emitted when a request fails, for example by timing out.
will complete with [`event: Page.requestfinished`]() event and not with [`event: Page.requestfailed`]().
## event: Page.requestfinished
- <[Request]>
- type: <[Request]>
Emitted when a request finishes successfully after downloading the response body. For a successful response, the
sequence of events is `request`, `response` and `requestfinished`.
## event: Page.response
- <[Response]>
- type: <[Response]>
Emitted when [response] status and headers are received for a request. For a successful response, the sequence of events
is `request`, `response` and `requestfinished`.
## event: Page.websocket
- <[WebSocket]> websocket
- type: <[WebSocket]> websocket
Emitted when <[WebSocket]> request is sent.
## event: Page.worker
- <[Worker]>
- type: <[Worker]>
Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the
page.
@ -885,8 +885,8 @@ Function to be evaluated in browser context
Optional argument to pass to [`param: pageFunction`]()
## namespace: Page.accessibility
- returns: <[Accessibility]>
## property: Page.accessibility
- type: <[Accessibility]>
## async method: Page.addInitScript
@ -913,8 +913,8 @@ await page.addInitScript(preloadFile);
### param: Page.addInitScript.script
- `script` <[function]|[string]|[Object]>
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw script content.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
Script to be evaluated in the page.
@ -933,10 +933,10 @@ Shortcut for main frame's [`method: Frame.addScriptTag`]().
### param: Page.addScriptTag.params
- `params` <[Object]>
- `url` <[string]> URL of a script to be added.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw JavaScript content to be injected into frame.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details.
- `url` <[string]> URL of a script to be added. Optional.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw JavaScript content to be injected into frame. Optional.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details. Optional.
## async method: Page.addStyleTag
- returns: <[ElementHandle]>
@ -948,9 +948,9 @@ Shortcut for main frame's [`method: Frame.addStyleTag`]().
### param: Page.addStyleTag.params
- `params` <[Object]>
- `url` <[string]> URL of the `<link>` tag.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw CSS content to be injected into frame.
- `url` <[string]> URL of the `<link>` tag. Optional.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw CSS content to be injected into frame. Optional.
## async method: Page.bringToFront
@ -1039,8 +1039,8 @@ Gets the full HTML contents of the page, including the doctype.
Get the browser context that the page belongs to.
## namespace: Page.coverage
- returns: <[null]|[ChromiumCoverage]>
## property: Page.coverage
- type: <[null]|[ChromiumCoverage]>
Browser-specific Coverage implementation, only available for Chromium atm. See
[ChromiumCoverage](#class-chromiumcoverage) for more details.
@ -1155,13 +1155,13 @@ await page.evaluate(() => matchMedia('(prefers-color-scheme: no-preference)').ma
### param: Page.emulateMedia.params
- `params` <[Object]>
- `media` <[null]|"screen"|"print"> Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation. Omitting `media` or passing `undefined` does not change the emulated value.
- `colorScheme` <[null]|"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing `null` disables color scheme emulation. Omitting `colorScheme` or passing `undefined` does not change the emulated value.
- `media` <[null]|"screen"|"print"> Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation. Omitting `media` or passing `undefined` does not change the emulated value. Optional.
- `colorScheme` <[null]|"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing `null` disables color scheme emulation. Omitting `colorScheme` or passing `undefined` does not change the emulated value. Optional.
## async method: Page.evaluate
- returns: <[Serializable]>
Returns the value of the [`param: pageFunction`]() invacation.
Returns the value of the [`param: pageFunction`]() invocation.
If the function passed to the `page.evaluate` returns a [Promise], then `page.evaluate` would wait for the promise to
resolve and return its value.
@ -1210,7 +1210,7 @@ Optional argument to pass to [`param: pageFunction`]()
## async method: Page.evaluateHandle
- returns: <[JSHandle]>
Returns the value of the [`param: pageFunction`]() invacation as in-page object (JSHandle).
Returns the value of the [`param: pageFunction`]() invocation as in-page object (JSHandle).
The only difference between `page.evaluate` and `page.evaluateHandle` is that `page.evaluateHandle` returns in-page
object (JSHandle).
@ -1432,8 +1432,8 @@ const frame = page.frame({ url: /.*domain.*/ });
### param: Page.frame.frameSelector
- `frameSelector` <[string]|[Object]>
- `name` <[string]> frame name specified in the `iframe`'s `name` attribute
- `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object.
- `name` <[string]> Frame name specified in the `iframe`'s `name` attribute. Optional.
- `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object. Optional.
Frame name or other frame lookup options.
@ -1566,16 +1566,16 @@ Returns `element.innerText`.
Indicates that the page has been closed.
## namespace: Page.keyboard
- returns: <[Keyboard]>
## property: Page.keyboard
- type: <[Keyboard]>
## method: Page.mainFrame
- returns: <[Frame]>
The page's main frame. Page is guaranteed to have a main frame which persists during navigations.
## namespace: Page.mouse
- returns: <[Mouse]>
## property: Page.mouse
- type: <[Mouse]>
## async method: Page.opener
- returns: <[null]|[Page]>
@ -1651,14 +1651,14 @@ Display header and footer. Defaults to `false`.
### option: Page.pdf.headerTemplate
- `headerTemplate` <[string]>
- `'date'` formatted print date
- `'title'` document title
- `'url'` document location
- `'pageNumber'` current page number
- `'totalPages'` total pages in the document
HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values
into them:
* `'date'` formatted print date
* `'title'` document title
* `'url'` document location
* `'pageNumber'` current page number
* `'totalPages'` total pages in the document
### option: Page.pdf.footerTemplate
- `footerTemplate` <[string]>
@ -1722,7 +1722,7 @@ generate the text for. A superset of the [`param: key`]() values can be found
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
`Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the [`param: key`]() in the upper case.
@ -1885,9 +1885,9 @@ Shortcut for main frame's [`method: Frame.selectOption`]()
### param: Page.selectOption.values
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>>
- `value` <[string]> Matches by `option.value`.
- `label` <[string]> Matches by `option.label`.
- `index` <[number]> Matches by the index.
- `value` <[string]> Matches by `option.value`. Optional.
- `label` <[string]> Matches by `option.label`. Optional.
- `index` <[number]> Matches by the index. Optional.
Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the
first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option
@ -2028,8 +2028,8 @@ Returns `element.textContent`.
Returns the page's title. Shortcut for main frame's [`method: Frame.title`]().
## namespace: Page.touchscreen
- returns: <[Touchscreen]>
## property: Page.touchscreen
- type: <[Touchscreen]>
## async method: Page.type
@ -2208,12 +2208,12 @@ Shortcut for main frame's [`method: Frame.waitForLoadState`]().
### param: Page.waitForLoadState.state
- `state` <"load"|"domcontentloaded"|"networkidle">
- `'load'` - wait for the `load` event to be fired.
- `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
- `'networkidle'` - wait until there are no network connections for at least `500` ms.
Load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the
method resolves immediately. Optional.
Optional load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the
method resolves immediately. Can be one of:
* `'load'` - wait for the `load` event to be fired.
* `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
* `'networkidle'` - wait until there are no network connections for at least `500` ms.
### option: Page.waitForLoadState.timeout = %%-navigation-timeout-%%
@ -2366,9 +2366,9 @@ At every point of time, page exposes its current frame tree via the [`method: Pa
Frame.childFrames`]() methods.
[Frame] object's lifecycle is controlled by three events, dispatched on the page object:
- [`event: Page.frameattached`]() - fired when the frame gets attached to the page. A Frame can be attached to the page only once.
- [`event: Page.framenavigated`]() - fired when the frame commits navigation to a different URL.
- [`event: Page.framedetached`]() - fired when the frame gets detached from the page. A Frame can be detached from the page only once.
* [`event: Page.frameattached`]() - fired when the frame gets attached to the page. A Frame can be attached to the page only once.
* [`event: Page.framenavigated`]() - fired when the frame commits navigation to a different URL.
* [`event: Page.framedetached`]() - 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:
@ -2493,10 +2493,10 @@ Adds a `<script>` tag into the page with the desired url or content.
### param: Frame.addScriptTag.params
- `params` <[Object]>
- `url` <[string]> URL of a script to be added.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw JavaScript content to be injected into frame.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details.
- `url` <[string]> URL of a script to be added. Optional.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw JavaScript content to be injected into frame. Optional.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details. Optional.
## async method: Frame.addStyleTag
- returns: <[ElementHandle]>
@ -2508,9 +2508,9 @@ content.
### param: Frame.addStyleTag.params
- `params` <[Object]>
- `url` <[string]> URL of the `<link>` tag.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw CSS content to be injected into frame.
- `url` <[string]> URL of the `<link>` tag. Optional.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw CSS content to be injected into frame. Optional.
## async method: Frame.check
@ -2902,7 +2902,7 @@ generate the text for. A superset of the [`param: key`]() values can be found
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
`Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the [`param: key`]() in the upper case.
@ -2951,9 +2951,9 @@ frame.selectOption('select#colors', 'red', 'green', 'blue');
### param: Frame.selectOption.values
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>>
- `value` <[string]> Matches by `option.value`.
- `label` <[string]> Matches by `option.label`.
- `index` <[number]> Matches by the index.
- `value` <[string]> Matches by `option.value`. Optional.
- `label` <[string]> Matches by `option.label`. Optional.
- `index` <[number]> Matches by the index. Optional.
Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the
first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option
@ -3145,12 +3145,12 @@ await frame.waitForLoadState(); // Waits for 'load' state by default.
### param: Frame.waitForLoadState.state
- `state` <"load"|"domcontentloaded"|"networkidle">
- `'load'` - wait for the `load` event to be fired.
- `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
- `'networkidle'` - wait until there are no network connections for at least `500` ms.
Load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the
method returns immediately. Optional.
Optional load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the
method returns immediately. Can be one of:
* `'load'` - wait for the `load` event to be fired.
* `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
* `'networkidle'` - wait until there are no network connections for at least `500` ms.
### option: Frame.waitForLoadState.timeout = %%-navigation-timeout-%%
@ -3350,8 +3350,8 @@ Optional argument to pass to [`param: pageFunction`]()
- returns: <[null]|[Object]>
- `x` <[number]> the x coordinate of the element in pixels.
- `y` <[number]> the y coordinate of the element in pixels.
- width <[number]> the width of the element in pixels.
- height <[number]> the height of the element in pixels.
- `width` <[number]> the width of the element in pixels.
- `height` <[number]> the height of the element in pixels.
This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is
calculated relative to the main frame viewport - which is usually the same as the browser window.
@ -3573,7 +3573,7 @@ generate the text for. A superset of the [`param: key`]() values can be found
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
`Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the [`param: key`]() in the upper case.
@ -3636,7 +3636,7 @@ This method waits for [actionability](./actionability.md) checks, then tries to
completely visible as defined by
[IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s ```ratio```.
Throws when ```elementHandle``` does not point to an element
Throws when `elementHandle` does not point to an element
[connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
### option: ElementHandle.scrollIntoViewIfNeeded.timeout = %%-input-timeout-%%
@ -3665,9 +3665,9 @@ handle.selectOption({ value: 'blue' }, { index: 2 }, 'red');
### param: ElementHandle.selectOption.values
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>>
- `value` <[string]> Matches by `option.value`.
- `label` <[string]> Matches by `option.label`.
- `index` <[number]> Matches by the index.
- `value` <[string]> Matches by `option.value`. Optional.
- `label` <[string]> Matches by `option.label`. Optional.
- `index` <[number]> Matches by the index. Optional.
Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the
first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option
@ -3939,9 +3939,7 @@ property to get
## async method: JSHandle.jsonValue
- returns: <[Serializable]>
Returns a JSON representation of the object. If the object has a
[`toJSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior)
function, it **will not be called**.
Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**.
> **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.
@ -3958,7 +3956,7 @@ error if the object has circular references.
## method: ConsoleMessage.location
- returns: <[Object]>
- `url` <[string]> URL of the resource if available, otherwise empty string.
- `url` <[string]> URL of the resource.
- `lineNumber` <[number]> 0-based line number in the resource.
- `columnNumber` <[number]> 0-based column number in the resource.
@ -4202,7 +4200,7 @@ generate the text for. A superset of the [`param: key`]() values can be found
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
`Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the [`param: key`]() in the upper case.
@ -4248,7 +4246,7 @@ generate the text for. A superset of the [`param: key`]() values can be found
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`,
`Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the [`param: key`]() in the upper case.
@ -4414,9 +4412,9 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi
# class: Request
Whenever the page sends a request for a network resource the following sequence of events are emitted by [Page]:
- [`event: Page.request`]() emitted when the request is issued by the page.
- [`event: Page.response`]() emitted when/if the response status and headers are received for the request.
- [`event: Page.requestfinished`]() emitted when the response body is downloaded and the request is complete.
* [`event: Page.request`]() emitted when the request is issued by the page.
* [`event: Page.response`]() emitted when/if the response status and headers are received for the request.
* [`event: Page.requestfinished`]() 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 [`event: Page.requestfailed`]() event is emitted.
@ -4676,8 +4674,8 @@ contain `[a-zA-Z0-9_]` characters.
### param: Selectors.register.script
- `script` <[function]|[string]|[Object]>
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw script content.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
Script that evaluates to a selector engine instance.
@ -4702,22 +4700,22 @@ Aborts the route's request.
### param: Route.abort.errorCode
- `errorCode` <[string]>
- `'aborted'` - An operation was aborted (due to user action)
- `'accessdenied'` - Permission to access a resource, other than the network, was denied
- `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified host or network.
- `'blockedbyclient'` - The client chose to block the request.
- `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
- `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent.
- `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN).
- `'connectionfailed'` - A connection attempt failed.
- `'connectionrefused'` - A connection attempt was refused.
- `'connectionreset'` - A connection was reset (corresponding to a TCP RST).
- `'internetdisconnected'` - The Internet connection has been lost.
- `'namenotresolved'` - The host name could not be resolved.
- `'timedout'` - An operation timed out.
- `'failed'` - A generic failure occurred.
Optional error code. Defaults to `failed`, could be one of the following:
* `'aborted'` - An operation was aborted (due to user action)
* `'accessdenied'` - Permission to access a resource, other than the network, was denied
* `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified host or network.
* `'blockedbyclient'` - The client chose to block the request.
* `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
* `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent.
* `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN).
* `'connectionfailed'` - A connection attempt failed.
* `'connectionrefused'` - A connection attempt was refused.
* `'connectionreset'` - A connection was reset (corresponding to a TCP RST).
* `'internetdisconnected'` - The Internet connection has been lost.
* `'namenotresolved'` - The host name could not be resolved.
* `'timedout'` - An operation timed out.
* `'failed'` - A generic failure occurred.
## async method: Route.continue
@ -4793,19 +4791,19 @@ The [WebSocket] class represents websocket connections in the page.
Fired when the websocket closes.
## event: WebSocket.framereceived
- <[Object]> web socket frame data
- type: <[Object]> web socket frame data
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket recieves a frame.
## event: WebSocket.framesent
- <[Object]> web socket frame data
- type: <[Object]> web socket frame data
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket sends a frame.
## event: WebSocket.socketerror
- <[String]> the error message
- type: <[String]> the error message
Fired when the websocket has an error.
@ -4956,7 +4954,7 @@ for (const worker of page.workers())
<!-- GEN:stop -->
## event: Worker.close
- <[Worker]>
- type: <[Worker]>
Emitted when this dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is terminated.
@ -5065,7 +5063,7 @@ This methods attaches Playwright to an existing browser instance.
- `params` <[Object]>
- `wsEndpoint` <[string]> A browser websocket endpoint to connect to. **required**
- `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.
- `logger` <[Logger]> Logger sink for Playwright logging.
- `logger` <[Logger]> Logger sink for Playwright logging. Optional.
- `timeout` <[number]> Maximum time in milliseconds to wait for the connection to be established. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
## method: BrowserType.executablePath
@ -5475,7 +5473,7 @@ message arguments
### param: Logger.log.hints
- `hints` <[Object]>
- `color` <[string]> preferred logger color
- `color` <[string]> Optional preferred logger color.
optional formatting hints
@ -5548,14 +5546,14 @@ const backgroundPage = await context.waitForEvent('backgroundpage');
<!-- GEN:stop -->
## event: ChromiumBrowserContext.backgroundpage
- <[Page]>
- type: <[Page]>
Emitted when new background page is created in the context.
> **NOTE** Only works with persistent context.
## event: ChromiumBrowserContext.serviceworker
- <[Worker]>
- type: <[Worker]>
Emitted when new service worker is created in the context.

View File

@ -1,14 +1,12 @@
## navigation-wait-until
- `waitUntil` <"load"|"domcontentloaded"|"networkidle">
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
When to consider operation succeeded, defaults to `load`. Events can be either:
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
## navigation-timeout
- `timeout` <[number]>
Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout.
@ -19,14 +17,12 @@ The default value can be changed by using the
[`method: Page.setDefaultTimeout`]() methods.
## wait-for-timeout
- `timeout` <[number]>
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 [`method: BrowserContext.setDefaultTimeout`]().
## input-timeout
- `timeout` <[number]>
Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by
@ -34,7 +30,6 @@ using the [`method: BrowserContext.setDefaultTimeout`]() or
[`method: Page.setDefaultTimeout`]() methods.
## input-no-wait-after
- `noWaitAfter` <[boolean]>
Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
@ -42,20 +37,17 @@ opt out of waiting via setting this flag. You would only need this option in the
to inaccessible pages. Defaults to `false`.
## input-force
- `force` <[boolean]>
Whether to bypass the [actionability](./actionability.md) checks. Defaults to `false`.
## input-selector
- `selector` <[string]>
A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See
[working with selectors](#working-with-selectors) for more details.
## input-position
- `position` <[Object]>
- `x` <[number]>
- `y` <[number]>
@ -64,57 +56,49 @@ A point to use relative to the top-left corner of element padding box. If not sp
element.
## input-modifiers
- `modifiers` <[Array]<"Alt"|"Control"|"Meta"|"Shift">>
Modifier keys to press. Ensures that only these modifiers are pressed during the operation, and then restores current
modifiers back. If not specified, currently pressed modifiers are used.
## input-button
- `button` <"left"|"right"|"middle">
Defaults to `left`.
## input-files
- `files` <[string]|[Array]<[string]>|[Object]|[Array]<[Object]>>
- `name` <[string]> [File] name **required**
- `mimeType` <[string]> [File] type **required**
- `buffer` <[Buffer]> File content **required**
## input-down-up-delay
- `delay` <[number]>
Time to wait between `mousedown` and `mouseup` in milliseconds. Defaults to 0.
## input-click-count
- `clickCount` <[number]>
defaults to 1. See [UIEvent.detail].
## query-selector
- `selector` <[string]>
A selector to query for. See [working with selectors](#working-with-selectors) for more details.
## wait-for-selector-state
- `state` <"attached"|"detached"|"visible"|"hidden">
- `'attached'` - wait for element to be present in DOM.
- `'detached'` - wait for element to not be present in DOM.
- `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without
any content or with `display:none` has an empty bounding box and is not considered visible.
- `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`.
This is opposite to the `'visible'` option.
Defaults to `'visible'`. Can be either:
* `'attached'` - wait for element to be present in DOM.
* `'detached'` - wait for element to not be present in DOM.
* `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without
any content or with `display:none` has an empty bounding box and is not considered visible.
* `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`.
This is opposite to the `'visible'` option.
## context-option-storage-state
- `storageState` <[string]|[Object]>
- `cookies` <[Array]<[Object]>> Optional cookies to set for context
- `name` <[string]> **required**
@ -136,25 +120,21 @@ Populates context with given storage state. This method can be used to initializ
obtained via [`method: BrowserContext.storageState`](). Either a path to the file with saved storage, or an object with the following fields:
## context-option-acceptdownloads
- `acceptDownloads` <[boolean]>
Whether to automatically download all the attachments. Defaults to `false` where all the downloads are canceled.
## context-option-ignorehttpserrors
- `ignoreHTTPSErrors` <[boolean]>
Whether to ignore HTTPS errors during navigation. Defaults to `false`.
## context-option-bypasscsp
- `bypassCSP` <[boolean]>
Toggles bypassing page's Content-Security-Policy.
## context-option-viewport
- `viewport` <[null]|[Object]>
- `width` <[number]> page width in pixels.
- `height` <[number]> page height in pixels.
@ -162,78 +142,66 @@ Toggles bypassing page's Content-Security-Policy.
Sets a consistent viewport for each page. Defaults to an 1280x720 viewport. `null` disables the default viewport.
## context-option-useragent
- `userAgent` <[string]>
Specific user agent to use in this context.
## context-option-devicescalefactor
- `deviceScaleFactor` <[number]>
Specify device scale factor (can be thought of as dpr). Defaults to `1`.
## context-option-ismobile
- `isMobile` <[boolean]>
Whether the `meta viewport` tag is taken into account and touch events are enabled. Defaults to `false`. Not supported
in Firefox.
## context-option-hastouch
- `hasTouch` <[boolean]>
Specifies if viewport supports touch events. Defaults to false.
## context-option-javascriptenabled
- `javaScriptEnabled` <[boolean]>
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)
for a list of supported timezone IDs.
## context-option-geolocation
- `geolocation` <[Object]>
- `latitude` <[number]> Latitude between -90 and 90.
- `longitude` <[number]> Longitude between -180 and 180.
- `accuracy` <[number]> Non-negative accuracy value. Defaults to `0`.
## context-option-locale
- `locale` <[string]>
Specify user locale, for example `en-GB`, `de-DE`, etc. Locale will affect `navigator.language` value, `Accept-Language`
request header value as well as number and date formatting rules.
## context-option-permissions
- `permissions` <[Array]<[string]>>
A list of permissions to grant to all pages in this context. See
[`method: BrowserContext.grantPermissions`]() for more details.
## context-option-extrahttpheaders
- `extraHTTPHeaders` <[Object]<[string], [string]>>
An object containing additional HTTP headers to be sent with every request. All header values must be strings.
## context-option-offline
- `offline` <[boolean]>
Whether to emulate network being offline. Defaults to `false`.
## context-option-httpcredentials
- `httpCredentials` <[Object]>
- `username` <[string]>
- `password` <[string]>
@ -241,20 +209,17 @@ Whether to emulate network being offline. Defaults to `false`.
Credentials for [HTTP authentication](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication).
## context-option-colorscheme
- `colorScheme` <"light"|"dark"|"no-preference">
Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. See
[`method: Page.emulateMedia`]() for more details. Defaults to '`light`'.
## context-option-logger
- `logger` <[Logger]>
Logger sink for Playwright logging.
## context-option-videospath
- `videosPath` <[string]>
**NOTE** Use [`param: recordVideo`]() instead, it takes precedence over `videosPath`. Enables video recording for all pages to
@ -262,7 +227,6 @@ Logger sink for Playwright logging.
[`method: BrowserContext.close`]() for videos to be saved.
## context-option-videosize
- `videoSize` <[Object]>
- `width` <[number]> Video frame width.
- `height` <[number]> Video frame height.
@ -273,7 +237,6 @@ recorded video. Can only be used if `videosPath` is set. If not specified the si
down if necessary to fit specified size.
## context-option-recordhar
- `recordHar` <[Object]>
- `omitContent` <[boolean]> Optional setting to control whether to omit request content from the HAR. Defaults to
`false`.
@ -284,7 +247,6 @@ specified, the HAR is not recorded. Make sure to await [`method: BrowserContext.
saved.
## context-option-recordvideo
- `recordVideo` <[Object]>
- `dir` <[string]> Path to the directory to put videos into.
- `size` <[Object]> Optional dimensions of the recorded videos. If not specified the size will be equal to `viewport`.
@ -297,7 +259,6 @@ Enables video recording for all pages into `recordVideo.dir` directory. If not s
sure to await [`method: BrowserContext.close`]() for videos to be saved.
## context-option-proxy
- `proxy` <[Object]>
- `server` <[string]> Proxy to be used for all requests. HTTP and SOCKS proxies are supported, for example
`http://myproxy.com:3128` or `socks5://myproxy.com:3128`. Short form `myproxy.com:3128` is considered an HTTP proxy.

View File

@ -397,7 +397,7 @@ Emitted when Browser context gets closed. This might happen because of one of th
* The [`browser.close()`](#browserclose) method was called.
#### browserContext.on('page')
- <[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.
@ -417,13 +417,13 @@ console.log(await page.evaluate('location.href'));
- `cookies` <[Array]<[Object]>>
- `name` <[string]> **required**
- `value` <[string]> **required**
- `url` <[string]> either url or domain / path are required
- `domain` <[string]> either url or domain / path are required
- `path` <[string]> either url or domain / path are required
- `expires` <[number]> Unix time in seconds.
- `httpOnly` <[boolean]>
- `secure` <[boolean]>
- `sameSite` <"Strict"|"Lax"|"None">
- `url` <[string]> either url or domain / path are required. Optional.
- `domain` <[string]> either url or domain / path are required Optional.
- `path` <[string]> either url or domain / path are required Optional.
- `expires` <[number]> Unix time in seconds. Optional.
- `httpOnly` <[boolean]> Optional.
- `secure` <[boolean]> Optional.
- `sameSite` <"Strict"|"Lax"|"None"> Optional.
- returns: <[Promise]>
Adds cookies into this browser context. All pages within this context will have these cookies installed. Cookies can be obtained via [`browserContext.cookies([urls])`](#browsercontextcookiesurls).
@ -434,8 +434,8 @@ await browserContext.addCookies([cookieObject1, cookieObject2]);
#### browserContext.addInitScript(script[, arg])
- `script` <[function]|[string]|[Object]> Script to be evaluated in all pages in the browser context.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw script content.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
- `arg` <[Serializable]> Optional argument to pass to `script` (only supported when passing a function).
- returns: <[Promise]>
@ -592,22 +592,22 @@ const crypto = require('crypto');
#### browserContext.grantPermissions(permissions[, options])
- `permissions` <[Array]<[string]>> A permission or an array of permissions to grant. Permissions can be one of the following values:
- `'geolocation'`
- `'midi'`
- `'midi-sysex'` (system-exclusive midi)
- `'notifications'`
- `'push'`
- `'camera'`
- `'microphone'`
- `'background-sync'`
- `'ambient-light-sensor'`
- `'accelerometer'`
- `'gyroscope'`
- `'magnetometer'`
- `'accessibility-events'`
- `'clipboard-read'`
- `'clipboard-write'`
- `'payment-handler'`
* `'geolocation'`
* `'midi'`
* `'midi-sysex'` (system-exclusive midi)
* `'notifications'`
* `'push'`
* `'camera'`
* `'microphone'`
* `'background-sync'`
* `'ambient-light-sensor'`
* `'accelerometer'`
* `'gyroscope'`
* `'magnetometer'`
* `'accessibility-events'`
* `'clipboard-read'`
* `'clipboard-write'`
* `'payment-handler'`
- `options` <[Object]>
- `origin` <[string]> The [origin] to grant permissions to, e.g. "https://example.com".
- returns: <[Promise]>
@ -889,7 +889,7 @@ page.removeListener('request', logRequest);
Emitted when the page closes.
#### page.on('console')
- <[ConsoleMessage]>
- type: <[ConsoleMessage]>
Emitted when JavaScript within the page calls one of console API methods, e.g. `console.log` or `console.dir`. Also emitted if the page throws an error or a warning.
@ -935,7 +935,7 @@ await new Promise((resolve, reject) => {
```
#### page.on('dialog')
- <[Dialog]>
- type: <[Dialog]>
Emitted when a JavaScript dialog appears, such as `alert`, `prompt`, `confirm` or `beforeunload`. Playwright can respond to the dialog via [`dialog.accept([promptText])`](#dialogacceptprompttext) or [`dialog.dismiss()`](#dialogdismiss) methods.
@ -944,14 +944,14 @@ Emitted when a JavaScript dialog appears, such as `alert`, `prompt`, `confirm` o
Emitted when the JavaScript [`DOMContentLoaded`](https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded) event is dispatched.
#### page.on('download')
- <[Download]>
- type: <[Download]>
Emitted when attachment download started. User can access basic file operations on downloaded content via the passed [Download] instance.
> **NOTE** Browser context **must** be created with the `acceptDownloads` set to `true` when user needs access to the downloaded content. If `acceptDownloads` is not set or set to `false`, download events are emitted, but the actual download is not performed and user has no access to the downloaded files.
#### page.on('filechooser')
- <[FileChooser]>
- type: <[FileChooser]>
Emitted when a file chooser is supposed to appear, such as after clicking the `<input type=file>`. Playwright can respond to it via setting the input files using [`fileChooser.setFiles(files[, options])`](#filechoosersetfilesfiles-options) that can be uploaded after that.
@ -962,17 +962,17 @@ page.on('filechooser', async (fileChooser) => {
```
#### page.on('frameattached')
- <[Frame]>
- type: <[Frame]>
Emitted when a frame is attached.
#### page.on('framedetached')
- <[Frame]>
- type: <[Frame]>
Emitted when a frame is detached.
#### page.on('framenavigated')
- <[Frame]>
- type: <[Frame]>
Emitted when a frame is navigated to a new url.
@ -981,12 +981,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.
#### page.on('pageerror')
- <[Error]> The exception message
- type: <[Error]> The exception message
Emitted when an uncaught exception happens within the page.
#### page.on('popup')
- <[Page]> Page corresponding to "popup" window
- type: <[Page]> Page corresponding to "popup" window
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.
@ -1003,34 +1003,34 @@ console.log(await popup.evaluate('location.href'));
> **NOTE** Use [`page.waitForLoadState([state, options])`](#pagewaitforloadstatestate-options) to wait until the page gets to a particular state (you should not need it in most cases).
#### page.on('request')
- <[Request]>
- type: <[Request]>
Emitted when a page issues a request. The [request] object is read-only. In order to intercept and mutate requests, see [`page.route(url, handler)`](#pagerouteurl-handler) or [`browserContext.route(url, handler)`](#browsercontextrouteurl-handler).
#### page.on('requestfailed')
- <[Request]>
- type: <[Request]>
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).
#### page.on('requestfinished')
- <[Request]>
- type: <[Request]>
Emitted when a request finishes successfully after downloading the response body. For a successful response, the sequence of events is `request`, `response` and `requestfinished`.
#### page.on('response')
- <[Response]>
- type: <[Response]>
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')
- <[WebSocket]> websocket
- type: <[WebSocket]> websocket
Emitted when <[WebSocket]> request is sent.
#### page.on('worker')
- <[Worker]>
- type: <[Worker]>
Emitted when a dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is spawned by the page.
@ -1087,12 +1087,12 @@ const divsCounts = await page.$$eval('div', (divs, min) => divs.length >= min, 1
```
#### page.accessibility
- returns: <[Accessibility]>
- type: <[Accessibility]>
#### page.addInitScript(script[, arg])
- `script` <[function]|[string]|[Object]> Script to be evaluated in the page.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw script content.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
- `arg` <[Serializable]> Optional argument to pass to `script` (only supported when passing a function).
- returns: <[Promise]>
@ -1117,10 +1117,10 @@ await page.addInitScript(preloadFile);
#### page.addScriptTag(params)
- `params` <[Object]>
- `url` <[string]> URL of a script to be added.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw JavaScript content to be injected into frame.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details.
- `url` <[string]> URL of a script to be added. Optional.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw JavaScript content to be injected into frame. Optional.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details. Optional.
- returns: <[Promise]<[ElementHandle]>>
Adds a `<script>` tag into the page with the desired url or content. Returns the added tag when the script's onload fires or when the script content was injected into frame.
@ -1129,9 +1129,9 @@ Shortcut for main frame's [`frame.addScriptTag(params)`](#frameaddscripttagparam
#### page.addStyleTag(params)
- `params` <[Object]>
- `url` <[string]> URL of the `<link>` tag.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw CSS content to be injected into frame.
- `url` <[string]> URL of the `<link>` tag. Optional.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw CSS content to be injected into frame. Optional.
- returns: <[Promise]<[ElementHandle]>>
Adds a `<link rel="stylesheet">` tag into the page with the desired url or a `<style type="text/css">` tag with the content. Returns the added tag when the stylesheet's onload fires or when the CSS content was injected into frame.
@ -1213,7 +1213,7 @@ Gets the full HTML contents of the page, including the doctype.
Get the browser context that the page belongs to.
#### page.coverage
- returns: <[null]|[ChromiumCoverage]>
- type: <[null]|[ChromiumCoverage]>
Browser-specific Coverage implementation, only available for Chromium atm. See [ChromiumCoverage](#class-chromiumcoverage) for more details.
@ -1279,8 +1279,8 @@ await page.dispatchEvent('#source', 'dragstart', { dataTransfer });
#### page.emulateMedia(params)
- `params` <[Object]>
- `media` <[null]|"screen"|"print"> Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation. Omitting `media` or passing `undefined` does not change the emulated value.
- `colorScheme` <[null]|"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing `null` disables color scheme emulation. Omitting `colorScheme` or passing `undefined` does not change the emulated value.
- `media` <[null]|"screen"|"print"> Changes the CSS media type of the page. The only allowed values are `'screen'`, `'print'` and `null`. Passing `null` disables CSS media emulation. Omitting `media` or passing `undefined` does not change the emulated value. Optional.
- `colorScheme` <[null]|"light"|"dark"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`. Passing `null` disables color scheme emulation. Omitting `colorScheme` or passing `undefined` does not change the emulated value. Optional.
- returns: <[Promise]>
```js
@ -1317,7 +1317,7 @@ await page.evaluate(() => matchMedia('(prefers-color-scheme: no-preference)').ma
- `arg` <[EvaluationArgument]> Optional argument to pass to `pageFunction`
- returns: <[Promise]<[Serializable]>>
Returns the value of the `pageFunction` invacation.
Returns the value of the `pageFunction` invocation.
If the function passed to the `page.evaluate` returns a [Promise], then `page.evaluate` would wait for the promise to resolve and return its value.
@ -1355,7 +1355,7 @@ Shortcut for main frame's [`frame.evaluate(pageFunction[, arg])`](#frameevaluate
- `arg` <[EvaluationArgument]> Optional argument to pass to `pageFunction`
- returns: <[Promise]<[JSHandle]>>
Returns the value of the `pageFunction` invacation as in-page object (JSHandle).
Returns the value of the `pageFunction` invocation as in-page object (JSHandle).
The only difference between `page.evaluate` and `page.evaluateHandle` is that `page.evaluateHandle` returns in-page object (JSHandle).
@ -1520,8 +1520,8 @@ Shortcut for main frame's [`frame.focus(selector[, options])`](#framefocusselect
#### page.frame(frameSelector)
- `frameSelector` <[string]|[Object]> Frame name or other frame lookup options.
- `name` <[string]> frame name specified in the `iframe`'s `name` attribute
- `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object.
- `name` <[string]> Frame name specified in the `iframe`'s `name` attribute. Optional.
- `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving frame's `url` as a [URL] object. Optional.
- returns: <[null]|[Frame]>
Returns frame matching the specified criteria. Either `name` or `url` must be specified.
@ -1552,9 +1552,9 @@ Returns element attribute value.
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If can not go back, returns `null`.
@ -1565,9 +1565,9 @@ Navigate to the previous page in history.
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If can not go forward, returns `null`.
@ -1580,9 +1580,9 @@ Navigate to the next page in history.
- `referer` <[string]> Referer header value. If provided it will take preference over the referer header value set by [`page.setExtraHTTPHeaders(headers)`](#pagesetextrahttpheadersheaders).
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
@ -1645,7 +1645,7 @@ Returns `element.innerText`.
Indicates that the page has been closed.
#### page.keyboard
- returns: <[Keyboard]>
- type: <[Keyboard]>
#### page.mainFrame()
- returns: <[Frame]>
@ -1653,7 +1653,7 @@ Indicates that the page has been closed.
The page's main frame. Page is guaranteed to have a main frame which persists during navigations.
#### page.mouse
- returns: <[Mouse]>
- type: <[Mouse]>
#### page.opener()
- returns: <[Promise]<[null]|[Page]>>
@ -1666,11 +1666,11 @@ Returns the opener for popup pages and `null` for others. If the opener has been
- `footerTemplate` <[string]> HTML template for the print footer. Should use the same format as the `headerTemplate`.
- `format` <[string]> Paper format. If set, takes priority over `width` or `height` options. Defaults to 'Letter'.
- `headerTemplate` <[string]> HTML template for the print header. Should be valid HTML markup with following classes used to inject printing values into them:
- `'date'` formatted print date
- `'title'` document title
- `'url'` document location
- `'pageNumber'` current page number
- `'totalPages'` total pages in the document
* `'date'` formatted print date
* `'title'` document title
* `'url'` document location
* `'pageNumber'` current page number
* `'totalPages'` total pages in the document
- `height` <[string]|[number]> Paper height, accepts values labeled with units.
- `landscape` <[boolean]> Paper orientation. Defaults to `false`.
- `margin` <[Object]> Paper margins, defaults to none.
@ -1745,7 +1745,7 @@ Focuses the element, and then uses [`keyboard.down(key)`](#keyboarddownkey) and
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
@ -1769,9 +1769,9 @@ await browser.close();
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
@ -1831,9 +1831,9 @@ Returns the buffer with the captured screenshot.
#### page.selectOption(selector, values[, options])
- `selector` <[string]> A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](#working-with-selectors) for more details.
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
- `value` <[string]> Matches by `option.value`.
- `label` <[string]> Matches by `option.label`.
- `index` <[number]> Matches by the index.
- `value` <[string]> Matches by `option.value`. Optional.
- `label` <[string]> Matches by `option.label`. Optional.
- `index` <[number]> Matches by the index. Optional.
- `options` <[Object]>
- `noWaitAfter` <[boolean]> Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to inaccessible pages. Defaults to `false`.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
@ -1862,9 +1862,9 @@ Shortcut for main frame's [`frame.selectOption(selector, values[, options])`](#f
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]>
#### page.setDefaultNavigationTimeout(timeout)
@ -1968,7 +1968,7 @@ Returns `element.textContent`.
Returns the page's title. Shortcut for main frame's [`frame.title()`](#frametitle).
#### page.touchscreen
- returns: <[Touchscreen]>
- type: <[Touchscreen]>
#### page.type(selector, text[, options])
- `selector` <[string]> A selector to search for element. If there are multiple elements satisfying the selector, the first will be used. See [working with selectors](#working-with-selectors) for more details.
@ -2079,10 +2079,10 @@ await page.waitForFunction(selector => !!document.querySelector(selector), selec
Shortcut for main frame's [`frame.waitForFunction(pageFunction[, arg, options])`](#framewaitforfunctionpagefunction-arg-options).
#### page.waitForLoadState([state, options])
- `state` <"load"|"domcontentloaded"|"networkidle"> Load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the method resolves immediately. Optional.
- `'load'` - wait for the `load` event to be fired.
- `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
- `'networkidle'` - wait until there are no network connections for at least `500` ms.
- `state` <"load"|"domcontentloaded"|"networkidle"> Optional load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the method resolves immediately. Can be one of:
* `'load'` - wait for the `load` event to be fired.
* `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
* `'networkidle'` - wait until there are no network connections for at least `500` ms.
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]>
@ -2112,9 +2112,9 @@ Shortcut for main frame's [`frame.waitForLoadState([state, options])`](#framewai
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `url` <[string]|[RegExp]|[Function]> A glob pattern, regex pattern or predicate receiving [URL] to match while waiting for the navigation.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns 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`.
@ -2168,10 +2168,10 @@ return finalResponse.ok();
- `selector` <[string]> A selector to query for. See [working with selectors](#working-with-selectors) for more details.
- `options` <[Object]>
- `state` <"attached"|"detached"|"visible"|"hidden"> Defaults to `'visible'`. Can be either:
- `'attached'` - wait for element to be present in DOM.
- `'detached'` - wait for element to not be present in DOM.
- `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible.
- `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option.
* `'attached'` - wait for element to be present in DOM.
* `'detached'` - wait for element to not be present in DOM.
* `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible.
* `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]<[null]|[ElementHandle]>>
@ -2225,9 +2225,9 @@ This method returns all of the dedicated [WebWorkers](https://developer.mozilla.
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:
@ -2358,10 +2358,10 @@ const divsCounts = await frame.$$eval('div', (divs, min) => divs.length >= min,
#### frame.addScriptTag(params)
- `params` <[Object]>
- `url` <[string]> URL of a script to be added.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw JavaScript content to be injected into frame.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details.
- `url` <[string]> URL of a script to be added. Optional.
- `path` <[string]> Path to the JavaScript file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw JavaScript content to be injected into frame. Optional.
- `type` <[string]> Script type. Use 'module' in order to load a Javascript ES6 module. See [script](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script) for more details. Optional.
- returns: <[Promise]<[ElementHandle]>>
Returns the added tag when the script's onload fires or when the script content was injected into frame.
@ -2370,9 +2370,9 @@ Adds a `<script>` tag into the page with the desired url or content.
#### frame.addStyleTag(params)
- `params` <[Object]>
- `url` <[string]> URL of the `<link>` tag.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw CSS content to be injected into frame.
- `url` <[string]> URL of the `<link>` tag. Optional.
- `path` <[string]> Path to the CSS file to be injected into frame. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw CSS content to be injected into frame. Optional.
- returns: <[Promise]<[ElementHandle]>>
Returns the added tag when the stylesheet's onload fires or when the CSS content was injected into frame.
@ -2601,9 +2601,9 @@ Returns element attribute value.
- `referer` <[string]> Referer header value. If provided it will take preference over the referer header value set by [`page.setExtraHTTPHeaders(headers)`](#pagesetextrahttpheadersheaders).
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect.
@ -2693,7 +2693,7 @@ Parent frame, if any. Detached frames and main frames return `null`.
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
@ -2704,9 +2704,9 @@ Shortcuts such as `key: "Control+o"` or `key: "Control+Shift+T"` are supported a
#### frame.selectOption(selector, values[, options])
- `selector` <[string]> A selector to query for. See [working with selectors](#working-with-selectors) for more details.
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
- `value` <[string]> Matches by `option.value`.
- `label` <[string]> Matches by `option.label`.
- `index` <[number]> Matches by the index.
- `value` <[string]> Matches by `option.value`. Optional.
- `label` <[string]> Matches by `option.label`. Optional.
- `index` <[number]> Matches by the index. Optional.
- `options` <[Object]>
- `noWaitAfter` <[boolean]> Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to inaccessible pages. Defaults to `false`.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
@ -2732,9 +2732,9 @@ frame.selectOption('select#colors', 'red', 'green', 'blue');
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]>
#### frame.setInputFiles(selector, files[, options])
@ -2863,10 +2863,10 @@ await frame.waitForFunction(selector => !!document.querySelector(selector), sele
```
#### frame.waitForLoadState([state, options])
- `state` <"load"|"domcontentloaded"|"networkidle"> Load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the method returns immediately. Optional.
- `'load'` - wait for the `load` event to be fired.
- `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
- `'networkidle'` - wait until there are no network connections for at least `500` ms.
- `state` <"load"|"domcontentloaded"|"networkidle"> Optional load state to wait for, defaults to `load`. If the state has been already reached while loading current document, the method returns immediately. Can be one of:
* `'load'` - wait for the `load` event to be fired.
* `'domcontentloaded'` - wait for the `DOMContentLoaded` event to be fired.
* `'networkidle'` - wait until there are no network connections for at least `500` ms.
- `options` <[Object]>
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]>
@ -2885,9 +2885,9 @@ await frame.waitForLoadState(); // Waits for 'load' state by default.
- `timeout` <[number]> Maximum operation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultNavigationTimeout(timeout)`](#browsercontextsetdefaultnavigationtimeouttimeout), [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout), [`page.setDefaultNavigationTimeout(timeout)`](#pagesetdefaultnavigationtimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- `url` <[string]|[RegExp]|[Function]> URL string, URL regex pattern or predicate receiving [URL] to match while waiting for the navigation.
- `waitUntil` <"load"|"domcontentloaded"|"networkidle"> When to consider operation succeeded, defaults to `load`. Events can be either:
- `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
- `'load'` - consider operation to be finished when the `load` event is fired.
- `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
* `'domcontentloaded'` - consider operation to be finished when the `DOMContentLoaded` event is fired.
* `'load'` - consider operation to be finished when the `load` event is fired.
* `'networkidle'` - consider operation to be finished when there are no network connections for at least `500` ms.
- returns: <[Promise]<[null]|[Response]>>
Returns 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`.
@ -2907,10 +2907,10 @@ const [response] = await Promise.all([
- `selector` <[string]> A selector to query for. See [working with selectors](#working-with-selectors) for more details.
- `options` <[Object]>
- `state` <"attached"|"detached"|"visible"|"hidden"> Defaults to `'visible'`. Can be either:
- `'attached'` - wait for element to be present in DOM.
- `'detached'` - wait for element to not be present in DOM.
- `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible.
- `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option.
* `'attached'` - wait for element to be present in DOM.
* `'detached'` - wait for element to not be present in DOM.
* `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible.
* `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]<[null]|[ElementHandle]>>
@ -3072,8 +3072,8 @@ expect(await feedHandle.$$eval('.tweet', nodes => nodes.map(n => n.innerText))).
- returns: <[Promise]<[null]|[Object]>>
- `x` <[number]> the x coordinate of the element in pixels.
- `y` <[number]> the y coordinate of the element in pixels.
- width <[number]> the width of the element in pixels.
- height <[number]> the height of the element in pixels.
- `width` <[number]> the width of the element in pixels.
- `height` <[number]> the height of the element in pixels.
This method returns the bounding box of the element, or `null` if the element is not visible. The bounding box is calculated relative to the main frame viewport - which is usually the same as the browser window.
@ -3260,7 +3260,7 @@ Focuses the element, and then uses [`keyboard.down(key)`](#keyboarddownkey) and
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
@ -3288,13 +3288,13 @@ This method waits for the [actionability](./actionability.md) checks, then scrol
This method waits for [actionability](./actionability.md) checks, then tries to scroll element into view, unless it is completely visible as defined by [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)'s ```ratio```.
Throws when ```elementHandle``` does not point to an element [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
Throws when `elementHandle` does not point to an element [connected](https://developer.mozilla.org/en-US/docs/Web/API/Node/isConnected) to a Document or a ShadowRoot.
#### elementHandle.selectOption(values[, options])
- `values` <[null]|[string]|[ElementHandle]|[Array]<[string]>|[Object]|[Array]<[ElementHandle]>|[Array]<[Object]>> Options to select. If the `<select>` has the `multiple` attribute, all matching options are selected, otherwise only the first option matching one of the passed options is selected. String values are equivalent to `{value:'string'}`. Option is considered matching if all specified properties match.
- `value` <[string]> Matches by `option.value`.
- `label` <[string]> Matches by `option.label`.
- `index` <[number]> Matches by the index.
- `value` <[string]> Matches by `option.value`. Optional.
- `label` <[string]> Matches by `option.label`. Optional.
- `index` <[number]> Matches by the index. Optional.
- `options` <[Object]>
- `noWaitAfter` <[boolean]> Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to inaccessible pages. Defaults to `false`.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
@ -3435,10 +3435,10 @@ If the element does not satisfy the condition for the `timeout` milliseconds, th
- `selector` <[string]> A selector to query for. See [working with selectors](#working-with-selectors) for more details.
- `options` <[Object]>
- `state` <"attached"|"detached"|"visible"|"hidden"> Defaults to `'visible'`. Can be either:
- `'attached'` - wait for element to be present in DOM.
- `'detached'` - wait for element to not be present in DOM.
- `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible.
- `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option.
* `'attached'` - wait for element to be present in DOM.
* `'detached'` - wait for element to not be present in DOM.
* `'visible'` - wait for element to have non-empty bounding box and no `visibility:hidden`. Note that element without any content or with `display:none` has an empty bounding box and is not considered visible.
* `'hidden'` - wait for element to be either detached from DOM, or have an empty bounding box or `visibility:hidden`. This is opposite to the `'visible'` option.
- `timeout` <[number]> Maximum time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [`browserContext.setDefaultTimeout(timeout)`](#browsercontextsetdefaulttimeouttimeout) or [`page.setDefaultTimeout(timeout)`](#pagesetdefaulttimeouttimeout) methods.
- returns: <[Promise]<[null]|[ElementHandle]>>
@ -3543,7 +3543,7 @@ Fetches a single property from the referenced object.
#### jsHandle.jsonValue()
- returns: <[Promise]<[Serializable]>>
Returns a JSON representation of the object. If the object has a [`toJSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior) function, it **will not be called**.
Returns a JSON representation of the object. If the object has a `toJSON` function, it **will not be called**.
> **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.
@ -3563,7 +3563,7 @@ Returns a JSON representation of the object. If the object has a [`toJSON`](http
#### consoleMessage.location()
- returns: <[Object]>
- `url` <[string]> URL of the resource if available, otherwise empty string.
- `url` <[string]> URL of the resource.
- `lineNumber` <[number]> 0-based line number in the resource.
- `columnNumber` <[number]> 0-based column number in the resource.
@ -3813,7 +3813,7 @@ Dispatches a `keydown` event.
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
@ -3847,7 +3847,7 @@ page.keyboard.insertText('嗨');
`F1` - `F12`, `Digit0`- `Digit9`, `KeyA`- `KeyZ`, `Backquote`, `Minus`, `Equal`, `Backslash`, `Backspace`, `Tab`, `Delete`, `Escape`, `ArrowDown`, `End`, `Enter`, `Home`, `Insert`, `PageDown`, `PageUp`, `ArrowRight`, `ArrowUp`, etc.
Following modification shortcuts are also suported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Following modification shortcuts are also supported: `Shift`, `Control`, `Alt`, `Meta`, `ShiftLeft`.
Holding down `Shift` will type the text that corresponds to the `key` in the upper case.
@ -3977,9 +3977,9 @@ Dispatches a `touchstart` and `touchend` event with a single touch at the positi
### 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.
@ -4210,8 +4210,8 @@ Selectors can be used to install custom selector engines. See [Working with sele
#### selectors.register(name, script[, options])
- `name` <[string]> Name that is used in selectors as a prefix, e.g. `{name: 'foo'}` enables `foo=myselectorbody` selectors. May only contain `[a-zA-Z0-9_]` characters.
- `script` <[function]|[string]|[Object]> Script that evaluates to a selector engine instance.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory.
- `content` <[string]> Raw script content.
- `path` <[string]> Path to the JavaScript file. If `path` is a relative path, then it is resolved relative to the current working directory. Optional.
- `content` <[string]> Raw script content. Optional.
- `options` <[Object]>
- `contentScript` <[boolean]> Whether to run this selector engine in isolated JavaScript environment. This environment has access to the same DOM, but not any JavaScript objects from the frame's scripts. Defaults to `false`. Note that running as a content script is not guaranteed when this engine is used together with other registered engines.
- returns: <[Promise]>
@ -4266,20 +4266,20 @@ Whenever a network route is set up with [`page.route(url, handler)`](#pagerouteu
#### route.abort([errorCode])
- `errorCode` <[string]> Optional error code. Defaults to `failed`, could be one of the following:
- `'aborted'` - An operation was aborted (due to user action)
- `'accessdenied'` - Permission to access a resource, other than the network, was denied
- `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified host or network.
- `'blockedbyclient'` - The client chose to block the request.
- `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
- `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent.
- `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN).
- `'connectionfailed'` - A connection attempt failed.
- `'connectionrefused'` - A connection attempt was refused.
- `'connectionreset'` - A connection was reset (corresponding to a TCP RST).
- `'internetdisconnected'` - The Internet connection has been lost.
- `'namenotresolved'` - The host name could not be resolved.
- `'timedout'` - An operation timed out.
- `'failed'` - A generic failure occurred.
* `'aborted'` - An operation was aborted (due to user action)
* `'accessdenied'` - Permission to access a resource, other than the network, was denied
* `'addressunreachable'` - The IP address is unreachable. This usually means that there is no route to the specified host or network.
* `'blockedbyclient'` - The client chose to block the request.
* `'blockedbyresponse'` - The request failed because the response was delivered along with requirements which are not met ('X-Frame-Options' and 'Content-Security-Policy' ancestor checks, for instance).
* `'connectionaborted'` - A connection timed out as a result of not receiving an ACK for data sent.
* `'connectionclosed'` - A connection was closed (corresponding to a TCP FIN).
* `'connectionfailed'` - A connection attempt failed.
* `'connectionrefused'` - A connection attempt was refused.
* `'connectionreset'` - A connection was reset (corresponding to a TCP RST).
* `'internetdisconnected'` - The Internet connection has been lost.
* `'namenotresolved'` - The host name could not be resolved.
* `'timedout'` - An operation timed out.
* `'failed'` - A generic failure occurred.
- returns: <[Promise]>
Aborts the route's request.
@ -4359,19 +4359,19 @@ The [WebSocket] class represents websocket connections in the page.
Fired when the websocket closes.
#### webSocket.on('framereceived')
- <[Object]> web socket frame data
- type: <[Object]> web socket frame data
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket recieves a frame.
#### webSocket.on('framesent')
- <[Object]> web socket frame data
- type: <[Object]> web socket frame data
- `payload` <[string]|[Buffer]> frame payload
Fired when the websocket sends a frame.
#### webSocket.on('socketerror')
- <[String]> the error message
- type: <[String]> the error message
Fired when the websocket has an error.
@ -4499,7 +4499,7 @@ for (const worker of page.workers())
<!-- GEN:stop -->
#### worker.on('close')
- <[Worker]>
- type: <[Worker]>
Emitted when this dedicated [WebWorker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) is terminated.
@ -4593,7 +4593,7 @@ const { chromium } = require('playwright'); // Or 'firefox' or 'webkit'.
- `params` <[Object]>
- `wsEndpoint` <[string]> A browser websocket endpoint to connect to. **required**
- `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.
- `logger` <[Logger]> Logger sink for Playwright logging.
- `logger` <[Logger]> Logger sink for Playwright logging. Optional.
- `timeout` <[number]> Maximum time in milliseconds to wait for the connection to be established. Defaults to `30000` (30 seconds). Pass `0` to disable timeout.
- returns: <[Promise]<[Browser]>>
@ -4792,7 +4792,7 @@ Determines whether sink is interested in the logger with the given name and seve
- `message` <[string]|[Error]> log message format
- `args` <[Array]<[Object]>> message arguments
- `hints` <[Object]> optional formatting hints
- `color` <[string]> preferred logger color
- `color` <[string]> Optional preferred logger color.
### class: ChromiumBrowser
* extends: [Browser]
@ -4886,14 +4886,14 @@ const backgroundPage = await context.waitForEvent('backgroundpage');
<!-- GEN:stop -->
#### chromiumBrowserContext.on('backgroundpage')
- <[Page]>
- type: <[Page]>
Emitted when new background page is created in the context.
> **NOTE** Only works with persistent context.
#### chromiumBrowserContext.on('serviceworker')
- <[Worker]>
- type: <[Worker]>
Emitted when new service worker is created in the context.

968
types/types.d.ts vendored

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,17 @@
* limitations under the License.
*/
// @ts-check
/** @typedef {{
* type: 'text' | 'li' | 'code' | 'gen' | 'h1' | 'h2' | 'h3' | 'h4',
* text?: string,
* codeLang?: string,
* lines?: string[],
* liType?: 'default' | 'bullet' | 'ordinal',
* children?: MarkdownNode[]
* }} MarkdownNode */
class Documentation {
/**
* @param {!Array<!Documentation.Class>} classesArray
@ -32,15 +43,16 @@ Documentation.Class = class {
* @param {string} name
* @param {!Array<!Documentation.Member>} membersArray
* @param {?string=} extendsName
* @param {string=} comment
* @param {MarkdownNode[]=} spec
* @param {string[]=} templates
*/
constructor(name, membersArray, extendsName = null, comment = '', templates = []) {
constructor(name, membersArray, extendsName = null, spec = undefined, templates = []) {
this.name = name;
this.membersArray = membersArray;
this.comment = comment;
this.spec = spec;
this.extends = extendsName;
this.templates = templates;
this.comment = '';
this.index();
}
@ -52,6 +64,10 @@ Documentation.Class = class {
/** @type {!Array<!Documentation.Member>} */
this.propertiesArray = [];
/** @type {!Map<string, !Documentation.Member>} */
this.options = new Map();
/** @type {!Array<!Documentation.Member>} */
this.optionsArray = [];
/** @type {!Map<string, !Documentation.Member>} */
this.methods = new Map();
/** @type {!Array<!Documentation.Member>} */
this.methodsArray = [];
@ -118,6 +134,16 @@ Documentation.Class = class {
}
}
}
visit(visitor) {
visitor(this);
for (const p of this.propertiesArray)
p.visit(visitor);
for (const m of this.methodsArray)
m.visit(visitor);
for (const e of this.eventsArray)
e.visit(visitor);
}
};
Documentation.Member = class {
@ -126,20 +152,19 @@ Documentation.Member = class {
* @param {string} name
* @param {?Documentation.Type} type
* @param {!Array<!Documentation.Member>} argsArray
* @param {string=} comment
* @param {string=} returnComment
* @param {MarkdownNode[]=} spec
* @param {boolean=} required
* @param {string[]=} templates
*/
constructor(kind, name, type, argsArray, comment = '', returnComment = '', required = true, templates = []) {
constructor(kind, name, type, argsArray, spec = undefined, required = true, templates = []) {
this.kind = kind;
this.name = name;
this.type = type;
this.comment = comment;
this.returnComment = returnComment;
this.spec = spec;
this.argsArray = argsArray;
this.required = required;
this.templates = templates;
this.comment = '';
/** @type {!Map<string, !Documentation.Member>} */
this.args = new Map();
for (const arg of argsArray)
@ -150,34 +175,41 @@ Documentation.Member = class {
* @param {string} name
* @param {!Array<!Documentation.Member>} argsArray
* @param {?Documentation.Type} returnType
* @param {string=} returnComment
* @param {string=} comment
* @param {MarkdownNode[]=} spec
* @param {string[]=} templates
* @return {!Documentation.Member}
*/
static createMethod(name, argsArray, returnType, returnComment, comment, templates) {
return new Documentation.Member('method', name, returnType, argsArray, comment, returnComment, undefined, templates);
static createMethod(name, argsArray, returnType, spec, templates) {
return new Documentation.Member('method', name, returnType, argsArray, spec, undefined, templates);
}
/**
* @param {string} name
* @param {!Documentation.Type} type
* @param {string=} comment
* @param {MarkdownNode[]=} spec
* @param {boolean=} required
* @return {!Documentation.Member}
*/
static createProperty(name, type, comment, required) {
return new Documentation.Member('property', name, type, [], comment, undefined, required);
static createProperty(name, type, spec, required) {
return new Documentation.Member('property', name, type, [], spec, required);
}
/**
* @param {string} name
* @param {?Documentation.Type=} type
* @param {string=} comment
* @param {MarkdownNode[]=} spec
* @return {!Documentation.Member}
*/
static createEvent(name, type = null, comment) {
return new Documentation.Member('event', name, type, [], comment);
static createEvent(name, type = null, spec) {
return new Documentation.Member('event', name, type, [], spec);
}
visit(visitor) {
visitor(this);
if (this.type)
this.type.visit(visitor);
for (const arg of this.argsArray)
arg.visit(visitor);
}
};
@ -190,7 +222,11 @@ Documentation.Type = class {
this.name = name;
this.properties = properties;
}
visit(visitor) {
for (const p of this.properties || [])
p.visit(visitor);
}
};
module.exports = Documentation;

View File

@ -80,7 +80,7 @@ function checkSources(sources) {
visit(classesByName.get(parent));
};
visit(cls);
return new Documentation.Class(cls.name, Array.from(membersMap.values()), undefined, cls.comment, cls.templates);
return new Documentation.Class(cls.name, Array.from(membersMap.values()), undefined, undefined, cls.templates);
});
}
@ -280,7 +280,7 @@ function checkSources(sources) {
const parameters = signature.parameters.map((s, index) => serializeSymbol(s, [], index < minArgumentCount));
const templates = signature.typeParameters ? signature.typeParameters.map(t => t.symbol.name) : [];
const returnType = serializeType(signature.getReturnType());
return Documentation.Member.createMethod(name, parameters, returnType.name !== 'void' ? returnType : null, undefined, undefined, templates);
return Documentation.Member.createMethod(name, parameters, returnType.name !== 'void' ? returnType : null, undefined, templates);
}
/**

View File

@ -14,326 +14,276 @@
* limitations under the License.
*/
// @ts-check
const { parseArgument } = require('../../parse_md');
const Documentation = require('./Documentation');
const commonmark = require('commonmark');
/** @typedef {import('./Documentation').MarkdownNode} MarkdownNode */
class MDOutline {
/**
* @param {!Page} page
* @param {string} text
* @return {!MDOutline}
* @param {MarkdownNode[]} api
*/
static async create(page, text) {
// Render markdown as HTML.
const reader = new commonmark.Parser();
const parsed = reader.parse(text);
const writer = new commonmark.HtmlRenderer();
const html = writer.render(parsed);
const logConsole = msg => console.log(msg.text());
page.on('console', logConsole);
// Extract headings.
await page.setContent(html);
const {classes, errors} = await page.evaluate(() => {
const classes = [];
const errors = [];
const headers = document.body.querySelectorAll('h3');
for (let i = 0; i < headers.length; i++) {
const fragment = extractSiblingsIntoFragment(headers[i], headers[i + 1]);
classes.push(parseClass(fragment));
}
return {classes, errors};
/**
* @param {HTMLLIElement} element
* @param {boolean} defaultRequired
*/
function parseProperty(element, defaultRequired) {
const clone = element.cloneNode(true);
const ul = clone.querySelector(':scope > ul');
const str = parseComment(extractSiblingsIntoFragment(clone.firstChild, ul));
const name = str.substring(0, str.indexOf('<')).replace(/\`/g, '').trim();
let type = findType(str);
const literals = type.match(/("[^"]+"(\|"[^"]+")*)/);
if (literals) {
const sorted = literals[1].split('|').sort((a, b) => a.localeCompare(b)).join('|');
type = type.substring(0, literals.index) + sorted + type.substring(literals.index + literals[0].length);
}
const properties = [];
let comment = str.substring(str.indexOf('<') + type.length + 2).trim();
const hasNonEnumProperties = type.split('|').some(part => {
const basicTypes = new Set(['string', 'number', 'boolean']);
const arrayTypes = new Set([...basicTypes].map(type => `Array<${type}>`));
return !basicTypes.has(part) && !arrayTypes.has(part) && !(part.startsWith('"') && part.endsWith('"'));
});
if (hasNonEnumProperties) {
for (const childElement of element.querySelectorAll(':scope > ul > li')) {
const text = childElement.textContent;
if (text.startsWith(`"`) || text.startsWith(`'`))
continue;
const property = parseProperty(childElement, true);
property.required = defaultRequired;
if (property.comment.toLowerCase().includes('defaults to '))
property.required = false;
if (property.comment.startsWith('Optional '))
property.required = false;
if (property.comment.toLowerCase().includes('if applicable.'))
property.required = false;
if (property.comment.toLowerCase().includes('if available.'))
property.required = false;
if (property.comment.includes('**required**'))
property.required = true;
properties.push(property);
}
} else if (ul) {
comment += '\n' + parseComment(ul).split('\n').map(l => ` - ${l}`).join('\n');
}
return {
name,
type,
comment,
properties
};
}
/**
* @param {string} str
* @return {string}
*/
function findType(str) {
const start = str.indexOf('<') + 1;
let count = 1;
for (let i = start; i < str.length; i++) {
if (str[i] === '<') count++;
if (str[i] === '>') count--;
if (!count)
return str.substring(start, i);
}
return 'unknown';
}
/**
* @param {DocumentFragment} content
*/
function parseClass(content) {
const members = [];
const commentWalker = document.createTreeWalker(content, NodeFilter.SHOW_COMMENT | NodeFilter.SHOW_ELEMENT, {
acceptNode(node) {
if (node instanceof HTMLElement && node.tagName === 'H4')
return NodeFilter.FILTER_ACCEPT;
if (!(node instanceof Comment))
return NodeFilter.FILTER_REJECT;
if (node.data.trim().startsWith('GEN:toc'))
return NodeFilter.FILTER_ACCEPT;
return NodeFilter.FILTER_REJECT;
}
});
const commentEnd = commentWalker.nextNode();
const headers = content.querySelectorAll('h4');
const name = content.firstChild.textContent;
let extendsName = null;
let commentStart = content.firstChild.nextSibling;
const extendsElement = content.querySelector('ul');
if (extendsElement && extendsElement.textContent.trim().startsWith('extends:')) {
commentStart = extendsElement.nextSibling;
extendsName = extendsElement.querySelector('a').textContent;
}
const comment = parseComment(extractSiblingsIntoFragment(commentStart, commentEnd));
for (let i = 0; i < headers.length; i++) {
const fragment = extractSiblingsIntoFragment(headers[i], headers[i + 1]);
members.push(parseMember(fragment));
}
return {
name,
comment,
extendsName,
members
};
}
/**
* @param {Node} content
*/
function parseComment(content) {
for (const code of content.querySelectorAll('pre > code'))
code.replaceWith('```' + code.className.substring('language-'.length) + '\n' + code.textContent + '```');
for (const code of content.querySelectorAll('code'))
code.replaceWith('`' + code.textContent + '`');
for (const strong of content.querySelectorAll('strong'))
strong.replaceWith('**' + parseComment(strong) + '**');
return content.textContent.trim();
}
/**
* @param {DocumentFragment} content
*/
function parseMember(content) {
const name = content.firstChild.textContent;
const args = [];
let returnType = null;
const paramRegex = /^\w+\.[\w$]+\((.*)\)$/;
const matches = paramRegex.exec(name) || ['', ''];
const parameters = matches[1];
const optionalStartIndex = parameters.indexOf('[');
const optinalParamsStr = optionalStartIndex !== -1 ? parameters.substring(optionalStartIndex).replace(/[\[\]]/g, '') : '';
const optionalparams = new Set(optinalParamsStr.split(',').filter(x => x).map(x => x.trim()));
const ul = content.querySelector('ul');
for (const element of content.querySelectorAll('h4 + ul > li')) {
if (element.matches('li') && element.textContent.trim().startsWith('<')) {
returnType = parseProperty(element, element.textContent.trim().includes('data'));
} else if (element.matches('li') && element.firstChild.matches && element.firstChild.matches('code')) {
const property = parseProperty(element, false);
property.required = !optionalparams.has(property.name) && !property.name.startsWith('...');
args.push(property);
} else if (element.matches('li') && element.firstChild.nodeType === Element.TEXT_NODE && element.firstChild.textContent.toLowerCase().startsWith('return')) {
returnType = parseProperty(element, true);
const expectedText = 'returns: ';
let actualText = element.firstChild.textContent;
let angleIndex = actualText.indexOf('<');
let spaceIndex = actualText.indexOf(' ');
angleIndex = angleIndex === -1 ? actualText.length : angleIndex;
spaceIndex = spaceIndex === -1 ? actualText.length : spaceIndex + 1;
actualText = actualText.substring(0, Math.min(angleIndex, spaceIndex));
if (actualText !== expectedText)
errors.push(`${name} has mistyped 'return' type declaration: expected exactly '${expectedText}', found '${actualText}'.`);
}
}
const comment = parseComment(extractSiblingsIntoFragment(ul ? ul.nextSibling : content.querySelector('h4').nextSibling));
return {
name,
args,
returnType,
comment
};
}
/**
* @param {!Node} fromInclusive
* @param {!Node} toExclusive
* @return {!DocumentFragment}
*/
function extractSiblingsIntoFragment(fromInclusive, toExclusive) {
const fragment = document.createDocumentFragment();
let node = fromInclusive;
while (node && node !== toExclusive) {
const next = node.nextSibling;
fragment.appendChild(node);
node = next;
}
return fragment;
}
});
page.off('console', logConsole);
return new MDOutline(classes, errors);
constructor(api) {
this.classesArray = /** @type {Documentation.Class[]} */ [];
this.classes = /** @type {Map<string, Documentation.Class>} */ new Map();
for (const clazz of api) {
const c = parseClass(clazz);
this.classesArray.push(c);
this.classes.set(c.name, c);
}
this.signatures = this._generateComments();
}
constructor(classes, errors) {
this.classes = [];
this.errors = errors;
const classHeading = /^class: (\w+)$/;
const constructorRegex = /^new (\w+)\((.*)\)$/;
const methodRegex = /^(\w+)\.([\w$]+)\(([^']*)\)$/;
const propertyRegex = /^(\w+)\.(\w+)$/;
const eventRegex = /^.*\.on\('(\w+)'\)$/;
let currentClassName = null;
let currentClassMembers = [];
let currentClassComment = '';
let currentClassExtends = null;
for (const cls of classes) {
const match = cls.name.match(classHeading);
if (!match)
continue;
currentClassName = match[1];
currentClassComment = cls.comment;
currentClassExtends = cls.extendsName;
for (const member of cls.members) {
if (constructorRegex.test(member.name)) {
const match = member.name.match(constructorRegex);
handleMethod.call(this, member, match[1], 'constructor', match[2]);
} else if (methodRegex.test(member.name)) {
const match = member.name.match(methodRegex);
handleMethod.call(this, member, match[1], match[2], match[3]);
} else if (propertyRegex.test(member.name)) {
const match = member.name.match(propertyRegex);
handleProperty.call(this, member, match[1], match[2]);
} else if (eventRegex.test(member.name)) {
const match = member.name.match(eventRegex);
handleEvent.call(this, member, match[1]);
_generateComments() {
/**
* @type {Map<string, string>}
*/
const signatures = new Map();
for (const clazz of this.classesArray) {
for (const method of clazz.methodsArray) {
const tokens = [];
let hasOptional = false;
for (const arg of method.argsArray) {
const optional = !arg.required;
if (tokens.length) {
if (optional && !hasOptional)
tokens.push(`[, ${arg.name}`);
else
tokens.push(`, ${arg.name}`);
} else {
if (optional && !hasOptional)
tokens.push(`[${arg.name}`);
else
tokens.push(`${arg.name}`);
}
hasOptional = hasOptional || optional;
}
if (hasOptional)
tokens.push(']');
const signature = tokens.join('');
const methodName = `${clazz.name}.${method.name}`;
signatures.set(methodName, signature);
}
flushClassIfNeeded.call(this);
}
function handleMethod(member, className, methodName, parameters) {
if (!currentClassName || !className || !methodName || className.toLowerCase() !== currentClassName.toLowerCase()) {
this.errors.push(`Failed to process header as method: ${member.name}`);
return;
}
parameters = parameters.trim().replace(/[\[\]]/g, '');
if (parameters !== member.args.map(arg => arg.name).join(', '))
this.errors.push(`Heading arguments for "${member.name}" do not match described ones, i.e. "${parameters}" != "${member.args.map(a => a.name).join(', ')}"`);
const args = member.args.map(createPropertyFromJSON);
let returnType = null;
let returnComment = '';
if (member.returnType) {
const returnProperty = createPropertyFromJSON(member.returnType);
returnType = returnProperty.type;
returnComment = returnProperty.comment;
}
const method = Documentation.Member.createMethod(methodName, args, returnType, returnComment, member.comment);
currentClassMembers.push(method);
}
function createPropertyFromJSON(payload) {
const type = new Documentation.Type(payload.type, payload.properties.map(createPropertyFromJSON));
const required = payload.required;
return Documentation.Member.createProperty(payload.name, type, payload.comment, required);
}
function handleProperty(member, className, propertyName) {
if (!currentClassName || !className || !propertyName || className.toLowerCase() !== currentClassName.toLowerCase()) {
this.errors.push(`Failed to process header as property: ${member.name}`);
return;
}
const type = member.returnType ? member.returnType.type : null;
const properties = member.returnType ? member.returnType.properties : [];
currentClassMembers.push(createPropertyFromJSON({type, name: propertyName, properties, comment: member.comment}));
}
function handleEvent(member, eventName) {
if (!currentClassName || !eventName) {
this.errors.push(`Failed to process header as event: ${member.name}`);
return;
}
currentClassMembers.push(Documentation.Member.createEvent(eventName, member.returnType && createPropertyFromJSON(member.returnType).type, member.comment));
}
function flushClassIfNeeded() {
if (currentClassName === null)
return;
this.classes.push(new Documentation.Class(currentClassName, currentClassMembers, currentClassExtends, currentClassComment));
currentClassName = null;
currentClassMembers = [];
}
for (const clazz of this.classesArray)
clazz.visit(item => item.comment = renderComments(item.spec, signatures));
return signatures;
}
}
/**
* @param {!Page} page
* @param {!Array<!Source>} sources
* @param {!boolean} copyDocsFromSuperClasses
* @return {!Promise<{documentation: !Documentation, errors: !Array<string>}>}
* @param {MarkdownNode} node
* @returns {Documentation.Class}
*/
module.exports = async function(page, sources, copyDocsFromSuperClasses) {
const classes = [];
const errors = [];
for (const source of sources) {
const outline = await MDOutline.create(page, source.text());
classes.push(...outline.classes);
errors.push(...outline.errors);
function parseClass(node) {
const members = [];
let extendsName = null;
const name = node.text.substring('class: '.length);
for (const member of node.children) {
if (member.type === 'li' && member.text.startsWith('extends: [')) {
extendsName = member.text.substring('extends: ['.length, member.text.indexOf(']'));
continue;
}
if (member.type === 'h2')
members.push(parseMember(member));
}
const documentation = new Documentation(classes);
return new Documentation.Class(name, members, extendsName, extractComments(node));
}
/**
* @param {MarkdownNode} item
* @returns {MarkdownNode[]}
*/
function extractComments(item) {
return (item.children || []).filter(c => c.type !== 'gen' && !c.type.startsWith('h'));
}
/**
* @param {MarkdownNode[]} spec
* @param {Map<string, string>} [signatures]
*/
function renderComments(spec, signatures) {
const result = [];
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, '');
}
}
return result.join('\n');
}
/**
* @param {string} comment
* @param {Map<string, string>} signatures
*/
function patchSignatures(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}')\``;
if (type === 'method') {
const signature = signatures.get(`${clazzPrefix}${clazz}.${name}`) || '';
return `\`${className}.${name}(${signature})\``;
}
return `\`${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;
}
/**
* @param {MarkdownNode} member
* @returns {Documentation.Member}
*/
function parseMember(member) {
const args = [];
const match = member.text.match(/(event|method|property|async method|): (JS|CDP|[A-Z])([^.]+)\.(.*)/);
const name = match[4];
let returnType = null;
const options = [];
for (const item of member.children || []) {
if (item.type === 'li' && item.liType === 'default')
returnType = parseType(item);
}
if (!returnType)
returnType = new Documentation.Type('void');
if (match[1] === 'async method')
returnType.name = `Promise<${returnType.name}>`;
if (match[1] === 'event')
return Documentation.Member.createEvent(name, returnType, extractComments(member));
if (match[1] === 'property')
return Documentation.Member.createProperty(name, returnType, extractComments(member), true);
for (const item of member.children || []) {
if (item.type === 'h3' && item.text.startsWith('param:'))
args.push(parseProperty(item));
if (item.type === 'h3' && item.text.startsWith('option:'))
options.push(parseProperty(item));
}
if (options.length) {
options.sort((o1, o2) => o1.name.localeCompare(o2.name));
for (const option of options)
option.required = false;
const type = new Documentation.Type('Object', options);
args.push(Documentation.Member.createProperty('options', type, undefined, false));
}
return Documentation.Member.createMethod(name, args, returnType, extractComments(member));
}
/**
* @param {MarkdownNode} spec
* @return {Documentation.Member}
*/
function parseProperty(spec) {
const param = spec.children[0];
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)));
}
/**
* @param {MarkdownNode=} spec
* @return {Documentation.Type}
*/
function parseType(spec) {
const { type } = parseArgument(spec.text);
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 properties = [];
const hasNonEnumProperties = typeName.split('|').some(part => {
const basicTypes = new Set(['string', 'number', 'boolean']);
const arrayTypes = new Set([...basicTypes].map(type => `Array<${type}>`));
return !basicTypes.has(part) && !arrayTypes.has(part) && !(part.startsWith('"') && part.endsWith('"'));
});
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 }]);
properties.push(Documentation.Member.createProperty(name, parseType(child), comments, guessRequired(text)));
}
}
return new Documentation.Type(typeName, properties);
}
/**
* @param {string} comment
*/
function guessRequired(comment) {
let required = true;
if (comment.toLowerCase().includes('defaults to '))
required = false;
if (comment.startsWith('Optional'))
required = false;
if (comment.endsWith('Optional.'))
required = false;
if (comment.toLowerCase().includes('if set'))
required = false;
if (comment.toLowerCase().includes('if applicable'))
required = false;
if (comment.toLowerCase().includes('if available'))
required = false;
if (comment.includes('**required**'))
required = true;
return required;
}
module.exports =
/**
* @param {any} api
* @param {boolean} copyDocsFromSuperClasses
*/
function(api, copyDocsFromSuperClasses) {
const errors = [];
const outline = new MDOutline(api);
const documentation = new Documentation(outline.classesArray);
if (copyDocsFromSuperClasses) {
// Push base class documentation to derived classes.
@ -356,5 +306,7 @@ module.exports = async function(page, sources, copyDocsFromSuperClasses) {
clazz.index();
}
}
return { documentation, errors };
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,12 +24,10 @@ const EXCLUDE_PROPERTIES = new Set([
]);
/**
* @param {!Page} page
* @param {!Array<!Source>} mdSources
* @return {!Promise<!Array<!Message>>}
*/
module.exports = async function lint(page, mdSources, jsSources) {
const mdResult = await mdBuilder(page, mdSources, true);
module.exports = function lint(api, jsSources) {
const mdResult = mdBuilder(api, true);
const jsResult = jsBuilder.checkSources(jsSources);
const jsDocumentation = filterJSDocumentation(jsSources, jsResult.documentation);
const mdDocumentation = mdResult.documentation;
@ -120,12 +118,14 @@ function compareDocumentations(actual, expected) {
for (const methodName of methodDiff.equal) {
const actualMethod = actualClass.methods.get(methodName);
const expectedMethod = expectedClass.methods.get(methodName);
if (!actualMethod.type !== !expectedMethod.type) {
if (actualMethod.type)
errors.push(`Method ${className}.${methodName} has unneeded description of return type`);
else
errors.push(`Method ${className}.${methodName} is missing return type description`);
} else if (actualMethod.type) {
const hasActualType = actualMethod.type && actualMethod.type.name !== 'void';
const hasExpectedType = expectedMethod.type && expectedMethod.type.name !== 'void';
if (hasActualType !== hasExpectedType) {
if (hasActualType)
errors.push(`Method ${className}.${methodName} has unneeded description of return type: `+ actualMethod.type.name);
else if (hasExpectedType)
errors.push(`Method ${className}.${methodName} is missing return type description: ` + expectedMethod.type.name);
} else if (hasActualType) {
checkType(`Method ${className}.${methodName} has the wrong return type: `, actualMethod.type, expectedMethod.type);
}
const actualArgs = Array.from(actualMethod.args.keys());

View File

@ -1,15 +1,17 @@
### class: Bar
# class: Bar
### class: Foo
# class: Foo
#### foo.test()
## method: Foo.test
#### foo.test()
## method: Foo.test
#### foo.title(arg, arg)
- `arg` <[number]>
## method: Foo.title
### param: Foo.title.arg
- `arg` <[number]>
### class: Bar
### param: Foo.title.arg
- `arg` <[number]>
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
# class: Bar

View File

@ -1,5 +1,5 @@
class Foo {
bar(options: {x: number, y: number, maybe?: number, nullable: string|null, object?: {one: number, two?: number}}) {
bar(options?: {x?: number, y?: number, maybe?: number, nullable?: string|null, object?: {one: number, two?: number}}) {
}

View File

@ -1,32 +1,33 @@
### class: Foo
# class: Foo
#### foo.bar(options)
- `options` <[Object]>
- `x` <[number]> **required**
- `y` <[number]> **required**
- `nullable` <?[string]> **required**
- `maybe` <[number]>
- `object` <[Object]>
- `one` <[number]>
- `two` <[number]> defaults to `2`.
## method: Foo.bar
#### foo.baz()
### option: Foo.bar.x
- `x` <[number]>
### option: Foo.bar.y
- `y` <[number]>
### option: Foo.bar.nullable
- `nullable` <?[string]>
### option: Foo.bar.maybe
- `maybe` <[number]>
### option: Foo.bar.object
- `object` <[Object]>
- `one` <[number]>
- `two` <[number]> defaults to `2`.
## method: Foo.baz
- returns: <?[Object]>
- `abc` <[number]>
- `def` <[number]> if applicable.
- `ghi` <[string]>
#### foo.goBack()
## method: Foo.goBack
- returns: <[Promise]<?[Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. If
can not go back, resolves to `null`.
#### foo.response()
## method: Foo.response
- returns: <?[Response]> A matching [Response] object, or `null` if the response has not been received yet.
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Object_type "Object"
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type "number"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Promise_type "Promise"
[Response]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Response_type "Response"

View File

@ -1,14 +1,11 @@
### class: Foo
# class: Foo
#### foo.asyncFunction()
## async method: Foo.asyncFunction
#### foo.return42()
## method: Foo.return42
#### foo.returnNothing()
## method: Foo.returnNothing
- returns: <[number]>
#### foo.www()
- returns <[string]>
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
## method: Foo.www
- returns: <[string]>

View File

@ -1,4 +1,2 @@
[MarkDown] foo.www() has mistyped 'return' type declaration: expected exactly 'returns: ', found 'returns '.
[MarkDown] Method Foo.asyncFunction is missing return type description
[MarkDown] Method Foo.return42 is missing return type description
[MarkDown] Method Foo.returnNothing has unneeded description of return type
[MarkDown] Method Foo.return42 is missing return type description: number
[MarkDown] Method Foo.returnNothing has unneeded description of return type: number

View File

@ -1,15 +1,15 @@
### class: Foo
# class: Foo
#### foo.on('c')
## event: Foo.c
#### foo.on('a')
## event: Foo.a
#### foo.aaa()
## method: Foo.aaa
#### foo.on('b')
## event: Foo.b
#### foo.ddd
## property: Foo.ddd
#### foo.ccc()
## method: Foo.ccc
#### foo.bbb()
## method: Foo.bbb

View File

@ -2,10 +2,10 @@ class Foo {
foo(arg1: string, arg3 = {}) {
}
test(...filePaths : string[]) {
test(filePaths : string[]) {
}
bar(options: {visibility?: boolean}) {
bar(options?: {visibility?: boolean}) {
}
}
export {Foo};

View File

@ -1,14 +1,19 @@
### class: Foo
#### foo.bar(options)
- `options` <[Object]>
- `visibility` <[boolean]>
#### foo.foo(arg1, arg2)
# class: Foo
## method: Foo.bar
### option: Foo.bar.visibility
- `visibility` <[boolean]>
## method: Foo.foo
### param: Foo.foo.arg1
- `arg1` <[string]>
### param: Foo.foo.arg2
- `arg2` <[string]>
#### foo.test(...files)
- `...filePaths` <...[string]>
## method: Foo.test
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object"
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
### param: Foo.test.filePaths
- `filePaths` <[Array]<[string]>>

View File

@ -1,4 +1,3 @@
[MarkDown] Heading arguments for "foo.test(...files)" do not match described ones, i.e. "...files" != "...filePaths"
[MarkDown] Method Foo.foo() fails to describe its parameters:
- Implemented but not documented argument: arg3
- Documented but not implemented argument: arg2

View File

@ -1,5 +1,5 @@
### class: Foo
# class: Foo
### class: Bar
# class: Bar
### class: Baz
# class: Baz

View File

@ -1,5 +1,5 @@
### class: Foo
# class: Foo
#### foo.on('start')
## event: Foo.start
#### foo.on('stop')
## event: Foo.stop

View File

@ -1,10 +1,10 @@
### class: Foo
# class: Foo
#### foo.$()
## method: Foo.$
#### foo.money$$money()
## method: Foo.money$$money
#### foo.proceed()
## method: Foo.proceed
#### foo.start()
## method: Foo.start

View File

@ -1,5 +1,5 @@
### class: Foo
# class: Foo
#### foo.a
## property: Foo.a
#### foo.c
## property: Foo.c

View File

@ -1,15 +1,18 @@
### class: Foo
# class: Foo
#### foo.method(arg1, arg2)
- `arg1` <[string]> A single line argument comment
- `arg2` <[string]> A multiline argument comment:
- it could be this
- or it could be that
## method: Foo.method
- returns: <[Promise]<[ElementHandle]>>
The method does something.
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[ElementHandle]: # "ElementHandle"
[ElementHandle]: # "Frame"
### param: Foo.method.arg1
- `arg1` <[string]>
A single line argument comment
### param: Foo.method.arg2
- `arg2` <[string]>
A multiline argument comment:
* it could be this
* or it could be that

View File

@ -25,7 +25,7 @@
"name": "string"
},
"kind": "property",
"comment": "A multiline argument comment:\n - it could be this\n - or it could be that"
"comment": "A multiline argument comment:\n- it could be this\n- or it could be that"
}
]
}

View File

@ -1,24 +1,23 @@
### class: Foo
# class: Foo
This is a class.
#### foo.on('frame')
- <[Frame]>
## event: Foo.frame
- type: <[Frame]>
This event is dispatched.
#### foo.$(selector)
- `selector` <[string]> A selector to query page for
## method: Foo.$
- returns: <[Promise]<[ElementHandle]>>
The method runs document.querySelector.
#### foo.url
- <[string]>
### param: Foo.$.selector
- `selector` <[string]>
A selector to query page for
## property: Foo.url
- type: <[string]>
Contains the URL of the request.
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[ElementHandle]: # "ElementHandle"
[ElementHandle]: # "Frame"

View File

@ -7,7 +7,7 @@
{
"name": "frame",
"type": {
"name": "[Frame]"
"name": "Frame"
},
"kind": "event",
"comment": "This event is dispatched."

View File

@ -16,20 +16,14 @@
const fs = require('fs');
const path = require('path');
const playwright = require('../../../../');
const checkPublicAPI = require('..');
const Source = require('../../Source');
const mdBuilder = require('../MDBuilder');
const jsBuilder = require('../JSBuilder');
const { folio } = require('folio');
const { parseMd } = require('../../../parse_md');
const fixtures = folio.extend();
fixtures.page.init(async({}, test) => {
const browser = await playwright.chromium.launch();
const page = await browser.newPage();
await test(page);
await browser.close();
}, { scope: 'worker' });
const { describe, it, expect } = fixtures.build();
describe('checkPublicAPI', function() {
@ -49,22 +43,22 @@ describe('checkPublicAPI', function() {
});
async function testLint(name) {
it(name, async({page}) => {
it(name, async({}) => {
const dirPath = path.join(__dirname, name);
const mdSources = await Source.readdir(dirPath, '.md');
const api = parseMd(fs.readFileSync(path.join(dirPath, 'doc.md')).toString());
const tsSources = await Source.readdir(dirPath, '.ts');
const jsSources = await Source.readdir(dirPath, '.js');
const messages = await checkPublicAPI(page, mdSources, jsSources.concat(tsSources));
const messages = await checkPublicAPI(api, jsSources.concat(tsSources));
const errors = messages.map(message => message.text);
expect(errors.join('\n')).toBe(fs.readFileSync(path.join(dirPath, 'result.txt')).toString());
});
}
async function testMDBuilder(name) {
it(name, async({page}) => {
it(name, ({}) => {
const dirPath = path.join(__dirname, name);
const sources = await Source.readdir(dirPath, '.md');
const {documentation} = await mdBuilder(page, sources, true);
const api = parseMd(fs.readFileSync(path.join(dirPath, 'doc.md')).toString());
const {documentation} = mdBuilder(api, true);
expect(serialize(documentation)).toBe(fs.readFileSync(path.join(dirPath, 'result.txt')).toString());
});
}

View File

@ -18,12 +18,12 @@
const playwright = require('../../');
const fs = require('fs');
const path = require('path');
const os = require('os');
const Source = require('./Source');
const Message = require('./Message');
const { parseMd, renderMd, parseArgument, applyTemplates } = require('./../parse_md');
const { spawnSync } = require('child_process');
const preprocessor = require('./preprocessor');
const mdBuilder = require('./check_public_api/MDBuilder');
const PROJECT_DIR = path.join(__dirname, '..', '..');
const VERSION = require(path.join(PROJECT_DIR, 'package.json')).version;
@ -62,7 +62,8 @@ async function run() {
// Generate signatures
{
const nodes = applyTemplates(parseMd(body), parseMd(params));
const signatures = new Map();
const { outline } = mdBuilder(nodes);
const signatures = outline.signatures;
for (const clazz of nodes) {
clazz.type = 'h3';
for (const member of clazz.children) {
@ -70,7 +71,7 @@ async function run() {
continue;
member.type = 'h4';
let match = member.text.match(/(event|method|namespace|async method|): (JS|CDP|[A-Z])([^.]+)\.(.*)/);
let match = member.text.match(/(event|method|property|async method|): (JS|CDP|[A-Z])([^.]+)\.(.*)/);
if (!match)
continue;
@ -89,9 +90,9 @@ async function run() {
if (item.type === 'li' && item.liType === 'default') {
const { type } = parseArgument(item.text);
if (match[1] === 'method')
item.text = `returns: ${type}`;
item.text = `returns: <${type}>`;
else
item.text = `returns: <[Promise]${type}>`;
item.text = `returns: <[Promise]<${type}>>`;
returnContainer.push(item);
continue;
}
@ -103,6 +104,8 @@ async function run() {
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);
}
@ -121,6 +124,8 @@ async function run() {
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);
}
}
@ -134,33 +139,13 @@ async function run() {
if (optionsContainer[0])
optionsContainer[0].children.sort((o1, o2) => o1.text.localeCompare(o2.text));
member.children = [...argChildren, ...optionsContainer, ...returnContainer, ...nonArgChildren];
const tokens = [];
let hasOptional = false;
for (const arg of args) {
const optional = arg.name === 'options' || arg.text.includes('Optional');
if (tokens.length) {
if (optional && !hasOptional)
tokens.push(`[, ${arg.name}`);
else
tokens.push(`, ${arg.name}`);
} else {
if (optional && !hasOptional)
tokens.push(`[${arg.name}`);
else
tokens.push(`${arg.name}`);
}
hasOptional = hasOptional || optional;
}
if (hasOptional)
tokens.push(']');
const signature = tokens.join('');
const methodName = `${match[2].toLowerCase() + match[3]}.${match[4]}`;
signatures.set(methodName, signature);
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] === 'namespace') {
if (match[1] === 'property') {
member.text = `${match[2].toLowerCase() + match[3]}.${match[4]}`;
continue;
}
@ -187,12 +172,13 @@ async function run() {
for (const source of mdSources.filter(source => source.hasUpdatedText()))
messages.push(Message.warning(`WARN: updated ${source.projectPath()}`));
const browser = await playwright.chromium.launch();
const page = await browser.newPage();
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(...await checkPublicAPI(page, [api], jsSources));
await browser.close();
messages.push(...checkPublicAPI(api, jsSources));
for (const source of mdSources) {
if (!source.hasUpdatedText())

View File

@ -14,21 +14,20 @@
* limitations under the License.
*/
const playwright = require('../..');
const fs = require('fs');
const path = require('path');
const Source = require('./Source');
const { parseMd, applyTemplates } = require('../parse_md');
const mdBuilder = require('./check_public_api/MDBuilder');
const PROJECT_DIR = path.join(__dirname, '..', '..');
(async () => {
const api = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'api.md'));
const browser = await playwright.chromium.launch();
const page = await browser.newPage();
const { documentation } = await mdBuilder(page, [api], false);
{
const apiBody = parseMd(fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-body.md')).toString());
const apiParams = parseMd(fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-params.md')).toString());
const api = applyTemplates(apiBody, apiParams);
const { documentation } = mdBuilder(api, false);
const result = serialize(documentation);
console.log(JSON.stringify(result));
await browser.close();
})()
}
function serialize(documentation) {
const result = {};

View File

@ -193,7 +193,7 @@ function generateLinks(source, signatures, messages) {
const linkOffset = offset + lineNumber + match.index;
const hrefOffset = offset + lineNumber + match.index + 3 + name.length;
let replacement;
const memberMatch = name.match(/`(event|method|namespace):\s(JS|CDP|[A-Z])([^.]+)\.(.*)`/m);
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}`));
@ -203,10 +203,11 @@ function generateLinks(source, signatures, messages) {
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(method);
let signature = signatures.get(key);
if (signature === undefined) {
messages.push(Message.error(`Bad method link: ${source.filePath()}:${lineNumber + 1}: ${method}`));
messages.push(Message.error(`Bad method link: ${source.filePath()}:${lineNumber + 1}: ${key}`));
signature = '(\u2026)';
}
replacement = method + '(' + signature + ')';

View File

@ -17,12 +17,14 @@
//@ts-check
const path = require('path');
const Source = require('../doclint/Source');
const {chromium, devices} = require('../..');
const {devices} = require('../..');
const Documentation = require('../doclint/check_public_api/Documentation');
const PROJECT_DIR = path.join(__dirname, '..', '..');
const fs = require('fs');
const {parseOverrides} = require('./parseOverrides');
const exported = require('./exported.json');
const { parseMd, applyTemplates } = require('../parse_md');
const objectDefinitions = [];
const handledMethods = new Set();
/** @type {Documentation} */
@ -35,11 +37,10 @@ let hadChanges = false;
fs.mkdirSync(typesDir)
writeFile(path.join(typesDir, 'protocol.d.ts'), fs.readFileSync(path.join(PROJECT_DIR, 'src', 'server', 'chromium', 'protocol.ts'), 'utf8'));
writeFile(path.join(typesDir, 'trace.d.ts'), fs.readFileSync(path.join(PROJECT_DIR, 'src', 'trace', 'traceTypes.ts'), 'utf8'));
const browser = await chromium.launch();
const page = await browser.newPage();
const api = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'api.md'));
const {documentation: mdDocumentation} = await require('../doclint/check_public_api/MDBuilder')(page, [api], true);
await browser.close();
const apiBody = parseMd(fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-body.md')).toString());
const apiParams = parseMd(fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-params.md')).toString());
const api = applyTemplates(apiBody, apiParams);
const {documentation: mdDocumentation} = require('../doclint/check_public_api/MDBuilder')(api, true);
const sources = await Source.readdir(path.join(PROJECT_DIR, 'src', 'client'), '', []);
const {documentation: jsDocumentation} = await require('../doclint/check_public_api/JSBuilder').checkSources(sources);
documentation = mergeDocumentation(mdDocumentation, jsDocumentation);
@ -408,8 +409,6 @@ function memberJSDOC(member, indent) {
if (member.comment)
lines.push(...member.comment.split('\n'));
lines.push(...member.argsArray.map(arg => `@param ${arg.name.replace(/\./g, '')} ${arg.comment.replace('\n', ' ')}`));
if (member.returnComment)
lines.push(`@returns ${member.returnComment}`);
if (!lines.length)
return indent;
return writeComment(lines.join('\n'), indent) + '\n' + indent;

View File

@ -268,16 +268,22 @@ function applyTemplates(body, params) {
return body;
}
/**
* @param {string} line
* @returns {{ name: string, type: string, text: string }}
*/
function parseArgument(line) {
let match = line.match(/`([^`]+)` (.*)/);
let match = line.match(/^`([^`]+)` (.*)/);
if (!match)
match = line.match(/(returns): (.*)/);
match = line.match(/^(returns): (.*)/);
if (!match)
match = line.match(/^(type): (.*)/);
if (!match)
throw new Error('Invalid argument: ' + line);
const name = match[1];
const remainder = match[2];
if (!remainder.startsWith('<'))
console.error('Bad argument:', remainder);
throw new Error('Bad argument: ' + remainder);
let depth = 0;
for (let i = 0; i < remainder.length; ++i) {
const c = remainder.charAt(i);
@ -286,9 +292,9 @@ function parseArgument(line) {
if (c === '>')
--depth;
if (depth === 0)
return { name, type: remainder.substring(0, i + 1), text: remainder.substring(i + 2) };
return { name, type: remainder.substring(1, i), text: remainder.substring(i + 2) };
}
throw new Error('Should not be reached');
}
module.exports = { parseMd, renderMd, parseArgument, applyTemplates };
module.exports = { parseMd, renderMd, parseArgument, applyTemplates, clone };