docs: more docs update (#327)
This commit is contained in:
parent
701b5db452
commit
8f480a3987
102
docs/api.md
102
docs/api.md
|
|
@ -91,6 +91,7 @@
|
||||||
* [page.content()](#pagecontent)
|
* [page.content()](#pagecontent)
|
||||||
* [page.coverage](#pagecoverage)
|
* [page.coverage](#pagecoverage)
|
||||||
* [page.dblclick(selector[, options])](#pagedblclickselector-options)
|
* [page.dblclick(selector[, options])](#pagedblclickselector-options)
|
||||||
|
* [page.emulateMedia(options)](#pageemulatemediaoptions)
|
||||||
* [page.evaluate(pageFunction[, ...args])](#pageevaluatepagefunction-args)
|
* [page.evaluate(pageFunction[, ...args])](#pageevaluatepagefunction-args)
|
||||||
* [page.evaluateHandle(pageFunction[, ...args])](#pageevaluatehandlepagefunction-args)
|
* [page.evaluateHandle(pageFunction[, ...args])](#pageevaluatehandlepagefunction-args)
|
||||||
* [page.evaluateOnNewDocument(pageFunction[, ...args])](#pageevaluateonnewdocumentpagefunction-args)
|
* [page.evaluateOnNewDocument(pageFunction[, ...args])](#pageevaluateonnewdocumentpagefunction-args)
|
||||||
|
|
@ -116,10 +117,12 @@
|
||||||
* [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout)
|
* [page.setDefaultNavigationTimeout(timeout)](#pagesetdefaultnavigationtimeouttimeout)
|
||||||
* [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout)
|
* [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout)
|
||||||
* [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders)
|
* [page.setExtraHTTPHeaders(headers)](#pagesetextrahttpheadersheaders)
|
||||||
|
* [page.setViewport(viewport)](#pagesetviewportviewport)
|
||||||
* [page.title()](#pagetitle)
|
* [page.title()](#pagetitle)
|
||||||
* [page.tripleclick(selector[, options])](#pagetripleclickselector-options)
|
* [page.tripleclick(selector[, options])](#pagetripleclickselector-options)
|
||||||
* [page.type(selector, text[, options])](#pagetypeselector-text-options)
|
* [page.type(selector, text[, options])](#pagetypeselector-text-options)
|
||||||
* [page.url()](#pageurl)
|
* [page.url()](#pageurl)
|
||||||
|
* [page.viewport()](#pageviewport)
|
||||||
* [page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#pagewaitforselectororfunctionortimeout-options-args)
|
* [page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])](#pagewaitforselectororfunctionortimeout-options-args)
|
||||||
* [page.waitForFunction(pageFunction[, options[, ...args]])](#pagewaitforfunctionpagefunction-options-args)
|
* [page.waitForFunction(pageFunction[, options[, ...args]])](#pagewaitforfunctionpagefunction-options-args)
|
||||||
* [page.waitForNavigation([options])](#pagewaitfornavigationoptions)
|
* [page.waitForNavigation([options])](#pagewaitfornavigationoptions)
|
||||||
|
|
@ -257,7 +260,6 @@
|
||||||
* [response.text()](#responsetext)
|
* [response.text()](#responsetext)
|
||||||
* [response.url()](#responseurl)
|
* [response.url()](#responseurl)
|
||||||
- [class: ChromiumTarget](#class-chromiumtarget)
|
- [class: ChromiumTarget](#class-chromiumtarget)
|
||||||
* [chromiumTarget.browser()](#chromiumtargetbrowser)
|
|
||||||
* [chromiumTarget.browserContext()](#chromiumtargetbrowsercontext)
|
* [chromiumTarget.browserContext()](#chromiumtargetbrowsercontext)
|
||||||
* [chromiumTarget.createCDPSession()](#chromiumtargetcreatecdpsession)
|
* [chromiumTarget.createCDPSession()](#chromiumtargetcreatecdpsession)
|
||||||
* [chromiumTarget.opener()](#chromiumtargetopener)
|
* [chromiumTarget.opener()](#chromiumtargetopener)
|
||||||
|
|
@ -792,7 +794,7 @@ await browserContext.setCookies([cookieObject1, cookieObject2]);
|
||||||
|
|
||||||
#### browserContext.setPermissions(origin, permissions[])
|
#### browserContext.setPermissions(origin, permissions[])
|
||||||
- `origin` <[string]> The [origin] to grant permissions to, e.g. "https://example.com".
|
- `origin` <[string]> The [origin] to grant permissions to, e.g. "https://example.com".
|
||||||
- `permissions` <[Array]<[string]>> An array of permissions to grant. All permissions that are not listed here will be automatically denied. Permissions can be one of the following values:
|
- `permissions` <[Array]<string>> An array of permissions to grant. All permissions that are not listed here will be automatically denied. Permissions can be one of the following values:
|
||||||
- `'geolocation'`
|
- `'geolocation'`
|
||||||
- `'midi'`
|
- `'midi'`
|
||||||
- `'midi-sysex'` (system-exclusive midi)
|
- `'midi-sysex'` (system-exclusive midi)
|
||||||
|
|
@ -1142,6 +1144,41 @@ Bear in mind that if the first click of the `dblclick()` triggers a navigation e
|
||||||
|
|
||||||
Shortcut for [page.mainFrame().dblclick(selector[, options])](#framedblclickselector-options).
|
Shortcut for [page.mainFrame().dblclick(selector[, options])](#framedblclickselector-options).
|
||||||
|
|
||||||
|
#### page.emulateMedia(options)
|
||||||
|
- `options` <[Object]>
|
||||||
|
- `type` <"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.
|
||||||
|
- `colorScheme` <"dark"|"light"|"no-preference"> Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`.
|
||||||
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
```js
|
||||||
|
await page.evaluate(() => matchMedia('screen').matches));
|
||||||
|
// → true
|
||||||
|
await page.evaluate(() => matchMedia('print').matches));
|
||||||
|
// → true
|
||||||
|
|
||||||
|
await page.emulateMedia({ type: 'print' });
|
||||||
|
await page.evaluate(() => matchMedia('screen').matches));
|
||||||
|
// → false
|
||||||
|
await page.evaluate(() => matchMedia('print').matches));
|
||||||
|
// → true
|
||||||
|
|
||||||
|
await page.emulateMedia({});
|
||||||
|
await page.evaluate(() => matchMedia('screen').matches));
|
||||||
|
// → true
|
||||||
|
await page.evaluate(() => matchMedia('print').matches));
|
||||||
|
// → true
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
await page.emulateMedia({ colorScheme: 'dark' }] });
|
||||||
|
await page.evaluate(() => matchMedia('(prefers-color-scheme: dark)').matches));
|
||||||
|
// → true
|
||||||
|
await page.evaluate(() => matchMedia('(prefers-color-scheme: light)').matches));
|
||||||
|
// → false
|
||||||
|
await page.evaluate(() => matchMedia('(prefers-color-scheme: no-preference)').matches));
|
||||||
|
// → false
|
||||||
|
```
|
||||||
|
|
||||||
#### page.evaluate(pageFunction[, ...args])
|
#### page.evaluate(pageFunction[, ...args])
|
||||||
- `pageFunction` <[function]|[string]> Function to be evaluated in the page context
|
- `pageFunction` <[function]|[string]> Function to be evaluated in the page context
|
||||||
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
||||||
|
|
@ -1525,6 +1562,32 @@ The extra HTTP headers will be sent with every request the page initiates.
|
||||||
|
|
||||||
> **NOTE** page.setExtraHTTPHeaders does not guarantee the order of headers in the outgoing requests.
|
> **NOTE** page.setExtraHTTPHeaders does not guarantee the order of headers in the outgoing requests.
|
||||||
|
|
||||||
|
#### page.setViewport(viewport)
|
||||||
|
- `viewport` <[Object]>
|
||||||
|
- `width` <[number]> page width in pixels. **required**
|
||||||
|
- `height` <[number]> page height in pixels. **required**
|
||||||
|
- `deviceScaleFactor` <[number]> Specify device scale factor (can be thought of as dpr). Defaults to `1`.
|
||||||
|
- `isMobile` <[boolean]> Whether the `meta viewport` tag is taken into account. Defaults to `false`.
|
||||||
|
- `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false`
|
||||||
|
- `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`.
|
||||||
|
- returns: <[Promise]>
|
||||||
|
|
||||||
|
> **NOTE** in certain cases, setting viewport will reload the page in order to set the `isMobile` or `hasTouch` properties.
|
||||||
|
|
||||||
|
In the case of multiple pages in a single browser, each page can have its own viewport size.
|
||||||
|
|
||||||
|
`page.setViewport` will resize the page. A lot of websites don't expect phones to change size, so you should set the viewport before navigating to the page.
|
||||||
|
|
||||||
|
```js
|
||||||
|
const page = await browser.newPage();
|
||||||
|
await page.setViewport({
|
||||||
|
width: 640,
|
||||||
|
height: 480,
|
||||||
|
deviceScaleFactor: 1,
|
||||||
|
});
|
||||||
|
await page.goto('https://example.com');
|
||||||
|
```
|
||||||
|
|
||||||
#### page.title()
|
#### page.title()
|
||||||
- returns: <[Promise]<[string]>> The page's title.
|
- returns: <[Promise]<[string]>> The page's title.
|
||||||
|
|
||||||
|
|
@ -1577,15 +1640,23 @@ Shortcut for [page.mainFrame().type(selector, text[, options])](#frametypeselect
|
||||||
|
|
||||||
This is a shortcut for [page.mainFrame().url()](#frameurl)
|
This is a shortcut for [page.mainFrame().url()](#frameurl)
|
||||||
|
|
||||||
|
#### page.viewport()
|
||||||
|
- returns: <?[Object]>
|
||||||
|
- `width` <[number]> page width in pixels.
|
||||||
|
- `height` <[number]> page height in pixels.
|
||||||
|
- `deviceScaleFactor` <[number]> Specify device scale factor (can be though of as dpr). Defaults to `1`.
|
||||||
|
- `isMobile` <[boolean]> Whether the `meta viewport` tag is taken into account. Defaults to `false`.
|
||||||
|
- `hasTouch`<[boolean]> Specifies if viewport supports touch events. Defaults to `false`
|
||||||
|
- `isLandscape` <[boolean]> Specifies if viewport is in landscape mode. Defaults to `false`.
|
||||||
|
|
||||||
#### page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
|
#### page.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
|
||||||
- `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
|
- `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
|
||||||
- `options` <[Object]> Optional waiting parameters
|
- `options` <[Object]> Optional waiting parameters
|
||||||
- `visible` <[boolean]> wait for element to be present in DOM and to be visible. Defaults to `false`.
|
- `visibility` <"visible"|"hidden"|"any"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`any`). Defaults to `any`.
|
||||||
- `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 [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
- `polling` <[number]|"raf"|"mutation"> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it can be one of the following values:
|
||||||
- `hidden` <[boolean]> wait for element to not be found in the DOM or to be hidden. Defaults to `false`.
|
|
||||||
- `polling` <[string]|[number]> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it can be one of the following values:
|
|
||||||
- `raf` - to constantly execute `pageFunction` in `requestAnimationFrame` callback. This is the tightest polling mode which is suitable to observe styling changes.
|
- `raf` - to constantly execute `pageFunction` in `requestAnimationFrame` callback. This is the tightest polling mode which is suitable to observe styling changes.
|
||||||
- `mutation` - to execute `pageFunction` on every DOM mutation.
|
- `mutation` - to execute `pageFunction` on every DOM mutation.
|
||||||
|
- `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 [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
||||||
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
||||||
- returns: <[Promise]<[JSHandle]>> Promise which resolves to a JSHandle of the success value
|
- returns: <[Promise]<[JSHandle]>> Promise which resolves to a JSHandle of the success value
|
||||||
|
|
||||||
|
|
@ -1704,7 +1775,7 @@ return finalResponse.ok();
|
||||||
#### page.waitForSelector(selector[, options])
|
#### page.waitForSelector(selector[, options])
|
||||||
- `selector` <[string]> A selector of an element to wait for
|
- `selector` <[string]> A selector of an element to wait for
|
||||||
- `options` <[Object]>
|
- `options` <[Object]>
|
||||||
- `waitFor` <"visible"|"hidden"|"any"|"nowait"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`any`) or do not wait at all (`nowait`). Defaults to `visible`.
|
- `visibility` <"visible"|"hidden"|"any"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`any`). Defaults to `any`.
|
||||||
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
||||||
- returns: <[Promise]<?[ElementHandle]>> Promise which resolves when element specified by selector string is added to DOM. Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.
|
- returns: <[Promise]<?[ElementHandle]>> Promise which resolves when element specified by selector string is added to DOM. Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.
|
||||||
|
|
||||||
|
|
@ -1999,7 +2070,6 @@ Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownopt
|
||||||
- `relativePoint` <[Object]> Optional relative point
|
- `relativePoint` <[Object]> Optional relative point
|
||||||
- `x` <[number]> x coordinate
|
- `x` <[number]> x coordinate
|
||||||
- `y` <[number]> y coordinate
|
- `y` <[number]> y coordinate
|
||||||
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions) and [`mouse.up`](#mouseupoptions).
|
Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions) and [`mouse.up`](#mouseupoptions).
|
||||||
|
|
@ -2031,7 +2101,6 @@ Dispatches a `mousemove` event.
|
||||||
- `relativePoint` <[Object]> Optional relative point
|
- `relativePoint` <[Object]> Optional relative point
|
||||||
- `x` <[number]> x coordinate
|
- `x` <[number]> x coordinate
|
||||||
- `y` <[number]> y coordinate
|
- `y` <[number]> y coordinate
|
||||||
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
|
||||||
- returns: <[Promise]>
|
- returns: <[Promise]>
|
||||||
|
|
||||||
Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions) and [`mouse.up`](#mouseupoptions).
|
Shortcut for [`mouse.move`](#mousemovex-y-options), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions), [`mouse.up`](#mouseupoptions), [`mouse.down`](#mousedownoptions) and [`mouse.up`](#mouseupoptions).
|
||||||
|
|
@ -2080,7 +2149,7 @@ Dispatches a `mouseup` event.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
// Generates a PDF with 'screen' media type.
|
// Generates a PDF with 'screen' media type.
|
||||||
await page.emulateMedia({ type: 'screen' });
|
await page.emulateMedia({type: 'screen'});
|
||||||
await page.pdf.generate({path: 'page.pdf'});
|
await page.pdf.generate({path: 'page.pdf'});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -2569,6 +2638,11 @@ Returns frame's url.
|
||||||
#### frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
|
#### frame.waitFor(selectorOrFunctionOrTimeout[, options[, ...args]])
|
||||||
- `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
|
- `selectorOrFunctionOrTimeout` <[string]|[number]|[function]> A [selector], predicate or timeout to wait for
|
||||||
- `options` <[Object]> Optional waiting parameters
|
- `options` <[Object]> Optional waiting parameters
|
||||||
|
- `visibility` <"visible"|"hidden"|"any"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`any`). Defaults to `any`.
|
||||||
|
- `polling` <[number]|"raf"|"mutation"> An interval at which the `pageFunction` is executed, defaults to `raf`. If `polling` is a number, then it is treated as an interval in milliseconds at which the function would be executed. If `polling` is a string, then it can be one of the following values:
|
||||||
|
- `raf` - to constantly execute `pageFunction` in `requestAnimationFrame` callback. This is the tightest polling mode which is suitable to observe styling changes.
|
||||||
|
- `mutation` - to execute `pageFunction` on every DOM mutation.
|
||||||
|
- `timeout` <[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 [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
||||||
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
- `...args` <...[Serializable]|[JSHandle]> Arguments to pass to `pageFunction`
|
||||||
- returns: <[Promise]<[JSHandle]>> Promise which resolves to a JSHandle of the success value
|
- returns: <[Promise]<[JSHandle]>> Promise which resolves to a JSHandle of the success value
|
||||||
|
|
||||||
|
|
@ -2654,7 +2728,7 @@ const [response] = await Promise.all([
|
||||||
#### frame.waitForSelector(selector[, options])
|
#### frame.waitForSelector(selector[, options])
|
||||||
- `selector` <[string]> A selector of an element to wait for
|
- `selector` <[string]> A selector of an element to wait for
|
||||||
- `options` <[Object]>
|
- `options` <[Object]>
|
||||||
- `waitFor` <"visible"|"hidden"|"any"|"nowait"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`any`) or do not wait at all (`nowait`). Defaults to `visible`.
|
- `visibility` <"visible"|"hidden"|"any"> Wait for element to become visible (`visible`), hidden (`hidden`), present in dom (`any`). Defaults to `any`.
|
||||||
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
- `timeout` <[number]> Maximum navigation time in milliseconds, defaults to 30 seconds, pass `0` to disable timeout. The default value can be changed by using the [page.setDefaultTimeout(timeout)](#pagesetdefaulttimeouttimeout) method.
|
||||||
- returns: <[Promise]<?[ElementHandle]>> Promise which resolves when element specified by selector string is added to DOM. Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.
|
- returns: <[Promise]<?[ElementHandle]>> Promise which resolves when element specified by selector string is added to DOM. Resolves to `null` if waiting for `hidden: true` and selector is not found in DOM.
|
||||||
|
|
||||||
|
|
@ -3268,12 +3342,6 @@ Contains the URL of the response.
|
||||||
|
|
||||||
### class: ChromiumTarget
|
### class: ChromiumTarget
|
||||||
|
|
||||||
#### chromiumTarget.browser()
|
|
||||||
|
|
||||||
- returns: <[Browser]>
|
|
||||||
|
|
||||||
Get the browser the target belongs to.
|
|
||||||
|
|
||||||
#### chromiumTarget.browserContext()
|
#### chromiumTarget.browserContext()
|
||||||
|
|
||||||
- returns: <[BrowserContext]>
|
- returns: <[BrowserContext]>
|
||||||
|
|
|
||||||
|
|
@ -383,11 +383,9 @@ export class Frame {
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForSelector(selector: string, options?: types.TimeoutOptions & { waitFor?: types.Visibility }): Promise<dom.ElementHandle<Element> | null> {
|
async waitForSelector(selector: string, options?: types.TimeoutOptions & { visibility?: types.Visibility }): Promise<dom.ElementHandle<Element> | null> {
|
||||||
const { timeout = this._page._timeoutSettings.timeout(), waitFor = 'any' } = (options || {});
|
const { timeout = this._page._timeoutSettings.timeout(), visibility = 'any' } = (options || {});
|
||||||
if ((waitFor as any) === 'nowait')
|
const handle = await this._waitForSelectorInUtilityContext(selector, visibility, timeout);
|
||||||
throw new Error('waitForSelector does not support "nowait"');
|
|
||||||
const handle = await this._waitForSelectorInUtilityContext(selector, waitFor as types.Visibility, timeout);
|
|
||||||
const mainContext = await this._mainContext();
|
const mainContext = await this._mainContext();
|
||||||
if (handle && handle._context !== mainContext) {
|
if (handle && handle._context !== mainContext) {
|
||||||
const adopted = this._page._delegate.adoptElementHandle(handle, mainContext);
|
const adopted = this._page._delegate.adoptElementHandle(handle, mainContext);
|
||||||
|
|
@ -662,7 +660,7 @@ export class Frame {
|
||||||
await handle.dispose();
|
await handle.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: any = {}, ...args: any[]): Promise<js.JSHandle | null> {
|
async waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: types.WaitForFunctionOptions & { visibility?: types.Visibility } = {}, ...args: any[]): Promise<js.JSHandle | null> {
|
||||||
if (helper.isString(selectorOrFunctionOrTimeout))
|
if (helper.isString(selectorOrFunctionOrTimeout))
|
||||||
return this.waitForSelector(selectorOrFunctionOrTimeout as string, options) as any;
|
return this.waitForSelector(selectorOrFunctionOrTimeout as string, options) as any;
|
||||||
if (helper.isNumber(selectorOrFunctionOrTimeout))
|
if (helper.isNumber(selectorOrFunctionOrTimeout))
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ export class Page extends EventEmitter {
|
||||||
return this.mainFrame().$(selector);
|
return this.mainFrame().$(selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForSelector(selector: string, options?: types.TimeoutOptions & { waitFor?: types.Visibility }): Promise<dom.ElementHandle<Element> | null> {
|
async waitForSelector(selector: string, options?: types.TimeoutOptions & { visibility?: types.Visibility }): Promise<dom.ElementHandle<Element> | null> {
|
||||||
return this.mainFrame().waitForSelector(selector, options);
|
return this.mainFrame().waitForSelector(selector, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -445,7 +445,7 @@ export class Page extends EventEmitter {
|
||||||
return this.mainFrame().type(selector, text, options);
|
return this.mainFrame().type(selector, text, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options: { visible?: boolean; hidden?: boolean; timeout?: number; polling?: string | number; } = {}, ...args: any[]): Promise<js.JSHandle> {
|
async waitFor(selectorOrFunctionOrTimeout: (string | number | Function), options?: types.WaitForFunctionOptions & { visibility?: types.Visibility }, ...args: any[]): Promise<js.JSHandle> {
|
||||||
return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
|
return this.mainFrame().waitFor(selectorOrFunctionOrTimeout, options, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,11 @@ type PageFunction<Args extends any[], R = any> = string | ((...args: Args) => R
|
||||||
type PageFunctionOn<On, Args extends any[], R = any> = string | ((on: On, ...args: Args) => R | Promise<R>);
|
type PageFunctionOn<On, Args extends any[], R = any> = string | ((on: On, ...args: Args) => R | Promise<R>);
|
||||||
|
|
||||||
type Handle<T> = T extends Node ? dom.ElementHandle<T> : js.JSHandle<T>;
|
type Handle<T> = T extends Node ? dom.ElementHandle<T> : js.JSHandle<T>;
|
||||||
type ElementForSelector<T> = T extends keyof HTMLElementTagNameMap ? HTMLElementTagNameMap[T] : Element;
|
|
||||||
|
|
||||||
export type Evaluate = <Args extends any[], R>(pageFunction: PageFunction<Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
export type Evaluate = <Args extends any[], R>(pageFunction: PageFunction<Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
||||||
export type EvaluateHandle = <Args extends any[], R>(pageFunction: PageFunction<Args, R>, ...args: Boxed<Args>) => Promise<Handle<R>>;
|
export type EvaluateHandle = <Args extends any[], R>(pageFunction: PageFunction<Args, R>, ...args: Boxed<Args>) => Promise<Handle<R>>;
|
||||||
export type $Eval = <Args extends any[], R, S extends string>(selector: S, pageFunction: PageFunctionOn<ElementForSelector<S>, Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
export type $Eval = <Args extends any[], R>(selector: string, pageFunction: PageFunctionOn<Element, Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
||||||
export type $$Eval = <Args extends any[], R, S extends string>(selector: S, pageFunction: PageFunctionOn<ElementForSelector<S>[], Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
export type $$Eval = <Args extends any[], R>(selector: string, pageFunction: PageFunctionOn<Element[], Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
||||||
export type EvaluateOn<T> = <Args extends any[], R>(pageFunction: PageFunctionOn<T, Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
export type EvaluateOn<T> = <Args extends any[], R>(pageFunction: PageFunctionOn<T, Args, R>, ...args: Boxed<Args>) => Promise<R>;
|
||||||
export type EvaluateHandleOn<T> = <Args extends any[], R>(pageFunction: PageFunctionOn<T, Args, R>, ...args: Boxed<Args>) => Promise<Handle<R>>;
|
export type EvaluateHandleOn<T> = <Args extends any[], R>(pageFunction: PageFunctionOn<T, Args, R>, ...args: Boxed<Args>) => Promise<Handle<R>>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -331,7 +331,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
});
|
});
|
||||||
it('should wait for visible recursively', async({page, server}) => {
|
it('should wait for visible recursively', async({page, server}) => {
|
||||||
let divVisible = false;
|
let divVisible = false;
|
||||||
const waitForSelector = page.waitForSelector('div#inner', { waitFor: 'visible' }).then(() => divVisible = true);
|
const waitForSelector = page.waitForSelector('div#inner', { visibility: 'visible' }).then(() => divVisible = true);
|
||||||
await page.setContent(`<div style='display: none; visibility: hidden;'><div id="inner">hi</div></div>`);
|
await page.setContent(`<div style='display: none; visibility: hidden;'><div id="inner">hi</div></div>`);
|
||||||
expect(divVisible).toBe(false);
|
expect(divVisible).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('div').style.removeProperty('display'));
|
await page.evaluate(() => document.querySelector('div').style.removeProperty('display'));
|
||||||
|
|
@ -343,7 +343,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
it('hidden should wait for visibility: hidden', async({page, server}) => {
|
it('hidden should wait for visibility: hidden', async({page, server}) => {
|
||||||
let divHidden = false;
|
let divHidden = false;
|
||||||
await page.setContent(`<div style='display: block;'></div>`);
|
await page.setContent(`<div style='display: block;'></div>`);
|
||||||
const waitForSelector = page.waitForSelector('div', { waitFor: 'hidden' }).then(() => divHidden = true);
|
const waitForSelector = page.waitForSelector('div', { visibility: 'hidden' }).then(() => divHidden = true);
|
||||||
await page.waitForSelector('div'); // do a round trip
|
await page.waitForSelector('div'); // do a round trip
|
||||||
expect(divHidden).toBe(false);
|
expect(divHidden).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('div').style.setProperty('visibility', 'hidden'));
|
await page.evaluate(() => document.querySelector('div').style.setProperty('visibility', 'hidden'));
|
||||||
|
|
@ -353,7 +353,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
it('hidden should wait for display: none', async({page, server}) => {
|
it('hidden should wait for display: none', async({page, server}) => {
|
||||||
let divHidden = false;
|
let divHidden = false;
|
||||||
await page.setContent(`<div style='display: block;'></div>`);
|
await page.setContent(`<div style='display: block;'></div>`);
|
||||||
const waitForSelector = page.waitForSelector('div', { waitFor: 'hidden' }).then(() => divHidden = true);
|
const waitForSelector = page.waitForSelector('div', { visibility: 'hidden' }).then(() => divHidden = true);
|
||||||
await page.waitForSelector('div'); // do a round trip
|
await page.waitForSelector('div'); // do a round trip
|
||||||
expect(divHidden).toBe(false);
|
expect(divHidden).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('div').style.setProperty('display', 'none'));
|
await page.evaluate(() => document.querySelector('div').style.setProperty('display', 'none'));
|
||||||
|
|
@ -363,7 +363,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
it('hidden should wait for removal', async({page, server}) => {
|
it('hidden should wait for removal', async({page, server}) => {
|
||||||
await page.setContent(`<div></div>`);
|
await page.setContent(`<div></div>`);
|
||||||
let divRemoved = false;
|
let divRemoved = false;
|
||||||
const waitForSelector = page.waitForSelector('div', { waitFor: 'hidden' }).then(() => divRemoved = true);
|
const waitForSelector = page.waitForSelector('div', { visibility: 'hidden' }).then(() => divRemoved = true);
|
||||||
await page.waitForSelector('div'); // do a round trip
|
await page.waitForSelector('div'); // do a round trip
|
||||||
expect(divRemoved).toBe(false);
|
expect(divRemoved).toBe(false);
|
||||||
await page.evaluate(() => document.querySelector('div').remove());
|
await page.evaluate(() => document.querySelector('div').remove());
|
||||||
|
|
@ -371,7 +371,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
expect(divRemoved).toBe(true);
|
expect(divRemoved).toBe(true);
|
||||||
});
|
});
|
||||||
it('should return null if waiting to hide non-existing element', async({page, server}) => {
|
it('should return null if waiting to hide non-existing element', async({page, server}) => {
|
||||||
const handle = await page.waitForSelector('non-existing', { waitFor: 'hidden' });
|
const handle = await page.waitForSelector('non-existing', { visibility: 'hidden' });
|
||||||
expect(handle).toBe(null);
|
expect(handle).toBe(null);
|
||||||
});
|
});
|
||||||
it('should respect timeout', async({page, server}) => {
|
it('should respect timeout', async({page, server}) => {
|
||||||
|
|
@ -384,7 +384,7 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
it('should have an error message specifically for awaiting an element to be hidden', async({page, server}) => {
|
it('should have an error message specifically for awaiting an element to be hidden', async({page, server}) => {
|
||||||
await page.setContent(`<div></div>`);
|
await page.setContent(`<div></div>`);
|
||||||
let error = null;
|
let error = null;
|
||||||
await page.waitForSelector('div', { waitFor: 'hidden', timeout: 10 }).catch(e => error = e);
|
await page.waitForSelector('div', { visibility: 'hidden', timeout: 10 }).catch(e => error = e);
|
||||||
expect(error).toBeTruthy();
|
expect(error).toBeTruthy();
|
||||||
expect(error.message).toContain('waiting for selector "[hidden] div" failed: timeout');
|
expect(error.message).toContain('waiting for selector "[hidden] div" failed: timeout');
|
||||||
});
|
});
|
||||||
|
|
@ -407,33 +407,24 @@ module.exports.describe = function({testRunner, expect, product, playwright, FFO
|
||||||
await page.waitForSelector('.zombo', { timeout: 10 }).catch(e => error = e);
|
await page.waitForSelector('.zombo', { timeout: 10 }).catch(e => error = e);
|
||||||
expect(error.stack).toContain('waittask.spec.js');
|
expect(error.stack).toContain('waittask.spec.js');
|
||||||
});
|
});
|
||||||
it('should throw for waitFor nowait', async({page, server}) => {
|
|
||||||
let error;
|
|
||||||
try {
|
|
||||||
await page.waitForSelector('non-existing-element', { waitFor: 'nowait' });
|
|
||||||
} catch (e) {
|
|
||||||
error = e;
|
|
||||||
}
|
|
||||||
expect(error.message).toBe('waitForSelector does not support "nowait"');
|
|
||||||
});
|
|
||||||
it('should throw for unknown waitFor option', async({page, server}) => {
|
it('should throw for unknown waitFor option', async({page, server}) => {
|
||||||
await page.setContent('<section>test</section>');
|
await page.setContent('<section>test</section>');
|
||||||
const error = await page.waitForSelector('section', { waitFor: 'foo' }).catch(e => e);
|
const error = await page.waitForSelector('section', { visibility: 'foo' }).catch(e => e);
|
||||||
expect(error.message).toContain('Unsupported waitFor option');
|
expect(error.message).toContain('Unsupported waitFor option');
|
||||||
});
|
});
|
||||||
it('should throw for numeric waitFor option', async({page, server}) => {
|
it('should throw for numeric waitFor option', async({page, server}) => {
|
||||||
await page.setContent('<section>test</section>');
|
await page.setContent('<section>test</section>');
|
||||||
const error = await page.waitForSelector('section', { waitFor: 123 }).catch(e => e);
|
const error = await page.waitForSelector('section', { visibility: 123 }).catch(e => e);
|
||||||
expect(error.message).toContain('Unsupported waitFor option');
|
expect(error.message).toContain('Unsupported waitFor option');
|
||||||
});
|
});
|
||||||
it('should throw for true waitFor option', async({page, server}) => {
|
it('should throw for true waitFor option', async({page, server}) => {
|
||||||
await page.setContent('<section>test</section>');
|
await page.setContent('<section>test</section>');
|
||||||
const error = await page.waitForSelector('section', { waitFor: true }).catch(e => e);
|
const error = await page.waitForSelector('section', { visibility: true }).catch(e => e);
|
||||||
expect(error.message).toContain('Unsupported waitFor option');
|
expect(error.message).toContain('Unsupported waitFor option');
|
||||||
});
|
});
|
||||||
it('should throw for false waitFor option', async({page, server}) => {
|
it('should throw for false waitFor option', async({page, server}) => {
|
||||||
await page.setContent('<section>test</section>');
|
await page.setContent('<section>test</section>');
|
||||||
const error = await page.waitForSelector('section', { waitFor: false }).catch(e => e);
|
const error = await page.waitForSelector('section', { visibility: false }).catch(e => e);
|
||||||
expect(error.message).toContain('Unsupported waitFor option');
|
expect(error.message).toContain('Unsupported waitFor option');
|
||||||
});
|
});
|
||||||
it('should support >> selector syntax', async({page, server}) => {
|
it('should support >> selector syntax', async({page, server}) => {
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,50 @@ Documentation.Class = class {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validateOrder(errors) {
|
||||||
|
const members = this.membersArray;
|
||||||
|
// Events should go first.
|
||||||
|
let eventIndex = 0;
|
||||||
|
for (; eventIndex < members.length && members[eventIndex].kind === 'event'; ++eventIndex);
|
||||||
|
for (; eventIndex < members.length && members[eventIndex].kind !== 'event'; ++eventIndex);
|
||||||
|
if (eventIndex < members.length)
|
||||||
|
errors.push(`Events should go first. Event '${members[eventIndex].name}' in class ${cls.name} breaks order`);
|
||||||
|
|
||||||
|
// Constructor should be right after events and before all other members.
|
||||||
|
const constructorIndex = members.findIndex(member => member.kind === 'method' && member.name === 'constructor');
|
||||||
|
if (constructorIndex > 0 && members[constructorIndex - 1].kind !== 'event')
|
||||||
|
errors.push(`Constructor of ${cls.name} should go before other methods`);
|
||||||
|
|
||||||
|
// Events should be sorted alphabetically.
|
||||||
|
for (let i = 0; i < members.length - 1; ++i) {
|
||||||
|
const member1 = this.membersArray[i];
|
||||||
|
const member2 = this.membersArray[i + 1];
|
||||||
|
if (member1.kind !== 'event' || member2.kind !== 'event')
|
||||||
|
continue;
|
||||||
|
if (member1.name > member2.name)
|
||||||
|
errors.push(`Event '${member1.name}' in class ${this.name} breaks alphabetic ordering of events`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// All other members should be sorted alphabetically.
|
||||||
|
for (let i = 0; i < members.length - 1; ++i) {
|
||||||
|
const member1 = this.membersArray[i];
|
||||||
|
const member2 = this.membersArray[i + 1];
|
||||||
|
if (member1.kind === 'event' || member2.kind === 'event')
|
||||||
|
continue;
|
||||||
|
if (member1.kind === 'method' && member1.name === 'constructor')
|
||||||
|
continue;
|
||||||
|
if (member1.name > member2.name) {
|
||||||
|
let memberName1 = `${this.name}.${member1.name}`;
|
||||||
|
if (member1.kind === 'method')
|
||||||
|
memberName1 += '()';
|
||||||
|
let memberName2 = `${this.name}.${member2.name}`;
|
||||||
|
if (member2.kind === 'method')
|
||||||
|
memberName2 += '()';
|
||||||
|
errors.push(`Bad alphabetic ordering of ${this.name} members: ${memberName1} should go after ${memberName2}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Documentation.Member = class {
|
Documentation.Member = class {
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,8 @@ module.exports = async function(page, sources) {
|
||||||
|
|
||||||
// Push base class documentation to derived classes.
|
// Push base class documentation to derived classes.
|
||||||
for (const [name, clazz] of documentation.classes.entries()) {
|
for (const [name, clazz] of documentation.classes.entries()) {
|
||||||
|
clazz.validateOrder(errors);
|
||||||
|
|
||||||
if (!clazz.extends || clazz.extends === 'EventEmitter' || clazz.extends === 'Error')
|
if (!clazz.extends || clazz.extends === 'EventEmitter' || clazz.extends === 'Error')
|
||||||
continue;
|
continue;
|
||||||
const superClass = documentation.classes.get(clazz.extends);
|
const superClass = documentation.classes.get(clazz.extends);
|
||||||
|
|
@ -311,6 +313,7 @@ module.exports = async function(page, sources) {
|
||||||
if (superClass.members.has(memberName))
|
if (superClass.members.has(memberName))
|
||||||
errors.push(`Member documentation overrides base: ${name}.${memberName} over ${clazz.extends}.${memberName}`);
|
errors.push(`Member documentation overrides base: ${name}.${memberName} over ${clazz.extends}.${memberName}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
clazz.membersArray = [...clazz.membersArray, ...superClass.membersArray];
|
clazz.membersArray = [...clazz.membersArray, ...superClass.membersArray];
|
||||||
clazz.index();
|
clazz.index();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,6 @@ module.exports = async function lint(page, mdSources, jsSources) {
|
||||||
const mdErrors = mdResult.errors;
|
const mdErrors = mdResult.errors;
|
||||||
mdErrors.push(...compareDocumentations(mdDocumentation, jsDocumentation));
|
mdErrors.push(...compareDocumentations(mdDocumentation, jsDocumentation));
|
||||||
mdErrors.push(...checkDuplicates(mdDocumentation));
|
mdErrors.push(...checkDuplicates(mdDocumentation));
|
||||||
mdErrors.push(...checkSorting(mdDocumentation));
|
|
||||||
|
|
||||||
// Push all errors with proper prefixes
|
// Push all errors with proper prefixes
|
||||||
const errors = jsErrors.map(error => '[JavaScript] ' + error);
|
const errors = jsErrors.map(error => '[JavaScript] ' + error);
|
||||||
|
|
@ -53,59 +52,6 @@ module.exports = async function lint(page, mdSources, jsSources) {
|
||||||
return errors.map(error => Message.error(error));
|
return errors.map(error => Message.error(error));
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {!Documentation} doc
|
|
||||||
* @return {!Array<string>}
|
|
||||||
*/
|
|
||||||
function checkSorting(doc) {
|
|
||||||
const errors = [];
|
|
||||||
for (const cls of doc.classesArray) {
|
|
||||||
const members = cls.membersArray;
|
|
||||||
|
|
||||||
// Events should go first.
|
|
||||||
let eventIndex = 0;
|
|
||||||
for (; eventIndex < members.length && members[eventIndex].kind === 'event'; ++eventIndex);
|
|
||||||
for (; eventIndex < members.length && members[eventIndex].kind !== 'event'; ++eventIndex);
|
|
||||||
if (eventIndex < members.length)
|
|
||||||
errors.push(`Events should go first. Event '${members[eventIndex].name}' in class ${cls.name} breaks order`);
|
|
||||||
|
|
||||||
// Constructor should be right after events and before all other members.
|
|
||||||
const constructorIndex = members.findIndex(member => member.kind === 'method' && member.name === 'constructor');
|
|
||||||
if (constructorIndex > 0 && members[constructorIndex - 1].kind !== 'event')
|
|
||||||
errors.push(`Constructor of ${cls.name} should go before other methods`);
|
|
||||||
|
|
||||||
// Events should be sorted alphabetically.
|
|
||||||
for (let i = 0; i < members.length - 1; ++i) {
|
|
||||||
const member1 = cls.membersArray[i];
|
|
||||||
const member2 = cls.membersArray[i + 1];
|
|
||||||
if (member1.kind !== 'event' || member2.kind !== 'event')
|
|
||||||
continue;
|
|
||||||
if (member1.name > member2.name)
|
|
||||||
errors.push(`Event '${member1.name}' in class ${cls.name} breaks alphabetic ordering of events`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// All other members should be sorted alphabetically.
|
|
||||||
for (let i = 0; i < members.length - 1; ++i) {
|
|
||||||
const member1 = cls.membersArray[i];
|
|
||||||
const member2 = cls.membersArray[i + 1];
|
|
||||||
if (member1.kind === 'event' || member2.kind === 'event')
|
|
||||||
continue;
|
|
||||||
if (member1.kind === 'method' && member1.name === 'constructor')
|
|
||||||
continue;
|
|
||||||
if (member1.name > member2.name) {
|
|
||||||
let memberName1 = `${cls.name}.${member1.name}`;
|
|
||||||
if (member1.kind === 'method')
|
|
||||||
memberName1 += '()';
|
|
||||||
let memberName2 = `${cls.name}.${member2.name}`;
|
|
||||||
if (member2.kind === 'method')
|
|
||||||
memberName2 += '()';
|
|
||||||
errors.push(`Bad alphabetic ordering of ${cls.name} members: ${memberName1} should go after ${memberName2}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {!Array<!Source>} jsSources
|
* @param {!Array<!Source>} jsSources
|
||||||
* @param {!Documentation} jsDocumentation
|
* @param {!Documentation} jsDocumentation
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue