docs: restructure documentation guides (#12236)

This commit is contained in:
Alex Rudenko 2024-04-11 11:08:28 +02:00 committed by GitHub
parent a2f3415df2
commit 964d99efb9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 936 additions and 997 deletions

View File

@ -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
View File

@ -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).

View 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.
:::

View File

@ -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
View 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
View 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']);
```

View 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).

View 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});
```

View 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';
```

View File

@ -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
View 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)

View File

@ -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.

View 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());
});
```

View 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.

View 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.

View File

@ -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.

View File

@ -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;
}
}
```

View 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.

View 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

View 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)).

View File

@ -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).

View File

@ -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',
},
{

View File

@ -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: [