mirror of
https://github.com/puppeteer/puppeteer
synced 2024-06-14 14:02:48 +00:00
docs: restructure documentation guides (#12236)
This commit is contained in:
parent
a2f3415df2
commit
964d99efb9
@ -6,7 +6,7 @@
|
||||
|
||||
/* eslint-disable import/order */
|
||||
|
||||
import {copyFile, readFile, writeFile} from 'fs/promises';
|
||||
import {readFile, writeFile} from 'fs/promises';
|
||||
|
||||
import {docgen, spliceIntoSection} from '@puppeteer/docgen';
|
||||
import {execa} from 'execa';
|
||||
@ -17,7 +17,7 @@ export const docsNgSchematicsTask = task({
|
||||
name: 'docs:ng-schematics',
|
||||
run: async () => {
|
||||
const readme = await readFile('packages/ng-schematics/README.md', 'utf-8');
|
||||
await writeFile('docs/integrations/ng-schematics.md', readme);
|
||||
await writeFile('docs/guides/ng-schematics.md', readme);
|
||||
},
|
||||
});
|
||||
|
||||
@ -71,9 +71,6 @@ export const docsTask = task({
|
||||
name: 'docs',
|
||||
dependencies: [docsNgSchematicsTask, docsChromiumSupportTask],
|
||||
run: async () => {
|
||||
// Copy main page.
|
||||
await copyFile('README.md', 'docs/index.md');
|
||||
|
||||
// Generate documentation
|
||||
for (const [name, folder] of [
|
||||
['browsers', 'browsers-api'],
|
||||
|
223
README.md
223
README.md
@ -5,141 +5,17 @@
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png" height="200" align="right"/>
|
||||
|
||||
#### [Guides](https://pptr.dev/category/guides) | [API](https://pptr.dev/api) | [FAQ](https://pptr.dev/faq) | [Contributing](https://pptr.dev/contributing) | [Troubleshooting](https://pptr.dev/troubleshooting)
|
||||
#### [Docs](https://pptr.dev/docs) | [API](https://pptr.dev/api) | [FAQ](https://pptr.dev/faq) | [Contributing](https://pptr.dev/contributing) | [Troubleshooting](https://pptr.dev/troubleshooting)
|
||||
|
||||
> Puppeteer is a Node.js library which provides a high-level API to control
|
||||
> Chrome/Chromium over the
|
||||
> [DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/).
|
||||
> Puppeteer runs in
|
||||
> [headless](https://developer.chrome.com/docs/chromium/new-headless/)
|
||||
> mode by default, but can be configured to run in full ("headful")
|
||||
> Chrome/Chromium.
|
||||
Puppeteer is a Node.js library which provides a high-level API to control
|
||||
Chrome/Chromium over the
|
||||
[DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/).
|
||||
Puppeteer runs in
|
||||
[headless](https://developer.chrome.com/docs/chromium/new-headless/)
|
||||
mode by default, but can be configured to run in full ("headful")
|
||||
Chrome/Chromium.
|
||||
|
||||
#### What can I do?
|
||||
|
||||
Most things that you can do manually in the browser can be done using Puppeteer!
|
||||
Here are a few examples to get you started:
|
||||
|
||||
- Generate screenshots and PDFs of pages.
|
||||
- Crawl a SPA (Single-Page Application) and generate pre-rendered content (i.e.
|
||||
"SSR" (Server-Side Rendering)).
|
||||
- Automate form submission, UI testing, keyboard input, etc.
|
||||
- Create an automated testing environment using the latest JavaScript and
|
||||
browser features.
|
||||
- Capture a
|
||||
[timeline trace](https://developer.chrome.com/docs/devtools/performance/reference)
|
||||
of your site to help diagnose performance issues.
|
||||
- [Test Chrome Extensions](https://pptr.dev/guides/chrome-extensions).
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
To use Puppeteer in your project, run:
|
||||
|
||||
```bash
|
||||
npm i puppeteer
|
||||
# or using yarn
|
||||
yarn add puppeteer
|
||||
# or using pnpm
|
||||
pnpm i puppeteer
|
||||
```
|
||||
|
||||
When you install Puppeteer, it automatically downloads a recent version of
|
||||
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) and a `chrome-headless-shell` binary (starting with Puppeteer v21.6.0) that is [guaranteed to
|
||||
work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy)
|
||||
with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder
|
||||
by default (starting with Puppeteer v19.0.0). See [configuration](https://pptr.dev/api/puppeteer.configuration) for configuration options and environmental variables to control the download behavior.
|
||||
|
||||
If you deploy a project using Puppeteer to a hosting provider, such as Render or
|
||||
Heroku, you might need to reconfigure the location of the cache to be within
|
||||
your project folder (see an example below) because not all hosting providers
|
||||
include `$HOME/.cache` into the project's deployment.
|
||||
|
||||
For a version of Puppeteer without the browser installation, see
|
||||
[`puppeteer-core`](#puppeteer-core).
|
||||
|
||||
If used with TypeScript, the minimum supported TypeScript version is `4.7.4`.
|
||||
|
||||
#### Configuration
|
||||
|
||||
Puppeteer uses several defaults that can be customized through configuration
|
||||
files.
|
||||
|
||||
For example, to change the default cache directory Puppeteer uses to install
|
||||
browsers, you can add a `.puppeteerrc.cjs` (or `puppeteer.config.cjs`) at the
|
||||
root of your application with the contents
|
||||
|
||||
```js
|
||||
const {join} = require('path');
|
||||
|
||||
/**
|
||||
* @type {import("puppeteer").Configuration}
|
||||
*/
|
||||
module.exports = {
|
||||
// Changes the cache location for Puppeteer.
|
||||
cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
|
||||
};
|
||||
```
|
||||
|
||||
After adding the configuration file, you will need to remove and reinstall
|
||||
`puppeteer` for it to take effect.
|
||||
|
||||
See the [configuration guide](https://pptr.dev/guides/configuration) for more
|
||||
information.
|
||||
|
||||
#### `puppeteer-core`
|
||||
|
||||
For every release since v1.7.0 we publish two packages:
|
||||
|
||||
- [`puppeteer`](https://www.npmjs.com/package/puppeteer)
|
||||
- [`puppeteer-core`](https://www.npmjs.com/package/puppeteer-core)
|
||||
|
||||
`puppeteer` is a _product_ for browser automation. When installed, it downloads
|
||||
a version of Chrome, which it then drives using `puppeteer-core`. Being an
|
||||
end-user product, `puppeteer` automates several workflows using reasonable
|
||||
defaults [that can be customized](https://pptr.dev/guides/configuration).
|
||||
|
||||
`puppeteer-core` is a _library_ to help drive anything that supports DevTools
|
||||
protocol. Being a library, `puppeteer-core` is fully driven through its
|
||||
programmatic interface implying no defaults are assumed and `puppeteer-core`
|
||||
will not download Chrome when installed.
|
||||
|
||||
You should use `puppeteer-core` if you are
|
||||
[connecting to a remote browser](https://pptr.dev/api/puppeteer.puppeteer.connect)
|
||||
or [managing browsers yourself](https://pptr.dev/browsers-api/).
|
||||
If you are managing browsers yourself, you will need to call
|
||||
[`puppeteer.launch`](https://pptr.dev/api/puppeteer.puppeteernode.launch) with
|
||||
an explicit
|
||||
[`executablePath`](https://pptr.dev/api/puppeteer.launchoptions)
|
||||
(or [`channel`](https://pptr.dev/api/puppeteer.launchoptions) if it's
|
||||
installed in a standard location).
|
||||
|
||||
When using `puppeteer-core`, remember to change the import:
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer-core';
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Puppeteer follows the latest
|
||||
[maintenance LTS](https://github.com/nodejs/Release#release-schedule) version of
|
||||
Node.
|
||||
|
||||
Puppeteer will be familiar to people using other browser testing frameworks. You
|
||||
[launch](https://pptr.dev/api/puppeteer.puppeteernode.launch)/[connect](https://pptr.dev/api/puppeteer.puppeteernode.connect)
|
||||
a [browser](https://pptr.dev/api/puppeteer.browser),
|
||||
[create](https://pptr.dev/api/puppeteer.browser.newpage) some
|
||||
[pages](https://pptr.dev/api/puppeteer.page), and then manipulate them with
|
||||
[Puppeteer's API](https://pptr.dev/api).
|
||||
|
||||
For more in-depth usage, check our [guides](https://pptr.dev/category/guides)
|
||||
and [examples](https://github.com/puppeteer/puppeteer/tree/main/examples).
|
||||
|
||||
#### Example
|
||||
|
||||
The following example searches [developer.chrome.com](https://developer.chrome.com/) for blog posts with text "automate beyond recorder", click on the first result and print the full title of the blog post.
|
||||
## Example
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
@ -176,86 +52,7 @@ import puppeteer from 'puppeteer';
|
||||
})();
|
||||
```
|
||||
|
||||
### Default runtime settings
|
||||
|
||||
**1. Uses Headless mode**
|
||||
|
||||
By default Puppeteer launches Chrome in
|
||||
[the Headless mode](https://developer.chrome.com/docs/chromium/new-headless/).
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch();
|
||||
// Equivalent to
|
||||
const browser = await puppeteer.launch({headless: true});
|
||||
```
|
||||
|
||||
Before v22, Puppeteer launched the [old Headless mode](https://developer.chrome.com/docs/chromium/new-headless/) by default.
|
||||
The old headless mode is now known as
|
||||
[`chrome-headless-shell`](https://developer.chrome.com/blog/chrome-headless-shell)
|
||||
and ships as a separate binary. `chrome-headless-shell` does not match the
|
||||
behavior of the regular Chrome completely but it is currently more performant
|
||||
for automation tasks where the complete Chrome feature set is not needed. If the performance
|
||||
is more important for your use case, switch to `chrome-headless-shell` as following:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({headless: 'shell'});
|
||||
```
|
||||
|
||||
To launch a "headful" version of Chrome, set the
|
||||
[`headless`](https://pptr.dev/api/puppeteer.browserlaunchargumentoptions) to `false`
|
||||
option when launching a browser:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({headless: false});
|
||||
```
|
||||
|
||||
**2. Runs a bundled version of Chrome**
|
||||
|
||||
By default, Puppeteer downloads and uses a specific version of Chrome so its
|
||||
API is guaranteed to work out of the box. To use Puppeteer with a different
|
||||
version of Chrome or Chromium, pass in the executable's path when creating a
|
||||
`Browser` instance:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
|
||||
```
|
||||
|
||||
You can also use Puppeteer with Firefox. See
|
||||
[status of cross-browser support](https://pptr.dev/faq#q-what-is-the-status-of-cross-browser-support) for
|
||||
more information.
|
||||
|
||||
See
|
||||
[`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/)
|
||||
for a description of the differences between Chromium and Chrome.
|
||||
[`This article`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/chromium_browser_vs_google_chrome.md)
|
||||
describes some differences for Linux users.
|
||||
|
||||
**3. Creates a fresh user profile**
|
||||
|
||||
Puppeteer creates its own browser user profile which it **cleans up on every
|
||||
run**.
|
||||
|
||||
#### Using Docker
|
||||
|
||||
See our [Docker guide](https://pptr.dev/guides/docker).
|
||||
|
||||
#### Using Chrome Extensions
|
||||
|
||||
See our [Chrome extensions guide](https://pptr.dev/guides/chrome-extensions).
|
||||
|
||||
## Resources
|
||||
|
||||
- [API Documentation](https://pptr.dev/api)
|
||||
- [Guides](https://pptr.dev/category/guides)
|
||||
- [Examples](https://github.com/puppeteer/puppeteer/tree/main/examples)
|
||||
- [Community list of Puppeteer resources](https://github.com/transitive-bullshit/awesome-puppeteer)
|
||||
|
||||
## Contributing
|
||||
|
||||
Check out our [contributing guide](https://pptr.dev/contributing) to get an
|
||||
Check out our [contributing guide](https://pptr.dev/community/contributing) to get an
|
||||
overview of Puppeteer development.
|
||||
|
||||
## FAQ
|
||||
|
||||
Our [FAQ](https://pptr.dev/faq) has migrated to
|
||||
[our site](https://pptr.dev/faq).
|
||||
|
79
docs/guides/browser-management.md
Normal file
79
docs/guides/browser-management.md
Normal file
@ -0,0 +1,79 @@
|
||||
# Browser management
|
||||
|
||||
Usually, you start working with Puppeteer by either launching [launching](https://pptr.dev/api/puppeteer.puppeteernode.launch) or [connecting](https://pptr.dev/api/puppeteer.puppeteernode.connect) to a browser.
|
||||
|
||||
## Launching a browser
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
// ...
|
||||
```
|
||||
|
||||
## Closing a browser
|
||||
|
||||
To gracefully close the browser, you the [`browser.close()`](https://pptr.dev/api/puppeteer.browser.close) method:
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
await browser.close();
|
||||
```
|
||||
|
||||
## Browser contexts
|
||||
|
||||
If you need to isolate your automation taks, use [BrowserContexts](https://pptr.dev/api/puppeteer.browser.createbrowsercontext/). Cookies and local storage are not shared between browser contexts. Also, you can close all pages in the context by closing the context.
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
const context = await browser.createBrowserContext();
|
||||
|
||||
const page1 = await context.newPage();
|
||||
const page2 = await context.newPage();
|
||||
|
||||
await context.close();
|
||||
```
|
||||
|
||||
## Permissions
|
||||
|
||||
You can also configure permissions for a browser context:
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
const browser = await puppeteer.launch();
|
||||
const context = browser.defaultBrowserContext();
|
||||
|
||||
await context.overridePermissions('https://html5demos.com', ['geolocation']);
|
||||
```
|
||||
|
||||
## Connecting to a running browser
|
||||
|
||||
If you launched a browser outside of Puppeteer, you can connect to it using [`connect`](https://pptr.dev/api/puppeteer.puppeteernode.connect/) method. Usually, you can grab a WebSocket endpoint URL from the browser output:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.connect({
|
||||
browserWSEndpoint: 'ws://127.0.0.1:9222/...',
|
||||
});
|
||||
|
||||
const page = await browser.newPage();
|
||||
|
||||
browser.disconnect();
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
Unlike `browser.close()`, `browser.disconnect()` does not shut down the browser or close any pages.
|
||||
|
||||
:::
|
@ -1,5 +1,18 @@
|
||||
# Configuration
|
||||
|
||||
By default, Puppeteer downloads and uses a specific version of Chrome so its
|
||||
API is guaranteed to work out of the box. To use Puppeteer with a different
|
||||
version of Chrome or Chromium, pass in the executable's path when creating a
|
||||
`Browser` instance:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
|
||||
```
|
||||
|
||||
You can also use Puppeteer with Firefox. See
|
||||
[status of cross-browser support](https://pptr.dev/faq#q-what-is-the-status-of-cross-browser-support) for
|
||||
more information.
|
||||
|
||||
```mdx-code-block
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
4
docs/guides/cookies.md
Normal file
4
docs/guides/cookies.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Cookies
|
||||
|
||||
Puppeteer allows modifying cookies for a page ahead of time by using [Page.setCookie()](https://pptr.dev/api/puppeteer.page.setcookie/).
|
||||
You can also read the cookies set for a page using [Page.cookies()](https://pptr.dev/api/puppeteer.page.cookies/).
|
9
docs/guides/files.md
Normal file
9
docs/guides/files.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Files
|
||||
|
||||
Currently, Puppeteer does not offer a way to handle file downloads in a programmtic way.
|
||||
For uploading files, you need to locate a file input element and call [`ElementHandle.uploadFile`](https://pptr.dev/api/puppeteer.elementhandle.uploadfile/).
|
||||
|
||||
```ts
|
||||
const fileElement = await page.waitForSelector('input[type=file]');
|
||||
await fileElement.uploadFile(['./path-to-local-file']);
|
||||
```
|
48
docs/guides/getting-started.md
Normal file
48
docs/guides/getting-started.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Getting started
|
||||
|
||||
Puppeteer will be familiar to people using other browser testing frameworks. You
|
||||
[launch](https://pptr.dev/api/puppeteer.puppeteernode.launch)/[connect](https://pptr.dev/api/puppeteer.puppeteernode.connect)
|
||||
a [browser](https://pptr.dev/api/puppeteer.browser),
|
||||
[create](https://pptr.dev/api/puppeteer.browser.newpage) some
|
||||
[pages](https://pptr.dev/api/puppeteer.page), and then manipulate them with
|
||||
[Puppeteer's API](https://pptr.dev/api).
|
||||
|
||||
The following example searches [developer.chrome.com](https://developer.chrome.com/) for blog posts with text "automate beyond recorder", click on the first result and print the full title of the blog post.
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
(async () => {
|
||||
// Launch the browser and open a new blank page
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Navigate the page to a URL
|
||||
await page.goto('https://developer.chrome.com/');
|
||||
|
||||
// Set screen size
|
||||
await page.setViewport({width: 1080, height: 1024});
|
||||
|
||||
// Type into search box
|
||||
await page.type('.devsite-search-field', 'automate beyond recorder');
|
||||
|
||||
// Wait and click on first result
|
||||
const searchResultSelector = '.devsite-result-item-link';
|
||||
await page.waitForSelector(searchResultSelector);
|
||||
await page.click(searchResultSelector);
|
||||
|
||||
// Locate the full title with a unique string
|
||||
const textSelector = await page.waitForSelector(
|
||||
'text/Customize and automate'
|
||||
);
|
||||
const fullTitle = await textSelector?.evaluate(el => el.textContent);
|
||||
|
||||
// Print the full title
|
||||
console.log('The title of this blog post is "%s".', fullTitle);
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
For more in-depth usage, check our [documentation](https://pptr.dev/docs)
|
||||
and [examples](https://github.com/puppeteer/puppeteer/tree/main/examples).
|
30
docs/guides/headless-modes.md
Normal file
30
docs/guides/headless-modes.md
Normal file
@ -0,0 +1,30 @@
|
||||
# Headless mode
|
||||
|
||||
By default Puppeteer launches the browser in
|
||||
[the Headless mode](https://developer.chrome.com/docs/chromium/new-headless/).
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch();
|
||||
// Equivalent to
|
||||
const browser = await puppeteer.launch({headless: true});
|
||||
```
|
||||
|
||||
Before v22, Puppeteer launched the [old Headless mode](https://developer.chrome.com/docs/chromium/new-headless/) by default.
|
||||
The old headless mode is now known as
|
||||
[`chrome-headless-shell`](https://developer.chrome.com/blog/chrome-headless-shell)
|
||||
and ships as a separate binary. `chrome-headless-shell` does not match the
|
||||
behavior of the regular Chrome completely but it is currently more performant
|
||||
for automation tasks where the complete Chrome feature set is not needed. If the performance
|
||||
is more important for your use case, switch to `chrome-headless-shell` as following:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({headless: 'shell'});
|
||||
```
|
||||
|
||||
To launch a "headful" version of Chrome, set the
|
||||
[`headless`](https://pptr.dev/api/puppeteer.browserlaunchargumentoptions) to `false`
|
||||
option when launching a browser:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({headless: false});
|
||||
```
|
48
docs/guides/installation.md
Normal file
48
docs/guides/installation.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Installation
|
||||
|
||||
To use Puppeteer in your project, run:
|
||||
|
||||
```bash
|
||||
npm i puppeteer
|
||||
# or using yarn
|
||||
yarn add puppeteer
|
||||
# or using pnpm
|
||||
pnpm i puppeteer
|
||||
```
|
||||
|
||||
When you install Puppeteer, it automatically downloads a recent version of
|
||||
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) and a `chrome-headless-shell` binary (starting with Puppeteer v21.6.0) that is [guaranteed to
|
||||
work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy)
|
||||
with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder
|
||||
by default (starting with Puppeteer v19.0.0). See [configuration](https://pptr.dev/api/puppeteer.configuration) for configuration options and environmental variables to control the download behavior.
|
||||
|
||||
For every release since v1.7.0 we publish two packages:
|
||||
|
||||
- [`puppeteer`](https://www.npmjs.com/package/puppeteer)
|
||||
- [`puppeteer-core`](https://www.npmjs.com/package/puppeteer-core)
|
||||
|
||||
`puppeteer` is a _product_ for browser automation. When installed, it downloads
|
||||
a version of Chrome, which it then drives using `puppeteer-core`. Being an
|
||||
end-user product, `puppeteer` automates several workflows using reasonable
|
||||
defaults [that can be customized](https://pptr.dev/guides/configuration).
|
||||
|
||||
`puppeteer-core` is a _library_ to help drive anything that supports DevTools
|
||||
protocol. Being a library, `puppeteer-core` is fully driven through its
|
||||
programmatic interface implying no defaults are assumed and `puppeteer-core`
|
||||
will not download Chrome when installed.
|
||||
|
||||
You should use `puppeteer-core` if you are
|
||||
[connecting to a remote browser](https://pptr.dev/api/puppeteer.puppeteer.connect)
|
||||
or [managing browsers yourself](https://pptr.dev/browsers-api/).
|
||||
If you are managing browsers yourself, you will need to call
|
||||
[`puppeteer.launch`](https://pptr.dev/api/puppeteer.puppeteernode.launch) with
|
||||
an explicit
|
||||
[`executablePath`](https://pptr.dev/api/puppeteer.launchoptions)
|
||||
(or [`channel`](https://pptr.dev/api/puppeteer.launchoptions) if it's
|
||||
installed in a standard location).
|
||||
|
||||
When using `puppeteer-core`, remember to change the import:
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer-core';
|
||||
```
|
@ -1,4 +1,4 @@
|
||||
# Evaluate JavaScript
|
||||
# JavaScript execution
|
||||
|
||||
Puppeteer allows evaluating JavaScript functions in the context of the page
|
||||
driven by Puppeteer:
|
6
docs/guides/links.md
Normal file
6
docs/guides/links.md
Normal file
@ -0,0 +1,6 @@
|
||||
# Links
|
||||
|
||||
- [API Documentation](https://pptr.dev/api)
|
||||
- [Guides](https://pptr.dev/category/guides)
|
||||
- [Examples](https://github.com/puppeteer/puppeteer/tree/main/examples)
|
||||
- [Community list of Puppeteer resources](https://github.com/transitive-bullshit/awesome-puppeteer)
|
@ -1,170 +0,0 @@
|
||||
# Locators
|
||||
|
||||
Locators is a new, experimental API that combines the functionalities of
|
||||
waiting and actions. With additional precondition checks, it
|
||||
enables automatic retries for failed actions, resulting in more reliable and
|
||||
less flaky automation scripts.
|
||||
|
||||
:::note
|
||||
|
||||
Locators API is experimental and we will not follow semver for breaking changes
|
||||
in the Locators API.
|
||||
|
||||
:::
|
||||
|
||||
## Use cases
|
||||
|
||||
### Waiting for an element
|
||||
|
||||
```ts
|
||||
await page.locator('button').wait();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
|
||||
### Waiting for a function
|
||||
|
||||
```ts
|
||||
await page
|
||||
.locator(() => {
|
||||
let resolve!: (node: HTMLCanvasElement) => void;
|
||||
const promise = new Promise(res => {
|
||||
return (resolve = res);
|
||||
});
|
||||
const observer = new MutationObserver(records => {
|
||||
for (const record of records) {
|
||||
if (record.target instanceof HTMLCanvasElement) {
|
||||
resolve(record.target);
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(document);
|
||||
return promise;
|
||||
})
|
||||
.wait();
|
||||
```
|
||||
|
||||
### Clicking an element
|
||||
|
||||
```ts
|
||||
await page.locator('button').click();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to become enabled.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
### Clicking an element matching a criteria
|
||||
|
||||
```ts
|
||||
await page
|
||||
.locator('button')
|
||||
.filter(button => !button.disabled)
|
||||
.click();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to become enabled.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
### Filling out an input
|
||||
|
||||
```ts
|
||||
await page.locator('input').fill('value');
|
||||
```
|
||||
|
||||
Automatically detects the input type and choose an appropriate way to fill it out with the provided value.
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to become enabled.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
### Retrieving an element property
|
||||
|
||||
```ts
|
||||
const enabled = await page
|
||||
.locator('button')
|
||||
.map(button => !button.disabled)
|
||||
.wait();
|
||||
```
|
||||
|
||||
### Hover over an element
|
||||
|
||||
```ts
|
||||
await page.locator('div').hover();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
### Scroll an element
|
||||
|
||||
```ts
|
||||
await page.locator('div').scroll({
|
||||
scrollLeft: 10,
|
||||
scrollTop: 20,
|
||||
});
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
## Configuring locators
|
||||
|
||||
Locators can be configured to tune configure the preconditions and other other options:
|
||||
|
||||
```ts
|
||||
await page
|
||||
.locator('button')
|
||||
.setEnsureElementIsInTheViewport(false)
|
||||
.setTimeout(0)
|
||||
.setVisibility(null)
|
||||
.setWaitForEnabled(false)
|
||||
.setWaitForStableBoundingBox(false)
|
||||
.click();
|
||||
```
|
||||
|
||||
## Getting locator events
|
||||
|
||||
Currently, locators support a single event that notifies you when the locator is about to perform the action:
|
||||
|
||||
```ts
|
||||
let willClick = false;
|
||||
await page
|
||||
.locator('button')
|
||||
.on(LocatorEvent.Action, () => {
|
||||
willClick = true;
|
||||
})
|
||||
.click();
|
||||
```
|
||||
|
||||
This event can be used for logging/debugging or other purposes. The event might
|
||||
fire multiple times if the locator retries the action.
|
14
docs/guides/network-logging.md
Normal file
14
docs/guides/network-logging.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Network logging
|
||||
|
||||
By default, Puppeteer listens for all network requests and responses and emits network events on the page.
|
||||
|
||||
```ts
|
||||
const page = await browser.newPage();
|
||||
page.on('request', request => {
|
||||
console.log(request.url());
|
||||
});
|
||||
|
||||
page.on('response', response => {
|
||||
console.log(response.url());
|
||||
});
|
||||
```
|
513
docs/guides/page-interactions.md
Normal file
513
docs/guides/page-interactions.md
Normal file
@ -0,0 +1,513 @@
|
||||
# Page interactions
|
||||
|
||||
Puppeteer allows you interact with the pages in various ways.
|
||||
|
||||
## Locators
|
||||
|
||||
Locators is a new, experimental API that combines the functionalities of
|
||||
waiting and actions. With additional precondition checks, it
|
||||
enables automatic retries for failed actions, resulting in more reliable and
|
||||
less flaky automation scripts.
|
||||
|
||||
:::note
|
||||
|
||||
Locators API is experimental and we will not follow semver for breaking changes
|
||||
in the Locators API.
|
||||
|
||||
:::
|
||||
|
||||
### Use cases
|
||||
|
||||
#### Waiting for an element
|
||||
|
||||
```ts
|
||||
await page.locator('button').wait();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
|
||||
#### Waiting for a function
|
||||
|
||||
```ts
|
||||
await page
|
||||
.locator(() => {
|
||||
let resolve!: (node: HTMLCanvasElement) => void;
|
||||
const promise = new Promise(res => {
|
||||
return (resolve = res);
|
||||
});
|
||||
const observer = new MutationObserver(records => {
|
||||
for (const record of records) {
|
||||
if (record.target instanceof HTMLCanvasElement) {
|
||||
resolve(record.target);
|
||||
}
|
||||
}
|
||||
});
|
||||
observer.observe(document);
|
||||
return promise;
|
||||
})
|
||||
.wait();
|
||||
```
|
||||
|
||||
#### Clicking an element
|
||||
|
||||
```ts
|
||||
await page.locator('button').click();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to become enabled.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
#### Clicking an element matching a criteria
|
||||
|
||||
```ts
|
||||
await page
|
||||
.locator('button')
|
||||
.filter(button => !button.disabled)
|
||||
.click();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to become enabled.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
#### Filling out an input
|
||||
|
||||
```ts
|
||||
await page.locator('input').fill('value');
|
||||
```
|
||||
|
||||
Automatically detects the input type and choose an appropriate way to fill it out with the provided value.
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to become enabled.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
#### Retrieving an element property
|
||||
|
||||
```ts
|
||||
const enabled = await page
|
||||
.locator('button')
|
||||
.map(button => !button.disabled)
|
||||
.wait();
|
||||
```
|
||||
|
||||
#### Hover over an element
|
||||
|
||||
```ts
|
||||
await page.locator('div').hover();
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
#### Scroll an element
|
||||
|
||||
```ts
|
||||
await page.locator('div').scroll({
|
||||
scrollLeft: 10,
|
||||
scrollTop: 20,
|
||||
});
|
||||
```
|
||||
|
||||
The following preconditions are automatically checked:
|
||||
|
||||
- Ensures the element is in the viewport.
|
||||
- Waits for the element to become
|
||||
[visible](https://pptr.dev/api/puppeteer.elementhandle.isvisible/) or hidden.
|
||||
- Waits for the element to have a stable bounding box over two consecutive
|
||||
animation frames.
|
||||
|
||||
### Configuring locators
|
||||
|
||||
Locators can be configured to tune configure the preconditions and other other options:
|
||||
|
||||
```ts
|
||||
await page
|
||||
.locator('button')
|
||||
.setEnsureElementIsInTheViewport(false)
|
||||
.setTimeout(0)
|
||||
.setVisibility(null)
|
||||
.setWaitForEnabled(false)
|
||||
.setWaitForStableBoundingBox(false)
|
||||
.click();
|
||||
```
|
||||
|
||||
### Getting locator events
|
||||
|
||||
Currently, locators support a single event that notifies you when the locator is about to perform the action:
|
||||
|
||||
```ts
|
||||
let willClick = false;
|
||||
await page
|
||||
.locator('button')
|
||||
.on(LocatorEvent.Action, () => {
|
||||
willClick = true;
|
||||
})
|
||||
.click();
|
||||
```
|
||||
|
||||
This event can be used for logging/debugging or other purposes. The event might
|
||||
fire multiple times if the locator retries the action.
|
||||
|
||||
## Query Selectors
|
||||
|
||||
Queries are the primary mechanism for interacting with the DOM on your site. For example, a typical workflow goes like:
|
||||
|
||||
```ts
|
||||
// Import puppeteer
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
(async () => {
|
||||
// Launch the browser
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
// Create a page
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Go to your site
|
||||
await page.goto('YOUR_SITE');
|
||||
|
||||
// Query for an element handle.
|
||||
const element = await page.waitForSelector('div > .class-name');
|
||||
|
||||
// Do something with element...
|
||||
await element.click(); // Just an example.
|
||||
|
||||
// Dispose of handle
|
||||
await element.dispose();
|
||||
|
||||
// Close browser.
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
### `P` Selectors
|
||||
|
||||
Puppeteer uses a superset of the CSS selector syntax for querying. We call this syntax _P selectors_ and it's supercharged with extra capabilities such as deep combinators and text selection.
|
||||
|
||||
:::caution
|
||||
|
||||
Although P selectors look like real CSS selectors (we intentionally designed it this way), they should not be used for actually CSS styling. They are designed only for Puppeteer.
|
||||
|
||||
:::
|
||||
|
||||
:::note
|
||||
|
||||
P selectors only work on the first "depth" of selectors; for example, `:is(div >>> a)` will not work.
|
||||
|
||||
:::
|
||||
|
||||
#### `>>>` and `>>>>` combinators
|
||||
|
||||
The `>>>` and `>>>>` are called _deep descendent_ and _deep_ combinators respectively. Both combinators have the effect of going into shadow hosts with `>>>` going into every shadow host under a node and `>>>>` going into the immediate one (if the node is a shadow host; otherwise, it's a no-op).
|
||||
|
||||
:::note
|
||||
|
||||
A common question is when should `>>>>` be chosen over `>>>` considering the flexibility of `>>>`. A similar question can be asked about `>` and a space; choose `>` if you do not need to query all elements under a given node and a space otherwise. This answer extends to `>>>>` (`>`) and `>>>` (space) naturally.
|
||||
|
||||
:::
|
||||
|
||||
##### Example
|
||||
|
||||
Suppose we have the markup
|
||||
|
||||
```html
|
||||
<custom-element>
|
||||
<template shadowrootmode="open">
|
||||
<slot></slot>
|
||||
</template>
|
||||
<custom-element>
|
||||
<template shadowrootmode="open">
|
||||
<slot></slot>
|
||||
</template>
|
||||
<custom-element>
|
||||
<template shadowrootmode="open">
|
||||
<slot></slot>
|
||||
</template>
|
||||
<h2>Light content</h2>
|
||||
</custom-element>
|
||||
</custom-element>
|
||||
</custom-element>
|
||||
```
|
||||
|
||||
> Note: `<template shadowrootmode="open">` is not supported on Firefox.
|
||||
> You can read more about it [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#attributes).
|
||||
|
||||
Then `custom-element >>> h2` will return `h2`, but `custom-element >>>> h2` will return nothing since the inner `h2` is in a deeper shadow root.
|
||||
|
||||
#### `P`-elements
|
||||
|
||||
`P` elements are [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) with a `-p` vendor prefix. It allows you to enhance your selectors with Puppeteer-specific query engines such as XPath, text queries, and ARIA.
|
||||
|
||||
##### Text selectors (`-p-text`)
|
||||
|
||||
Text selectors will select "minimal" elements containing the given text, even within (open) shadow roots. Here, "minimum" means the deepest elements that contain a given text, but not their parents (which technically will also contain the given text).
|
||||
|
||||
###### Example
|
||||
|
||||
```ts
|
||||
const element = await page.waitForSelector('div ::-p-text(My name is Jun)');
|
||||
// You can also use escapes.
|
||||
const element = await page.waitForSelector(
|
||||
':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\))'
|
||||
);
|
||||
// or quotes
|
||||
const element = await page.waitForSelector(
|
||||
'div >>>> ::-p-text("My name is Jun (pronounced like \\"June\\")"):hover'
|
||||
);
|
||||
```
|
||||
|
||||
##### XPath selectors (`-p-xpath`)
|
||||
|
||||
XPath selectors will use the browser's native [`Document.evaluate`](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate) to query for elements.
|
||||
|
||||
###### Example
|
||||
|
||||
```ts
|
||||
const element = await page.waitForSelector('::-p-xpath(h2)');
|
||||
```
|
||||
|
||||
##### ARIA selectors (`-p-aria`)
|
||||
|
||||
ARIA selectors can be used to find elements with a given ARIA label. These labels are computed using Chrome's internal representation.
|
||||
|
||||
###### Example
|
||||
|
||||
```ts
|
||||
const node = await page.waitForSelector('::-p-aria(Submit)');
|
||||
const node = await page.waitForSelector(
|
||||
'::-p-aria([name="Click me"][role="button"])'
|
||||
);
|
||||
```
|
||||
|
||||
#### Custom selectors
|
||||
|
||||
Puppeteer provides users the ability to add their own query selectors to Puppeteer using [Puppeteer.registerCustomQueryHandler](../api/puppeteer.registercustomqueryhandler.md). This is useful for creating custom selectors based on framework objects or other vendor-specific objects.
|
||||
|
||||
##### Custom Selectors
|
||||
|
||||
You can register a custom query handler that allows you to create custom selectors. For example, define a query handler for `getById` selectors:
|
||||
|
||||
```ts
|
||||
Puppeteer.registerCustomQueryHandler('getById', {
|
||||
queryOne: (elementOrDocument, selector) => {
|
||||
return elementOrDocument.querySelector(`[id="${CSS.escape(selector)}"]`);
|
||||
},
|
||||
// Note: for demonstation perpose only `id` should be page unique
|
||||
queryAll: (elementOrDocument, selector) => {
|
||||
return elementOrDocument.querySelectorAll(`[id="${CSS.escape(selector)}"]`);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You can now use it as following:
|
||||
|
||||
```ts
|
||||
const node = await page.waitForSelector('::-p-getById(elementId)');
|
||||
// OR used in conjunction with other selectors
|
||||
const moreSpecificNode = await page.waitForSelector(
|
||||
'.side-bar ::-p-getById(elementId)'
|
||||
);
|
||||
```
|
||||
|
||||
##### Custom framework components selector
|
||||
|
||||
:::caution
|
||||
|
||||
Be careful when relying on internal APIs of libraries or frameworks. They can change at any time.
|
||||
|
||||
:::
|
||||
|
||||
Find Vue components by name by using Vue internals for querying:
|
||||
|
||||
```ts
|
||||
Puppeteer.registerCustomQueryHandler('vue', {
|
||||
queryOne: (element, name) => {
|
||||
const walker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
|
||||
do {
|
||||
const currentNode = walker.currentNode;
|
||||
if (
|
||||
currentNode.__vnode?.ctx?.type?.name.toLowerCase() ===
|
||||
name.toLocaleLowerCase()
|
||||
) {
|
||||
return currentNode;
|
||||
}
|
||||
} while (walker.nextNode());
|
||||
|
||||
return null;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Query the Vue component as following:
|
||||
|
||||
```ts
|
||||
const element = await page.$('::-p-vue(MyComponent)');
|
||||
```
|
||||
|
||||
##### Web Components
|
||||
|
||||
Web Components create their own tag so you can query them by the tag name:
|
||||
|
||||
```ts
|
||||
const element = await page.$('my-web-component');
|
||||
```
|
||||
|
||||
Extend `HTMLElementTagNameMap` to define types for custom tags. This allows Puppeteer to infer the return type for the ElementHandle:
|
||||
|
||||
```ts
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'my-web-component': MyWebComponent;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Query Selectors (legacy)
|
||||
|
||||
:::caution
|
||||
|
||||
While we maintin prefixed selectors, the recommended way is to use the selector syntax documented above.
|
||||
|
||||
:::
|
||||
|
||||
Queries are the primary mechanism for interacting with the DOM on your site. For example, a typical workflow goes like:
|
||||
|
||||
```ts
|
||||
// Import puppeteer
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
(async () => {
|
||||
// Launch the browser
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
// Create a page
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Go to your site
|
||||
await page.goto('YOUR_SITE');
|
||||
|
||||
// Query for an element handle.
|
||||
const element = await page.waitForSelector('div > .class-name');
|
||||
|
||||
// Do something with element...
|
||||
await element.click(); // Just an example.
|
||||
|
||||
// Dispose of handle
|
||||
await element.dispose();
|
||||
|
||||
// Close browser.
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
### CSS
|
||||
|
||||
CSS selectors follow the CSS spec of the browser being automated. We provide some basic type deduction for CSS selectors (such as `HTMLInputElement` for `input`), but any selector that contains no type information (such as `.class-name`) will need to be coerced manually using TypeScript's `as` coercion mechanism.
|
||||
|
||||
#### Example
|
||||
|
||||
```ts
|
||||
// Automatic
|
||||
const element = await page.waitForSelector('div > input');
|
||||
// Manual
|
||||
const element = (await page.waitForSelector(
|
||||
'div > .class-name-for-input'
|
||||
)) as HTMLInputElement;
|
||||
```
|
||||
|
||||
### Built-in selectors
|
||||
|
||||
Built-in selectors are Puppeteer's own class of selectors for doing things CSS cannot. Every built-in selector starts with a prefix `.../` to assist Puppeteer in distinguishing between CSS selectors and a built-in.
|
||||
|
||||
#### Text selectors (`text/`)
|
||||
|
||||
Text selectors will select "minimal" elements containing the given text, even within (open) shadow roots. Here, "minimum" means the deepest elements that contain a given text, but not their parents (which technically will also contain the given text).
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
// Note we usually need type coercion since the type cannot be deduced, but for text selectors, `instanceof` checks may be better for runtime validation.
|
||||
const element = await page.waitForSelector('text/My name is Jun');
|
||||
```
|
||||
|
||||
#### XPath selectors (`xpath/`)
|
||||
|
||||
XPath selectors will use the browser's native [`Document.evaluate`](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate) to query for elements.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
// There is not type deduction for XPaths.
|
||||
const node = await page.waitForSelector('xpath/h2');
|
||||
```
|
||||
|
||||
#### ARIA selectors (`aria/`)
|
||||
|
||||
ARIA selectors can be used to find elements with a given ARIA label. These labels are computed using Chrome's internal representation.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const node = await page.waitForSelector('aria/Button name');
|
||||
```
|
||||
|
||||
#### Pierce selectors (`pierce/`)
|
||||
|
||||
Pierce selectors will run the `querySelector*` API on the document and all shadow roots to find an element.
|
||||
|
||||
:::danger
|
||||
|
||||
Selectors will **not** _partially_ pierce through shadow roots. See the examples below.
|
||||
|
||||
:::
|
||||
|
||||
##### Example
|
||||
|
||||
Suppose the HTML is
|
||||
|
||||
```html
|
||||
<div>
|
||||
<custom-element>
|
||||
<div></div>
|
||||
</custom-element>
|
||||
</div>
|
||||
```
|
||||
|
||||
Then
|
||||
|
||||
```ts
|
||||
// This will be two elements because of the outer and inner div.
|
||||
expect((await page.$$('pierce/div')).length).toBe(2);
|
||||
|
||||
// Partial piercing doesn't work.
|
||||
expect((await page.$$('pierce/div div')).length).toBe(0);
|
||||
```
|
||||
|
||||
### Custom selectors
|
||||
|
||||
Puppeteer provides users the ability to add their own query selectors to Puppeteer using [Puppeteer.registerCustomQueryHandler](../api/puppeteer.registercustomqueryhandler.md). This is useful for creating custom selectors based on framework objects or other vendor-specific objects.
|
19
docs/guides/pdf-generation.md
Normal file
19
docs/guides/pdf-generation.md
Normal file
@ -0,0 +1,19 @@
|
||||
# PDF generation
|
||||
|
||||
For printing PDFs use [`Page.pdf()`](https://pptr.dev/api/puppeteer.page.pdf).
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.goto('https://news.ycombinator.com', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
// Saves the PDF to hn.pdf.
|
||||
await page.pdf({
|
||||
path: 'hn.pdf',
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
```
|
||||
|
||||
By default, the [`Page.pdf()`](https://pptr.dev/api/puppeteer.page.pdf) waits for fonts to be loaded.
|
@ -1,118 +0,0 @@
|
||||
# Query Selectors (legacy)
|
||||
|
||||
Queries are the primary mechanism for interacting with the DOM on your site. For example, a typical workflow goes like:
|
||||
|
||||
```ts
|
||||
// Import puppeteer
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
(async () => {
|
||||
// Launch the browser
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
// Create a page
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Go to your site
|
||||
await page.goto('YOUR_SITE');
|
||||
|
||||
// Query for an element handle.
|
||||
const element = await page.waitForSelector('div > .class-name');
|
||||
|
||||
// Do something with element...
|
||||
await element.click(); // Just an example.
|
||||
|
||||
// Dispose of handle
|
||||
await element.dispose();
|
||||
|
||||
// Close browser.
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
## CSS
|
||||
|
||||
CSS selectors follow the CSS spec of the browser being automated. We provide some basic type deduction for CSS selectors (such as `HTMLInputElement` for `input`), but any selector that contains no type information (such as `.class-name`) will need to be coerced manually using TypeScript's `as` coercion mechanism.
|
||||
|
||||
### Example
|
||||
|
||||
```ts
|
||||
// Automatic
|
||||
const element = await page.waitForSelector('div > input');
|
||||
// Manual
|
||||
const element = (await page.waitForSelector(
|
||||
'div > .class-name-for-input'
|
||||
)) as HTMLInputElement;
|
||||
```
|
||||
|
||||
## Built-in selectors
|
||||
|
||||
Built-in selectors are Puppeteer's own class of selectors for doing things CSS cannot. Every built-in selector starts with a prefix `.../` to assist Puppeteer in distinguishing between CSS selectors and a built-in.
|
||||
|
||||
### Text selectors (`text/`)
|
||||
|
||||
Text selectors will select "minimal" elements containing the given text, even within (open) shadow roots. Here, "minimum" means the deepest elements that contain a given text, but not their parents (which technically will also contain the given text).
|
||||
|
||||
#### Example
|
||||
|
||||
```ts
|
||||
// Note we usually need type coercion since the type cannot be deduced, but for text selectors, `instanceof` checks may be better for runtime validation.
|
||||
const element = await page.waitForSelector('text/My name is Jun');
|
||||
```
|
||||
|
||||
### XPath selectors (`xpath/`)
|
||||
|
||||
XPath selectors will use the browser's native [`Document.evaluate`](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate) to query for elements.
|
||||
|
||||
#### Example
|
||||
|
||||
```ts
|
||||
// There is not type deduction for XPaths.
|
||||
const node = await page.waitForSelector('xpath/h2');
|
||||
```
|
||||
|
||||
### ARIA selectors (`aria/`)
|
||||
|
||||
ARIA selectors can be used to find elements with a given ARIA label. These labels are computed using Chrome's internal representation.
|
||||
|
||||
#### Example
|
||||
|
||||
```ts
|
||||
const node = await page.waitForSelector('aria/Button name');
|
||||
```
|
||||
|
||||
### Pierce selectors (`pierce/`)
|
||||
|
||||
Pierce selectors will run the `querySelector*` API on the document and all shadow roots to find an element.
|
||||
|
||||
:::danger
|
||||
|
||||
Selectors will **not** _partially_ pierce through shadow roots. See the examples below.
|
||||
|
||||
:::
|
||||
|
||||
#### Example
|
||||
|
||||
Suppose the HTML is
|
||||
|
||||
```html
|
||||
<div>
|
||||
<custom-element>
|
||||
<div></div>
|
||||
</custom-element>
|
||||
</div>
|
||||
```
|
||||
|
||||
Then
|
||||
|
||||
```ts
|
||||
// This will be two elements because of the outer and inner div.
|
||||
expect((await page.$$('pierce/div')).length).toBe(2);
|
||||
|
||||
// Partial piercing doesn't work.
|
||||
expect((await page.$$('pierce/div div')).length).toBe(0);
|
||||
```
|
||||
|
||||
## Custom selectors
|
||||
|
||||
Puppeteer provides users the ability to add their own query selectors to Puppeteer using [Puppeteer.registerCustomQueryHandler](../api/puppeteer.registercustomqueryhandler.md). This is useful for creating custom selectors based on framework objects or other vendor-specific objects.
|
@ -1,213 +0,0 @@
|
||||
# Query Selectors
|
||||
|
||||
Queries are the primary mechanism for interacting with the DOM on your site. For example, a typical workflow goes like:
|
||||
|
||||
```ts
|
||||
// Import puppeteer
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
(async () => {
|
||||
// Launch the browser
|
||||
const browser = await puppeteer.launch();
|
||||
|
||||
// Create a page
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Go to your site
|
||||
await page.goto('YOUR_SITE');
|
||||
|
||||
// Query for an element handle.
|
||||
const element = await page.waitForSelector('div > .class-name');
|
||||
|
||||
// Do something with element...
|
||||
await element.click(); // Just an example.
|
||||
|
||||
// Dispose of handle
|
||||
await element.dispose();
|
||||
|
||||
// Close browser.
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
## `P` Selectors
|
||||
|
||||
Puppeteer uses a superset of the CSS selector syntax for querying. We call this syntax _P selectors_ and it's supercharged with extra capabilities such as deep combinators and text selection.
|
||||
|
||||
:::caution
|
||||
|
||||
Although P selectors look like real CSS selectors (we intentionally designed it this way), they should not be used for actually CSS styling. They are designed only for Puppeteer.
|
||||
|
||||
:::
|
||||
|
||||
:::note
|
||||
|
||||
P selectors only work on the first "depth" of selectors; for example, `:is(div >>> a)` will not work.
|
||||
|
||||
:::
|
||||
|
||||
### `>>>` and `>>>>` combinators
|
||||
|
||||
The `>>>` and `>>>>` are called _deep descendent_ and _deep_ combinators respectively. Both combinators have the effect of going into shadow hosts with `>>>` going into every shadow host under a node and `>>>>` going into the immediate one (if the node is a shadow host; otherwise, it's a no-op).
|
||||
|
||||
:::note
|
||||
|
||||
A common question is when should `>>>>` be chosen over `>>>` considering the flexibility of `>>>`. A similar question can be asked about `>` and a space; choose `>` if you do not need to query all elements under a given node and a space otherwise. This answer extends to `>>>>` (`>`) and `>>>` (space) naturally.
|
||||
|
||||
:::
|
||||
|
||||
#### Example
|
||||
|
||||
Suppose we have the markup
|
||||
|
||||
```html
|
||||
<custom-element>
|
||||
<template shadowrootmode="open">
|
||||
<slot></slot>
|
||||
</template>
|
||||
<custom-element>
|
||||
<template shadowrootmode="open">
|
||||
<slot></slot>
|
||||
</template>
|
||||
<custom-element>
|
||||
<template shadowrootmode="open">
|
||||
<slot></slot>
|
||||
</template>
|
||||
<h2>Light content</h2>
|
||||
</custom-element>
|
||||
</custom-element>
|
||||
</custom-element>
|
||||
```
|
||||
|
||||
> Note: `<template shadowrootmode="open">` is not supported on Firefox.
|
||||
> You can read more about it [here](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template#attributes).
|
||||
|
||||
Then `custom-element >>> h2` will return `h2`, but `custom-element >>>> h2` will return nothing since the inner `h2` is in a deeper shadow root.
|
||||
|
||||
### `P`-elements
|
||||
|
||||
`P` elements are [pseudo-elements](https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements) with a `-p` vendor prefix. It allows you to enhance your selectors with Puppeteer-specific query engines such as XPath, text queries, and ARIA.
|
||||
|
||||
#### Text selectors (`-p-text`)
|
||||
|
||||
Text selectors will select "minimal" elements containing the given text, even within (open) shadow roots. Here, "minimum" means the deepest elements that contain a given text, but not their parents (which technically will also contain the given text).
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const element = await page.waitForSelector('div ::-p-text(My name is Jun)');
|
||||
// You can also use escapes.
|
||||
const element = await page.waitForSelector(
|
||||
':scope >>> ::-p-text(My name is Jun \\(pronounced like "June"\\))'
|
||||
);
|
||||
// or quotes
|
||||
const element = await page.waitForSelector(
|
||||
'div >>>> ::-p-text("My name is Jun (pronounced like \\"June\\")"):hover'
|
||||
);
|
||||
```
|
||||
|
||||
#### XPath selectors (`-p-xpath`)
|
||||
|
||||
XPath selectors will use the browser's native [`Document.evaluate`](https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate) to query for elements.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const element = await page.waitForSelector('::-p-xpath(h2)');
|
||||
```
|
||||
|
||||
#### ARIA selectors (`-p-aria`)
|
||||
|
||||
ARIA selectors can be used to find elements with a given ARIA label. These labels are computed using Chrome's internal representation.
|
||||
|
||||
##### Example
|
||||
|
||||
```ts
|
||||
const node = await page.waitForSelector('::-p-aria(Submit)');
|
||||
const node = await page.waitForSelector(
|
||||
'::-p-aria([name="Click me"][role="button"])'
|
||||
);
|
||||
```
|
||||
|
||||
### Custom selectors
|
||||
|
||||
Puppeteer provides users the ability to add their own query selectors to Puppeteer using [Puppeteer.registerCustomQueryHandler](../api/puppeteer.registercustomqueryhandler.md). This is useful for creating custom selectors based on framework objects or other vendor-specific objects.
|
||||
|
||||
#### Custom Selectors
|
||||
|
||||
You can register a custom query handler that allows you to create custom selectors. For example, define a query handler for `getById` selectors:
|
||||
|
||||
```ts
|
||||
Puppeteer.registerCustomQueryHandler('getById', {
|
||||
queryOne: (elementOrDocument, selector) => {
|
||||
return elementOrDocument.querySelector(`[id="${CSS.escape(selector)}"]`);
|
||||
},
|
||||
// Note: for demonstation perpose only `id` should be page unique
|
||||
queryAll: (elementOrDocument, selector) => {
|
||||
return elementOrDocument.querySelectorAll(`[id="${CSS.escape(selector)}"]`);
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
You can now use it as following:
|
||||
|
||||
```ts
|
||||
const node = await page.waitForSelector('::-p-getById(elementId)');
|
||||
// OR used in conjunction with other selectors
|
||||
const moreSpecificNode = await page.waitForSelector(
|
||||
'.side-bar ::-p-getById(elementId)'
|
||||
);
|
||||
```
|
||||
|
||||
#### Custom framework components selector
|
||||
|
||||
:::caution
|
||||
|
||||
Be careful when relying on internal APIs of libraries or frameworks. They can change at any time.
|
||||
|
||||
:::
|
||||
|
||||
Find Vue components by name by using Vue internals for querying:
|
||||
|
||||
```ts
|
||||
Puppeteer.registerCustomQueryHandler('vue', {
|
||||
queryOne: (element, name) => {
|
||||
const walker = document.createTreeWalker(element, NodeFilter.SHOW_ELEMENT);
|
||||
do {
|
||||
const currentNode = walker.currentNode;
|
||||
if (
|
||||
currentNode.__vnode?.ctx?.type?.name.toLowerCase() ===
|
||||
name.toLocaleLowerCase()
|
||||
) {
|
||||
return currentNode;
|
||||
}
|
||||
} while (walker.nextNode());
|
||||
|
||||
return null;
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
Query the Vue component as following:
|
||||
|
||||
```ts
|
||||
const element = await page.$('::-p-vue(MyComponent)');
|
||||
```
|
||||
|
||||
#### Web Components
|
||||
|
||||
Web Components create their own tag so you can query them by the tag name:
|
||||
|
||||
```ts
|
||||
const element = await page.$('my-web-component');
|
||||
```
|
||||
|
||||
Extend `HTMLElementTagNameMap` to define types for custom tags. This allows Puppeteer to infer the return type for the ElementHandle:
|
||||
|
||||
```ts
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'my-web-component': MyWebComponent;
|
||||
}
|
||||
}
|
||||
```
|
28
docs/guides/screenshots.md
Normal file
28
docs/guides/screenshots.md
Normal file
@ -0,0 +1,28 @@
|
||||
# Screenshots
|
||||
|
||||
For capturing screenshots use [`Page.screenshot()`](https://pptr.dev/api/puppeteer.screenshot.pdf).
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
await page.goto('https://news.ycombinator.com', {
|
||||
waitUntil: 'networkidle2',
|
||||
});
|
||||
await page.screenshot({
|
||||
path: 'hn.pdf',
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
```
|
||||
|
||||
You can also capture a screenshot of a specific element using [`ElementHandle.screenshot()`](https://pptr.dev/api/puppeteer.elementhandle.screenshot):
|
||||
|
||||
```ts
|
||||
const fileElement = await page.waitForSelector('div');
|
||||
await fileElement.screenshot({
|
||||
path: 'div.png',
|
||||
});
|
||||
```
|
||||
|
||||
By default, [`ElementHandle.screenshot()`](https://pptr.dev/api/puppeteer.elementhandle.screenshot) tries to scroll the element into view
|
||||
if it is hidden.
|
14
docs/guides/system-requirements.md
Normal file
14
docs/guides/system-requirements.md
Normal file
@ -0,0 +1,14 @@
|
||||
# System requirements
|
||||
|
||||
- Node 18+. Puppeteer follows the latest
|
||||
[maintenance LTS](https://github.com/nodejs/Release#release-schedule) version of
|
||||
Node
|
||||
|
||||
- TypeScript 4.7.4+ (If used with TypeScript)
|
||||
|
||||
- Operating systems:
|
||||
|
||||
- Windows, x64 architecture
|
||||
- MacOS, x64 and arm64 architectures
|
||||
- Debian/Ubuntu Linux, with x64 arhicture
|
||||
- Required system packages https://source.chromium.org/chromium/chromium/src/+/main:chrome/installer/linux/debian/dist_package_versions.json
|
25
docs/guides/what-is-puppeteer.md
Normal file
25
docs/guides/what-is-puppeteer.md
Normal file
@ -0,0 +1,25 @@
|
||||
# What is Puppeteer?
|
||||
|
||||
Puppeteer is a Node.js library which provides a high-level API to control
|
||||
Chrome/Chromium over the
|
||||
[DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/).
|
||||
Puppeteer runs in
|
||||
[headless](https://developer.chrome.com/docs/chromium/new-headless/)
|
||||
mode by default, but can be configured to run in full ("headful")
|
||||
Chrome/Chromium.
|
||||
|
||||
# Features
|
||||
|
||||
Most things that you can do manually in the browser can be done using Puppeteer!
|
||||
Here are a few examples to get you started:
|
||||
|
||||
- Automate form submission, UI testing, keyboard input, etc.
|
||||
- Create an automated testing environment using the latest JavaScript and
|
||||
browser features.
|
||||
- Capture a
|
||||
[timeline trace](https://developer.chrome.com/docs/devtools/performance/reference)
|
||||
of your site to help diagnose performance issues.
|
||||
- [Test Chrome Extensions](https://pptr.dev/guides/chrome-extensions).
|
||||
- Generate screenshots and PDFs of pages.
|
||||
- Crawl a SPA (Single-Page Application) and generate pre-rendered content (i.e.
|
||||
"SSR" (Server-Side Rendering)).
|
261
docs/index.md
261
docs/index.md
@ -1,261 +0,0 @@
|
||||
# Puppeteer
|
||||
|
||||
[![build](https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/puppeteer/puppeteer/actions/workflows/ci.yml)
|
||||
[![npm puppeteer package](https://img.shields.io/npm/v/puppeteer.svg)](https://npmjs.org/package/puppeteer)
|
||||
|
||||
<img src="https://user-images.githubusercontent.com/10379601/29446482-04f7036a-841f-11e7-9872-91d1fc2ea683.png" height="200" align="right"/>
|
||||
|
||||
#### [Guides](https://pptr.dev/category/guides) | [API](https://pptr.dev/api) | [FAQ](https://pptr.dev/faq) | [Contributing](https://pptr.dev/contributing) | [Troubleshooting](https://pptr.dev/troubleshooting)
|
||||
|
||||
> Puppeteer is a Node.js library which provides a high-level API to control
|
||||
> Chrome/Chromium over the
|
||||
> [DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/).
|
||||
> Puppeteer runs in
|
||||
> [headless](https://developer.chrome.com/docs/chromium/new-headless/)
|
||||
> mode by default, but can be configured to run in full ("headful")
|
||||
> Chrome/Chromium.
|
||||
|
||||
#### What can I do?
|
||||
|
||||
Most things that you can do manually in the browser can be done using Puppeteer!
|
||||
Here are a few examples to get you started:
|
||||
|
||||
- Generate screenshots and PDFs of pages.
|
||||
- Crawl a SPA (Single-Page Application) and generate pre-rendered content (i.e.
|
||||
"SSR" (Server-Side Rendering)).
|
||||
- Automate form submission, UI testing, keyboard input, etc.
|
||||
- Create an automated testing environment using the latest JavaScript and
|
||||
browser features.
|
||||
- Capture a
|
||||
[timeline trace](https://developer.chrome.com/docs/devtools/performance/reference)
|
||||
of your site to help diagnose performance issues.
|
||||
- [Test Chrome Extensions](https://pptr.dev/guides/chrome-extensions).
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
To use Puppeteer in your project, run:
|
||||
|
||||
```bash
|
||||
npm i puppeteer
|
||||
# or using yarn
|
||||
yarn add puppeteer
|
||||
# or using pnpm
|
||||
pnpm i puppeteer
|
||||
```
|
||||
|
||||
When you install Puppeteer, it automatically downloads a recent version of
|
||||
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing/) (~170MB macOS, ~282MB Linux, ~280MB Windows) and a `chrome-headless-shell` binary (starting with Puppeteer v21.6.0) that is [guaranteed to
|
||||
work](https://pptr.dev/faq#q-why-doesnt-puppeteer-vxxx-work-with-chromium-vyyy)
|
||||
with Puppeteer. The browser is downloaded to the `$HOME/.cache/puppeteer` folder
|
||||
by default (starting with Puppeteer v19.0.0). See [configuration](https://pptr.dev/api/puppeteer.configuration) for configuration options and environmental variables to control the download behavior.
|
||||
|
||||
If you deploy a project using Puppeteer to a hosting provider, such as Render or
|
||||
Heroku, you might need to reconfigure the location of the cache to be within
|
||||
your project folder (see an example below) because not all hosting providers
|
||||
include `$HOME/.cache` into the project's deployment.
|
||||
|
||||
For a version of Puppeteer without the browser installation, see
|
||||
[`puppeteer-core`](#puppeteer-core).
|
||||
|
||||
If used with TypeScript, the minimum supported TypeScript version is `4.7.4`.
|
||||
|
||||
#### Configuration
|
||||
|
||||
Puppeteer uses several defaults that can be customized through configuration
|
||||
files.
|
||||
|
||||
For example, to change the default cache directory Puppeteer uses to install
|
||||
browsers, you can add a `.puppeteerrc.cjs` (or `puppeteer.config.cjs`) at the
|
||||
root of your application with the contents
|
||||
|
||||
```js
|
||||
const {join} = require('path');
|
||||
|
||||
/**
|
||||
* @type {import("puppeteer").Configuration}
|
||||
*/
|
||||
module.exports = {
|
||||
// Changes the cache location for Puppeteer.
|
||||
cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
|
||||
};
|
||||
```
|
||||
|
||||
After adding the configuration file, you will need to remove and reinstall
|
||||
`puppeteer` for it to take effect.
|
||||
|
||||
See the [configuration guide](https://pptr.dev/guides/configuration) for more
|
||||
information.
|
||||
|
||||
#### `puppeteer-core`
|
||||
|
||||
For every release since v1.7.0 we publish two packages:
|
||||
|
||||
- [`puppeteer`](https://www.npmjs.com/package/puppeteer)
|
||||
- [`puppeteer-core`](https://www.npmjs.com/package/puppeteer-core)
|
||||
|
||||
`puppeteer` is a _product_ for browser automation. When installed, it downloads
|
||||
a version of Chrome, which it then drives using `puppeteer-core`. Being an
|
||||
end-user product, `puppeteer` automates several workflows using reasonable
|
||||
defaults [that can be customized](https://pptr.dev/guides/configuration).
|
||||
|
||||
`puppeteer-core` is a _library_ to help drive anything that supports DevTools
|
||||
protocol. Being a library, `puppeteer-core` is fully driven through its
|
||||
programmatic interface implying no defaults are assumed and `puppeteer-core`
|
||||
will not download Chrome when installed.
|
||||
|
||||
You should use `puppeteer-core` if you are
|
||||
[connecting to a remote browser](https://pptr.dev/api/puppeteer.puppeteer.connect)
|
||||
or [managing browsers yourself](https://pptr.dev/browsers-api/).
|
||||
If you are managing browsers yourself, you will need to call
|
||||
[`puppeteer.launch`](https://pptr.dev/api/puppeteer.puppeteernode.launch) with
|
||||
an explicit
|
||||
[`executablePath`](https://pptr.dev/api/puppeteer.launchoptions)
|
||||
(or [`channel`](https://pptr.dev/api/puppeteer.launchoptions) if it's
|
||||
installed in a standard location).
|
||||
|
||||
When using `puppeteer-core`, remember to change the import:
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer-core';
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Puppeteer follows the latest
|
||||
[maintenance LTS](https://github.com/nodejs/Release#release-schedule) version of
|
||||
Node.
|
||||
|
||||
Puppeteer will be familiar to people using other browser testing frameworks. You
|
||||
[launch](https://pptr.dev/api/puppeteer.puppeteernode.launch)/[connect](https://pptr.dev/api/puppeteer.puppeteernode.connect)
|
||||
a [browser](https://pptr.dev/api/puppeteer.browser),
|
||||
[create](https://pptr.dev/api/puppeteer.browser.newpage) some
|
||||
[pages](https://pptr.dev/api/puppeteer.page), and then manipulate them with
|
||||
[Puppeteer's API](https://pptr.dev/api).
|
||||
|
||||
For more in-depth usage, check our [guides](https://pptr.dev/category/guides)
|
||||
and [examples](https://github.com/puppeteer/puppeteer/tree/main/examples).
|
||||
|
||||
#### Example
|
||||
|
||||
The following example searches [developer.chrome.com](https://developer.chrome.com/) for blog posts with text "automate beyond recorder", click on the first result and print the full title of the blog post.
|
||||
|
||||
```ts
|
||||
import puppeteer from 'puppeteer';
|
||||
|
||||
(async () => {
|
||||
// Launch the browser and open a new blank page
|
||||
const browser = await puppeteer.launch();
|
||||
const page = await browser.newPage();
|
||||
|
||||
// Navigate the page to a URL
|
||||
await page.goto('https://developer.chrome.com/');
|
||||
|
||||
// Set screen size
|
||||
await page.setViewport({width: 1080, height: 1024});
|
||||
|
||||
// Type into search box
|
||||
await page.type('.devsite-search-field', 'automate beyond recorder');
|
||||
|
||||
// Wait and click on first result
|
||||
const searchResultSelector = '.devsite-result-item-link';
|
||||
await page.waitForSelector(searchResultSelector);
|
||||
await page.click(searchResultSelector);
|
||||
|
||||
// Locate the full title with a unique string
|
||||
const textSelector = await page.waitForSelector(
|
||||
'text/Customize and automate'
|
||||
);
|
||||
const fullTitle = await textSelector?.evaluate(el => el.textContent);
|
||||
|
||||
// Print the full title
|
||||
console.log('The title of this blog post is "%s".', fullTitle);
|
||||
|
||||
await browser.close();
|
||||
})();
|
||||
```
|
||||
|
||||
### Default runtime settings
|
||||
|
||||
**1. Uses Headless mode**
|
||||
|
||||
By default Puppeteer launches Chrome in
|
||||
[the Headless mode](https://developer.chrome.com/docs/chromium/new-headless/).
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch();
|
||||
// Equivalent to
|
||||
const browser = await puppeteer.launch({headless: true});
|
||||
```
|
||||
|
||||
Before v22, Puppeteer launched the [old Headless mode](https://developer.chrome.com/docs/chromium/new-headless/) by default.
|
||||
The old headless mode is now known as
|
||||
[`chrome-headless-shell`](https://developer.chrome.com/blog/chrome-headless-shell)
|
||||
and ships as a separate binary. `chrome-headless-shell` does not match the
|
||||
behavior of the regular Chrome completely but it is currently more performant
|
||||
for automation tasks where the complete Chrome feature set is not needed. If the performance
|
||||
is more important for your use case, switch to `chrome-headless-shell` as following:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({headless: 'shell'});
|
||||
```
|
||||
|
||||
To launch a "headful" version of Chrome, set the
|
||||
[`headless`](https://pptr.dev/api/puppeteer.browserlaunchargumentoptions) to `false`
|
||||
option when launching a browser:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({headless: false});
|
||||
```
|
||||
|
||||
**2. Runs a bundled version of Chrome**
|
||||
|
||||
By default, Puppeteer downloads and uses a specific version of Chrome so its
|
||||
API is guaranteed to work out of the box. To use Puppeteer with a different
|
||||
version of Chrome or Chromium, pass in the executable's path when creating a
|
||||
`Browser` instance:
|
||||
|
||||
```ts
|
||||
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
|
||||
```
|
||||
|
||||
You can also use Puppeteer with Firefox. See
|
||||
[status of cross-browser support](https://pptr.dev/faq#q-what-is-the-status-of-cross-browser-support) for
|
||||
more information.
|
||||
|
||||
See
|
||||
[`this article`](https://www.howtogeek.com/202825/what%E2%80%99s-the-difference-between-chromium-and-chrome/)
|
||||
for a description of the differences between Chromium and Chrome.
|
||||
[`This article`](https://chromium.googlesource.com/chromium/src/+/refs/heads/main/docs/chromium_browser_vs_google_chrome.md)
|
||||
describes some differences for Linux users.
|
||||
|
||||
**3. Creates a fresh user profile**
|
||||
|
||||
Puppeteer creates its own browser user profile which it **cleans up on every
|
||||
run**.
|
||||
|
||||
#### Using Docker
|
||||
|
||||
See our [Docker guide](https://pptr.dev/guides/docker).
|
||||
|
||||
#### Using Chrome Extensions
|
||||
|
||||
See our [Chrome extensions guide](https://pptr.dev/guides/chrome-extensions).
|
||||
|
||||
## Resources
|
||||
|
||||
- [API Documentation](https://pptr.dev/api)
|
||||
- [Guides](https://pptr.dev/category/guides)
|
||||
- [Examples](https://github.com/puppeteer/puppeteer/tree/main/examples)
|
||||
- [Community list of Puppeteer resources](https://github.com/transitive-bullshit/awesome-puppeteer)
|
||||
|
||||
## Contributing
|
||||
|
||||
Check out our [contributing guide](https://pptr.dev/contributing) to get an
|
||||
overview of Puppeteer development.
|
||||
|
||||
## FAQ
|
||||
|
||||
Our [FAQ](https://pptr.dev/faq) has migrated to
|
||||
[our site](https://pptr.dev/faq).
|
@ -83,6 +83,22 @@ const config = {
|
||||
from: '/guides',
|
||||
to: '/category/guides',
|
||||
},
|
||||
{
|
||||
from: '/guides/query-selectors',
|
||||
to: '/guides/page-interactions',
|
||||
},
|
||||
{
|
||||
from: '/guides/query-selectors-legacy',
|
||||
to: '/guides/page-interactions',
|
||||
},
|
||||
{
|
||||
from: '/guides/locators',
|
||||
to: '/guides/page-interactions',
|
||||
},
|
||||
{
|
||||
from: '/guides/evaluate-javascript',
|
||||
to: '/guides/javascript-execution',
|
||||
},
|
||||
{
|
||||
from: '/chromium-support',
|
||||
to: '/supported-browsers',
|
||||
@ -260,8 +276,8 @@ const config = {
|
||||
items: [
|
||||
...[
|
||||
{
|
||||
type: 'doc',
|
||||
docId: 'index',
|
||||
type: 'docSidebar',
|
||||
sidebarId: 'docs',
|
||||
label: 'Docs',
|
||||
},
|
||||
{
|
||||
|
@ -6,25 +6,54 @@
|
||||
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
|
||||
module.exports = {
|
||||
docs: [
|
||||
'index',
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Introduction',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Introduction',
|
||||
keywords: ['introduction'],
|
||||
},
|
||||
items: [
|
||||
'guides/what-is-puppeteer',
|
||||
'guides/installation',
|
||||
'guides/getting-started',
|
||||
'guides/system-requirements',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Core concepts',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Core concepts',
|
||||
keywords: ['core-concepts'],
|
||||
},
|
||||
items: [
|
||||
'guides/browser-management',
|
||||
'guides/page-interactions',
|
||||
'guides/javascript-execution',
|
||||
'guides/network-logging',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Puppeteer Guides',
|
||||
title: 'Guides',
|
||||
keywords: ['guides'],
|
||||
},
|
||||
collapsed: false,
|
||||
items: [
|
||||
'guides/configuration',
|
||||
'guides/query-selectors',
|
||||
'guides/locators',
|
||||
'guides/evaluate-javascript',
|
||||
'guides/docker',
|
||||
'guides/request-interception',
|
||||
'guides/chrome-extensions',
|
||||
'guides/debugging',
|
||||
'guides/network-interception',
|
||||
'guides/headless-modes',
|
||||
'guides/screenshots',
|
||||
'guides/pdf-generation',
|
||||
'guides/chrome-extensions',
|
||||
'guides/cookies',
|
||||
'guides/files',
|
||||
],
|
||||
},
|
||||
{
|
||||
@ -35,19 +64,31 @@ module.exports = {
|
||||
title: 'Puppeteer Integrations',
|
||||
keywords: ['integrations'],
|
||||
},
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
type: 'doc',
|
||||
label: 'Angular Schematics',
|
||||
id: 'integrations/ng-schematics',
|
||||
label: 'Angular',
|
||||
id: 'guides/ng-schematics',
|
||||
},
|
||||
{
|
||||
type: 'doc',
|
||||
label: 'Docker',
|
||||
id: 'guides/docker',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Community',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Community',
|
||||
keywords: ['community'],
|
||||
},
|
||||
items: ['contributing', 'troubleshooting', 'guides/links'],
|
||||
},
|
||||
'webdriver-bidi',
|
||||
'supported-browsers',
|
||||
'troubleshooting',
|
||||
'contributing',
|
||||
'faq',
|
||||
],
|
||||
api: [
|
||||
|
Loading…
Reference in New Issue
Block a user