docs: generate api.md (#4576)

This commit is contained in:
Pavel Feldman 2020-12-02 13:50:10 -08:00 committed by GitHub
parent f5c8e1d344
commit 1fa7e86ea9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 5177 additions and 40 deletions

4786
docs-src/api-body.md Normal file

File diff suppressed because it is too large Load diff

209
docs-src/api-footer.md Normal file
View file

@ -0,0 +1,209 @@
### EvaluationArgument
Playwright evaluation methods like [page.evaluate(pageFunction[, arg])](#pageevaluatepagefunction-arg) take a single optional argument. This argument can be a mix of [Serializable] values and [JSHandle] or [ElementHandle] instances. Handles are automatically converted to the value they represent.
See examples for various scenarios:
```js
// A primitive value.
await page.evaluate(num => num, 42);
// An array.
await page.evaluate(array => array.length, [1, 2, 3]);
// An object.
await page.evaluate(object => object.foo, { foo: 'bar' });
// A single handle.
const button = await page.$('button');
await page.evaluate(button => button.textContent, button);
// Alternative notation using elementHandle.evaluate.
await button.evaluate((button, from) => button.textContent.substring(from), 5);
// Object with multiple handles.
const button1 = await page.$('.button1');
const button2 = await page.$('.button2');
await page.evaluate(
o => o.button1.textContent + o.button2.textContent,
{ button1, button2 });
// Obejct destructuring works. Note that property names must match
// between the destructured object and the argument.
// Also note the required parenthesis.
await page.evaluate(
({ button1, button2 }) => button1.textContent + button2.textContent,
{ button1, button2 });
// Array works as well. Arbitrary names can be used for destructuring.
// Note the required parenthesis.
await page.evaluate(
([b1, b2]) => b1.textContent + b2.textContent,
[button1, button2]);
// Any non-cyclic mix of serializables and handles works.
await page.evaluate(
x => x.button1.textContent + x.list[0].textContent + String(x.foo),
{ button1, list: [button2], foo: null });
```
### Environment Variables
> **NOTE** [playwright-core](https://www.npmjs.com/package/playwright-core) **does not** respect environment variables.
Playwright looks for certain [environment variables](https://en.wikipedia.org/wiki/Environment_variable) to aid its operations.
If Playwright doesn't find them in the environment, a lowercased variant of these variables will be used from the [npm config](https://docs.npmjs.com/cli/config).
- `PLAYWRIGHT_DOWNLOAD_HOST` - overwrite URL prefix that is used to download browsers. Note: this includes protocol and might even include path prefix. By default, Playwright uses `https://storage.googleapis.com` to download Chromium and `https://playwright.azureedge.net` to download Webkit & Firefox. You can also use browser-specific download hosts that superceed the `PLAYWRIGHT_DOWNLOAD_HOST` variable:
- `PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST` - host to specify Chromium downloads
- `PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST` - host to specify Firefox downloads
- `PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST` - host to specify Webkit downloads
- `PLAYWRIGHT_BROWSERS_PATH` - specify a shared directory that playwright will use to download browsers and to look for browsers when launching browser instances.
- `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` - set to non-empty value to skip browser downloads altogether.
```sh
# Linux/macOS
# Install browsers to the shared location.
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/playwright-browsers npm install --save-dev playwright
# Use shared location to find browsers.
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/playwright-browsers node playwright-script.js
# Windows
# Install browsers to the shared location.
$ set PLAYWRIGHT_BROWSERS_PATH=%USERPROFILE%\playwright-browsers
$ npm install --save-dev playwright
# Use shared location to find browsers.
$ set PLAYWRIGHT_BROWSERS_PATH=%USERPROFILE%\playwright-browsers
$ node playwright-script.js
```
### Working with selectors
Selector describes an element in the page. It can be used to obtain `ElementHandle` (see [page.$()](#pageselector) for example) or shortcut element operations to avoid intermediate handle (see [page.click()](#pageclickselector-options) for example).
Selector has the following format: `engine=body [>> engine=body]*`. Here `engine` is one of the supported [selector engines](selectors.md) (e.g. `css` or `xpath`), and `body` is a selector body in the format of the particular engine. When multiple `engine=body` clauses are present (separated by `>>`), next one is queried relative to the previous one's result.
For convenience, selectors in the wrong format are heuristically converted to the right format:
- selector starting with `//` or `..` is assumed to be `xpath=selector`;
- selector starting and ending with a quote (either `"` or `'`) is assumed to be `text=selector`;
- otherwise selector is assumed to be `css=selector`.
```js
// queries 'div' css selector
const handle = await page.$('css=div');
// queries '//html/body/div' xpath selector
const handle = await page.$('xpath=//html/body/div');
// queries '"foo"' text selector
const handle = await page.$('text="foo"');
// queries 'span' css selector inside the result of '//html/body/div' xpath selector
const handle = await page.$('xpath=//html/body/div >> css=span');
// converted to 'css=div'
const handle = await page.$('div');
// converted to 'xpath=//html/body/div'
const handle = await page.$('//html/body/div');
// converted to 'text="foo"'
const handle = await page.$('"foo"');
// queries '../span' xpath selector starting with the result of 'div' css selector
const handle = await page.$('div >> ../span');
// queries 'span' css selector inside the div handle
const handle = await divHandle.$('css=span');
```
### Working with Chrome Extensions
Playwright can be used for testing Chrome Extensions.
> **NOTE** Extensions in Chrome / Chromium currently only work in non-headless mode.
The following is code for getting a handle to the [background page](https://developer.chrome.com/extensions/background_pages) of an extension whose source is located in `./my-extension`:
```js
const { chromium } = require('playwright');
(async () => {
const pathToExtension = require('path').join(__dirname, 'my-extension');
const userDataDir = '/tmp/test-user-data-dir';
const browserContext = await chromium.launchPersistentContext(userDataDir,{
headless: false,
args: [
`--disable-extensions-except=${pathToExtension}`,
`--load-extension=${pathToExtension}`
]
});
const backgroundPage = browserContext.backgroundPages()[0];
// Test the background page as you would any other page.
await browserContext.close();
})();
```
> **NOTE** It is not yet possible to test extension popups or content scripts.
[AXNode]: #accessibilitysnapshotoptions "AXNode"
[Accessibility]: #class-accessibility "Accessibility"
[Array]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array "Array"
[Body]: #class-body "Body"
[BrowserServer]: #class-browserserver "BrowserServer"
[BrowserContext]: #class-browsercontext "BrowserContext"
[BrowserType]: #class-browsertype "BrowserType"
[Browser]: #class-browser "Browser"
[Buffer]: https://nodejs.org/api/buffer.html#buffer_class_buffer "Buffer"
[ChildProcess]: https://nodejs.org/api/child_process.html "ChildProcess"
[ChromiumBrowser]: #class-chromiumbrowser "ChromiumBrowser"
[ChromiumBrowserContext]: #class-chromiumbrowsercontext "ChromiumBrowserContext"
[ChromiumCoverage]: #class-chromiumcoverage "ChromiumCoverage"
[CDPSession]: #class-cdpsession "CDPSession"
[ConsoleMessage]: #class-consolemessage "ConsoleMessage"
[Dialog]: #class-dialog "Dialog"
[Download]: #class-download "Download"
[ElementHandle]: #class-elementhandle "ElementHandle"
[Element]: https://developer.mozilla.org/en-US/docs/Web/API/element "Element"
[Error]: https://nodejs.org/api/errors.html#errors_class_error "Error"
[EvaluationArgument]: #evaluationargument "Evaluation Argument"
[File]: #class-file "https://developer.mozilla.org/en-US/docs/Web/API/File"
[FileChooser]: #class-filechooser "FileChooser"
[FirefoxBrowser]: #class-firefoxbrowser "FirefoxBrowser"
[Frame]: #class-frame "Frame"
[JSHandle]: #class-jshandle "JSHandle"
[Keyboard]: #class-keyboard "Keyboard"
[Logger]: #class-logger "Logger"
[Map]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map "Map"
[Mouse]: #class-mouse "Mouse"
[Object]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object "Object"
[Page]: #class-page "Page"
[Playwright]: #class-playwright "Playwright"
[Promise]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise "Promise"
[RegExp]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
[Request]: #class-request "Request"
[Response]: #class-response "Response"
[Route]: #class-route "Route"
[Selectors]: #class-selectors "Selectors"
[Serializable]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Description "Serializable"
[TimeoutError]: #class-timeouterror "TimeoutError"
[Touchscreen]: #class-touchscreen "Touchscreen"
[UIEvent.detail]: https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail "UIEvent.detail"
[URL]: https://nodejs.org/api/url.html
[USKeyboardLayout]: ../src/usKeyboardLayout.ts "USKeyboardLayout"
[UnixTime]: https://en.wikipedia.org/wiki/Unix_time "Unix Time"
[Video]: #class-video "Video"
[WebKitBrowser]: #class-webkitbrowser "WebKitBrowser"
[WebSocket]: #class-websocket "WebSocket"
[Worker]: #class-worker "Worker"
[boolean]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type "Boolean"
[function]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function "Function"
[iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols "Iterator"
[null]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
[number]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type "Number"
[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin "Origin"
[selector]: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors "selector"
[Readable]: https://nodejs.org/api/stream.html#stream_class_stream_readable "Readable"
[string]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type "String"
[xpath]: https://developer.mozilla.org/en-US/docs/Web/XPath "xpath"

133
docs-src/api-header.md Normal file
View file

@ -0,0 +1,133 @@
# Playwright API <!-- GEN:version -->Tip-Of-Tree<!-- GEN:stop-->
##### Table of Contents
<!-- GEN:toc-top-level -->
- [Playwright module](#playwright-module)
- [class: Browser](#class-browser)
- [class: BrowserContext](#class-browsercontext)
- [class: Page](#class-page)
- [class: Frame](#class-frame)
- [class: ElementHandle](#class-elementhandle)
- [class: JSHandle](#class-jshandle)
- [class: ConsoleMessage](#class-consolemessage)
- [class: Dialog](#class-dialog)
- [class: Download](#class-download)
- [class: Video](#class-video)
- [class: FileChooser](#class-filechooser)
- [class: Keyboard](#class-keyboard)
- [class: Mouse](#class-mouse)
- [class: Touchscreen](#class-touchscreen)
- [class: Request](#class-request)
- [class: Response](#class-response)
- [class: Selectors](#class-selectors)
- [class: Route](#class-route)
- [class: WebSocket](#class-websocket)
- [class: TimeoutError](#class-timeouterror)
- [class: Accessibility](#class-accessibility)
- [class: Worker](#class-worker)
- [class: BrowserServer](#class-browserserver)
- [class: BrowserType](#class-browsertype)
- [class: Logger](#class-logger)
- [class: ChromiumBrowser](#class-chromiumbrowser)
- [class: ChromiumBrowserContext](#class-chromiumbrowsercontext)
- [class: ChromiumCoverage](#class-chromiumcoverage)
- [class: CDPSession](#class-cdpsession)
- [class: FirefoxBrowser](#class-firefoxbrowser)
- [class: WebKitBrowser](#class-webkitbrowser)
- [EvaluationArgument](#evaluationargument)
- [Environment Variables](#environment-variables)
- [Working with selectors](#working-with-selectors)
- [Working with Chrome Extensions](#working-with-chrome-extensions)
<!-- GEN:stop -->
### Playwright module
Playwright module provides a method to launch a browser instance.
The following is a typical example of using Playwright to drive automation:
```js
const { chromium, firefox, webkit } = require('playwright');
(async () => {
const browser = await chromium.launch(); // Or 'firefox' or 'webkit'.
const page = await browser.newPage();
await page.goto('http://example.com');
// other actions...
await browser.close();
})();
```
By default, the `playwright` NPM package automatically downloads browser executables during installation. The `playwright-core` NPM package can be used to skip automatic downloads.
<!-- GEN:toc -->
- [playwright.chromium](#playwrightchromium)
- [playwright.devices](#playwrightdevices)
- [playwright.errors](#playwrighterrors)
- [playwright.firefox](#playwrightfirefox)
- [playwright.selectors](#playwrightselectors)
- [playwright.webkit](#playwrightwebkit)
<!-- GEN:stop -->
#### playwright.chromium
- returns: <[BrowserType]>
This object can be used to launch or connect to Chromium, returning instances of [ChromiumBrowser].
#### playwright.devices
- returns: <[Object]>
Returns a list of devices to be used with [`browser.newContext([options])`](#browsernewcontextoptions) or [`browser.newPage([options])`](#browsernewpageoptions). Actual list of devices can be found in [src/server/deviceDescriptors.ts](https://github.com/Microsoft/playwright/blob/master/src/server/deviceDescriptors.ts).
```js
const { webkit, devices } = require('playwright');
const iPhone = devices['iPhone 6'];
(async () => {
const browser = await webkit.launch();
const context = await browser.newContext({
...iPhone
});
const page = await context.newPage();
await page.goto('http://example.com');
// other actions...
await browser.close();
})();
```
#### playwright.errors
- returns: <[Object]>
- `TimeoutError` <[function]> A class of [TimeoutError].
Playwright methods might throw errors if they are unable to fulfill a request. For example, [page.waitForSelector(selector[, options])](#pagewaitforselectorselector-options)
might fail if the selector doesn't match any nodes during the given timeframe.
For certain types of errors Playwright uses specific error classes.
These classes are available via [`playwright.errors`](#playwrighterrors).
An example of handling a timeout error:
```js
try {
await page.waitForSelector('.foo');
} catch (e) {
if (e instanceof playwright.errors.TimeoutError) {
// Do something if this is a timeout.
}
}
```
#### playwright.firefox
- returns: <[BrowserType]>
This object can be used to launch or connect to Firefox, returning instances of [FirefoxBrowser].
#### playwright.selectors
- returns: <[Selectors]>
Selectors can be used to install custom selector engines. See [Working with selectors](#working-with-selectors) for more information.
#### playwright.webkit
- returns: <[BrowserType]>
This object can be used to launch or connect to WebKit, returning instances of [WebKitBrowser].

View file

@ -1,3 +1,4 @@
<!-- THIS FILE IS NOW GENERATED -->
# Playwright API <!-- GEN:version -->Tip-Of-Tree<!-- GEN:stop-->
@ -1581,11 +1582,11 @@ Navigate to the next page in history.
- returns: <[Promise]<[null]|[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.
`page.goto` will throw an error if:
- there's an SSL error (e.g. in case of self-signed certificates).
- target URL is invalid.
- the `timeout` is exceeded during navigation.
- the remote server does not respond or is unreachable.
- the main resource failed to load.
* there's an SSL error (e.g. in case of self-signed certificates).
* target URL is invalid.
* the `timeout` is exceeded during navigation.
* the remote server does not respond or is unreachable.
* the main resource failed to load.
`page.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling [response.status()](#responsestatus).
@ -1697,28 +1698,28 @@ await page.pdf({path: 'page.pdf'});
The `width`, `height`, and `margin` options accept values labeled with units. Unlabeled values are treated as pixels.
A few examples:
- `page.pdf({width: 100})` - prints with width set to 100 pixels
- `page.pdf({width: '100px'})` - prints with width set to 100 pixels
- `page.pdf({width: '10cm'})` - prints with width set to 10 centimeters.
* `page.pdf({width: 100})` - prints with width set to 100 pixels
* `page.pdf({width: '100px'})` - prints with width set to 100 pixels
* `page.pdf({width: '10cm'})` - prints with width set to 10 centimeters.
All possible units are:
- `px` - pixel
- `in` - inch
- `cm` - centimeter
- `mm` - millimeter
* `px` - pixel
* `in` - inch
* `cm` - centimeter
* `mm` - millimeter
The `format` options are:
- `Letter`: 8.5in x 11in
- `Legal`: 8.5in x 14in
- `Tabloid`: 11in x 17in
- `Ledger`: 17in x 11in
- `A0`: 33.1in x 46.8in
- `A1`: 23.4in x 33.1in
- `A2`: 16.54in x 23.4in
- `A3`: 11.7in x 16.54in
- `A4`: 8.27in x 11.7in
- `A5`: 5.83in x 8.27in
- `A6`: 4.13in x 5.83in
* `Letter`: 8.5in x 11in
* `Legal`: 8.5in x 14in
* `Tabloid`: 11in x 17in
* `Ledger`: 17in x 11in
* `A0`: 33.1in x 46.8in
* `A1`: 23.4in x 33.1in
* `A2`: 16.54in x 23.4in
* `A3`: 11.7in x 16.54in
* `A4`: 8.27in x 11.7in
* `A5`: 5.83in x 8.27in
* `A6`: 4.13in x 5.83in
> **NOTE** `headerTemplate` and `footerTemplate` markup have the following limitations:
> 1. Script tags inside templates are not evaluated.
@ -2566,11 +2567,11 @@ Returns element attribute value.
- returns: <[Promise]<[null]|[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.
`frame.goto` will throw an error if:
- there's an SSL error (e.g. in case of self-signed certificates).
- target URL is invalid.
- the `timeout` is exceeded during navigation.
- the remote server does not respond or is unreachable.
- the main resource failed to load.
* there's an SSL error (e.g. in case of self-signed certificates).
* target URL is invalid.
* the `timeout` is exceeded during navigation.
* the remote server does not respond or is unreachable.
* the main resource failed to load.
`frame.goto` will not throw an error when any valid HTTP status code is returned by the remote server, including 404 "Not Found" and 500 "Internal Server Error". The status code for such responses can be retrieved by calling [response.status()](#responsestatus).
@ -3346,11 +3347,11 @@ When all steps combined have not finished during the specified `timeout`, this m
- returns: <[Promise]> Promise that resolves when the element satisfies the `state`.
Depending on the `state` parameter, this method waits for one of the [actionability](./actionability.md) checks to pass. This method throws when the element is detached while waiting, unless waiting for the `"hidden"` state.
- `"visible"` Wait until the element is [visible](./actionability.md#visible).
- `"hidden"` Wait until the element is [not visible](./actionability.md#visible) or [not attached](./actionability.md#attached). Note that waiting for hidden does not throw when the element detaches.
- `"stable"` Wait until the element is both [visible](./actionability.md#visible) and [stable](./actionability.md#stable).
- `"enabled"` Wait until the element is [enabled](./actionability.md#enabled).
- `"disabled"` Wait until the element is [not enabled](./actionability.md#enabled).
* `"visible"` Wait until the element is [visible](./actionability.md#visible).
* `"hidden"` Wait until the element is [not visible](./actionability.md#visible) or [not attached](./actionability.md#attached). Note that waiting for hidden does not throw when the element detaches.
* `"stable"` Wait until the element is both [visible](./actionability.md#visible) and [stable](./actionability.md#stable).
* `"enabled"` Wait until the element is [enabled](./actionability.md#enabled).
* `"disabled"` Wait until the element is [not enabled](./actionability.md#enabled).
If the element does not satisfy the condition for the `timeout` milliseconds, this method will throw.
@ -4853,12 +4854,12 @@ reported.
* extends: [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter)
The `CDPSession` instances are used to talk raw Chrome Devtools Protocol:
- protocol methods can be called with `session.send` method.
- protocol events can be subscribed to with `session.on` method.
* protocol methods can be called with `session.send` method.
* protocol events can be subscribed to with `session.on` method.
Useful links:
- Documentation on DevTools Protocol can be found here: [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
- Getting Started with DevTools Protocol: https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
* Documentation on DevTools Protocol can be found here: [DevTools Protocol Viewer](https://chromedevtools.github.io/devtools-protocol/).
* Getting Started with DevTools Protocol: https://github.com/aslushnikov/getting-started-with-cdp/blob/master/README.md
```js
const client = await page.context().newCDPSession(page);

View file

@ -16,14 +16,14 @@
*/
const playwright = require('../../');
const fs = require('fs');
const path = require('path');
const os = require('os');
const Source = require('./Source');
const Message = require('./Message');
const {spawnSync} = require('child_process');
const os = require('os');
const PROJECT_DIR = path.join(__dirname, '..', '..');
const VERSION = require(path.join(PROJECT_DIR, 'package.json')).version;
@ -41,11 +41,19 @@ async function run() {
const messages = [];
let changedFiles = false;
// Produce api.md
{
const comment = '<!-- THIS FILE IS NOW GENERATED -->';
const header = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-header.md')).toString();
const body = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-body.md')).toString();
const footer = fs.readFileSync(path.join(PROJECT_DIR, 'docs-src', 'api-footer.md')).toString();
fs.writeFileSync(path.join(PROJECT_DIR, 'docs', 'api.md'), [comment, header, body, footer].join('\n'));
}
// Documentation checks.
{
const readme = await Source.readFile(path.join(PROJECT_DIR, 'README.md'));
const binReadme = await Source.readFile(path.join(PROJECT_DIR, 'bin', 'README.md'));
const ffmpegReadme = await Source.readFile(path.join(PROJECT_DIR, 'third_party', 'ffmpeg', 'README.md'));
const contributing = await Source.readFile(path.join(PROJECT_DIR, 'CONTRIBUTING.md'));
const api = await Source.readFile(path.join(PROJECT_DIR, 'docs', 'api.md'));
const docs = await Source.readdir(path.join(PROJECT_DIR, 'docs'), '.md');