summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer
diff options
context:
space:
mode:
Diffstat (limited to 'remote/test/puppeteer')
-rw-r--r--remote/test/puppeteer/.release-please-manifest.json6
-rw-r--r--remote/test/puppeteer/.vscode/launch.template.json46
-rw-r--r--remote/test/puppeteer/Herebyfile.mjs33
-rw-r--r--remote/test/puppeteer/README.md216
-rw-r--r--remote/test/puppeteer/examples/README.md14
-rw-r--r--remote/test/puppeteer/moz.yaml4
-rw-r--r--remote/test/puppeteer/package-lock.json1126
-rw-r--r--remote/test/puppeteer/package.json16
-rw-r--r--remote/test/puppeteer/packages/browsers/CHANGELOG.md27
-rw-r--r--remote/test/puppeteer/packages/browsers/README.md24
-rw-r--r--remote/test/puppeteer/packages/browsers/package.json2
-rw-r--r--remote/test/puppeteer/packages/browsers/src/CLI.ts28
-rw-r--r--remote/test/puppeteer/packages/browsers/src/browser-data/browser-data.ts111
-rw-r--r--remote/test/puppeteer/packages/browsers/src/browser-data/firefox.ts132
-rw-r--r--remote/test/puppeteer/packages/browsers/src/browser-data/types.ts3
-rw-r--r--remote/test/puppeteer/packages/browsers/src/fileUtil.ts14
-rw-r--r--remote/test/puppeteer/packages/browsers/src/httpUtil.ts3
-rw-r--r--remote/test/puppeteer/packages/browsers/src/install.ts9
-rw-r--r--remote/test/puppeteer/packages/browsers/src/launch.ts69
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts2
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts1
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chromium/launch.spec.ts1
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/firefox/firefox-data.spec.ts71
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/versions.ts2
-rw-r--r--remote/test/puppeteer/packages/ng-schematics/.eslintignore2
-rw-r--r--remote/test/puppeteer/packages/ng-schematics/README.md2
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/CHANGELOG.md98
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/Herebyfile.mjs6
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/package.json9
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/Browser.ts2
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/BrowserContext.ts2
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/CDPSession.ts2
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/ElementHandle.ts22
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/Frame.ts143
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPRequest.ts226
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPResponse.ts9
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/Page.ts29
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/api/locators/locators.ts23
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/BidiOverCdp.ts4
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/Browser.ts7
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/CDPSession.ts18
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/Connection.ts5
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/Frame.ts34
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPRequest.ts236
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPResponse.ts6
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/Page.ts136
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Browser.ts17
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/BrowsingContext.ts48
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Connection.ts25
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Navigation.ts24
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Realm.ts32
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Request.ts90
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Session.ts30
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserContext.ts10
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserPrompt.ts7
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/AriaQueryHandler.ts11
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts93
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/BrowserContext.ts104
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts13
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/FrameTree.ts6
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts217
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts21
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts18
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/common/CallbackRegistry.ts15
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/common/Configuration.ts2
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/common/Errors.ts4
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/common/PDFOptions.ts2
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/common/util.ts4
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/node/ChromeLauncher.ts25
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/node/NodeWebSocketTransport.ts16
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/node/ProductLauncher.ts6
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/node/PuppeteerNode.ts6
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/revisions.ts4
-rw-r--r--remote/test/puppeteer/packages/puppeteer-core/src/util/Function.ts2
-rw-r--r--remote/test/puppeteer/packages/puppeteer/CHANGELOG.md115
-rw-r--r--remote/test/puppeteer/packages/puppeteer/package.json7
-rw-r--r--remote/test/puppeteer/packages/puppeteer/src/getConfiguration.ts11
-rw-r--r--remote/test/puppeteer/test/.eslintrc.js6
-rw-r--r--remote/test/puppeteer/test/TestExpectations.json887
-rw-r--r--remote/test/puppeteer/test/TestSuites.json2
-rw-r--r--remote/test/puppeteer/test/golden-chrome/screenshot-element-clip.pngbin0 -> 104 bytes
-rw-r--r--remote/test/puppeteer/test/golden-firefox/screenshot-element-clip.pngbin0 -> 104 bytes
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js6
-rw-r--r--remote/test/puppeteer/test/installation/package.json4
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts35
-rw-r--r--remote/test/puppeteer/test/src/ariaqueryhandler.spec.ts11
-rw-r--r--remote/test/puppeteer/test/src/browser.spec.ts19
-rw-r--r--remote/test/puppeteer/test/src/cdp/CDPSession.spec.ts2
-rw-r--r--remote/test/puppeteer/test/src/cdp/devtools.spec.ts7
-rw-r--r--remote/test/puppeteer/test/src/elementhandle.spec.ts22
-rw-r--r--remote/test/puppeteer/test/src/frame.spec.ts51
-rw-r--r--remote/test/puppeteer/test/src/jshandle.spec.ts10
-rw-r--r--remote/test/puppeteer/test/src/keyboard.spec.ts11
-rw-r--r--remote/test/puppeteer/test/src/launcher.spec.ts44
-rw-r--r--remote/test/puppeteer/test/src/navigation.spec.ts21
-rw-r--r--remote/test/puppeteer/test/src/network.spec.ts4
-rw-r--r--remote/test/puppeteer/test/src/page.spec.ts21
-rw-r--r--remote/test/puppeteer/test/src/requestinterception-experimental.spec.ts93
-rw-r--r--remote/test/puppeteer/test/src/requestinterception.spec.ts61
-rw-r--r--remote/test/puppeteer/test/src/screenshot.spec.ts27
-rw-r--r--remote/test/puppeteer/test/src/utils.ts17
-rwxr-xr-xremote/test/puppeteer/tools/analyze_issue.mjs12
-rw-r--r--remote/test/puppeteer/tools/docgen/package.json8
-rw-r--r--remote/test/puppeteer/tools/docgen/src/custom_markdown_documenter.ts306
-rw-r--r--remote/test/puppeteer/tools/doctest/package.json4
-rw-r--r--remote/test/puppeteer/tools/eslint/package.json2
-rw-r--r--remote/test/puppeteer/tools/mocha-runner/package.json2
-rw-r--r--remote/test/puppeteer/tools/sort-test-expectations.mjs12
-rw-r--r--remote/test/puppeteer/tools/update_chrome_revision.mjs6
-rw-r--r--remote/test/puppeteer/versions.js8
110 files changed, 3611 insertions, 2076 deletions
diff --git a/remote/test/puppeteer/.release-please-manifest.json b/remote/test/puppeteer/.release-please-manifest.json
index a3ccb1a4ae..85dc75087e 100644
--- a/remote/test/puppeteer/.release-please-manifest.json
+++ b/remote/test/puppeteer/.release-please-manifest.json
@@ -1,7 +1,7 @@
{
- "packages/puppeteer": "22.4.0",
- "packages/puppeteer-core": "22.4.0",
+ "packages/puppeteer": "22.6.5",
+ "packages/puppeteer-core": "22.6.5",
"packages/testserver": "0.6.0",
"packages/ng-schematics": "0.6.0",
- "packages/browsers": "2.1.0"
+ "packages/browsers": "2.2.2"
}
diff --git a/remote/test/puppeteer/.vscode/launch.template.json b/remote/test/puppeteer/.vscode/launch.template.json
new file mode 100644
index 0000000000..51870281bd
--- /dev/null
+++ b/remote/test/puppeteer/.vscode/launch.template.json
@@ -0,0 +1,46 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "inputs": [
+ {
+ "type": "pickString",
+ "id": "suit",
+ "description": "Which test suit to run?",
+ "options": [
+ "chrome-headless",
+ "chrome-headful",
+ "chrome-headless-shell",
+ "firefox-headless",
+ "firefox-headful",
+ "firefox-bidi",
+ "chrome-bidi"
+ ],
+ "default": "chrome-headless"
+ }
+ ],
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Launch Tests",
+ "skipFiles": ["<node_internals>/**"],
+ "runtimeExecutable": "npm",
+ "cwd": "${workspaceFolder}",
+ "runtimeArgs": [
+ "run-script",
+ "test",
+ "--",
+ "--test-suite",
+ "${input:suit}",
+ "--no-coverage",
+ "--no-suggestions"
+ ],
+ "outFiles": ["${workspaceFolder}/**/*.js"],
+ "env": {
+ "DEBUGGER_ATTACHED": true
+ }
+ }
+ ]
+}
diff --git a/remote/test/puppeteer/Herebyfile.mjs b/remote/test/puppeteer/Herebyfile.mjs
index 30f9c75262..7b1e27958f 100644
--- a/remote/test/puppeteer/Herebyfile.mjs
+++ b/remote/test/puppeteer/Herebyfile.mjs
@@ -6,20 +6,20 @@
/* 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';
import {task} from 'hereby';
import semver from 'semver';
-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);
- },
-});
+function addNoTocHeader(markdown) {
+ return `---
+hide_table_of_contents: true
+---
+
+${markdown}`;
+}
/**
* This logic should match the one in `website/docusaurus.config.js`.
@@ -34,10 +34,18 @@ function getApiUrl(version) {
}
}
+export const docsNgSchematicsTask = task({
+ name: 'docs:ng-schematics',
+ run: async () => {
+ const readme = await readFile('packages/ng-schematics/README.md', 'utf-8');
+ await writeFile('docs/guides/ng-schematics.md', readme);
+ },
+});
+
export const docsChromiumSupportTask = task({
- name: 'docs:chromium-support',
+ name: 'docs:supported-browsers',
run: async () => {
- const content = await readFile('docs/chromium-support.md', {
+ const content = await readFile('docs/supported-browsers.md', {
encoding: 'utf8',
});
const {versionsPerRelease} = await import('./versions.js');
@@ -61,7 +69,7 @@ export const docsChromiumSupportTask = task({
}
}
await writeFile(
- 'docs/chromium-support.md',
+ 'docs/supported-browsers.md',
spliceIntoSection('version', content, buffer.join('\n'))
);
},
@@ -72,7 +80,8 @@ export const docsTask = task({
dependencies: [docsNgSchematicsTask, docsChromiumSupportTask],
run: async () => {
// Copy main page.
- await copyFile('README.md', 'docs/index.md');
+ const mainPage = await readFile('README.md', 'utf-8');
+ await writeFile('docs/index.md', addNoTocHeader(mainPage));
// Generate documentation
for (const [name, folder] of [
diff --git a/remote/test/puppeteer/README.md b/remote/test/puppeteer/README.md
index 288a5b623c..6078b23c2c 100644
--- a/remote/test/puppeteer/README.md
+++ b/remote/test/puppeteer/README.md
@@ -1,145 +1,21 @@
# Puppeteer
-[![Build status](https://github.com/puppeteer/puppeteer/workflows/CI/badge.svg)](https://github.com/puppeteer/puppeteer/actions?query=workflow%3ACI)
+[![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/articles/new-headless/)
+> [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://developers.google.com/web/tools/chrome-devtools/evaluate-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 behavor.
-
-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).
+## [Get started](https://pptr.dev/docs) | [API](https://pptr.dev/api) | [FAQ](https://pptr.dev/faq) | [Contributing](https://pptr.dev/contributing) | [Troubleshooting](https://pptr.dev/troubleshooting)
-#### 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';
@@ -175,87 +51,3 @@ import puppeteer from 'puppeteer';
await browser.close();
})();
```
-
-### Default runtime settings
-
-**1. Uses Headless mode**
-
-By default Puppeteer launches Chrome in
-[the Headless mode](https://developer.chrome.com/articles/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/articles/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).
diff --git a/remote/test/puppeteer/examples/README.md b/remote/test/puppeteer/examples/README.md
index 92e83eb39c..b87324b7e0 100644
--- a/remote/test/puppeteer/examples/README.md
+++ b/remote/test/puppeteer/examples/README.md
@@ -1,6 +1,18 @@
# Running the examples
-Assuming you have a checkout of the Puppeteer repo and have run `npm i` (or `yarn`) to install the dependencies, and `npm run build` (or `yarn run build`) to build the project, the examples can be run from the root folder like so:
+Assuming you have a checkout of the Puppeteer repo and install the dependencies:
+
+```bash npm2yarn
+npm install
+```
+
+Build the project:
+
+```bash npm2yarn
+npm run build
+```
+
+The examples can be run from the root folder like so:
```bash
NODE_PATH=../ node examples/search.js
diff --git a/remote/test/puppeteer/moz.yaml b/remote/test/puppeteer/moz.yaml
index 35363b67dc..9c6b0e80c3 100644
--- a/remote/test/puppeteer/moz.yaml
+++ b/remote/test/puppeteer/moz.yaml
@@ -5,6 +5,6 @@ origin:
description: Headless Chrome Node API
license: Apache-2.0
name: puppeteer
- release: puppeteer-v22.4.0
- url: ../puppeteer
+ release: puppeteer-v22.6.5
+ url: /Users/juliandescottes/Development/git/puppeteer
schema: 1
diff --git a/remote/test/puppeteer/package-lock.json b/remote/test/puppeteer/package-lock.json
index b1fb3b0189..d99df978d1 100644
--- a/remote/test/puppeteer/package-lock.json
+++ b/remote/test/puppeteer/package-lock.json
@@ -21,32 +21,32 @@
"@types/node": "20.8.4",
"@types/semver": "7.5.8",
"@types/sinon": "17.0.3",
- "@typescript-eslint/eslint-plugin": "7.1.0",
- "@typescript-eslint/parser": "7.1.0",
- "esbuild": "0.20.1",
+ "@typescript-eslint/eslint-plugin": "7.6.0",
+ "@typescript-eslint/parser": "7.6.0",
+ "esbuild": "0.20.2",
"eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-import": "2.29.1",
- "eslint-plugin-mocha": "10.3.0",
+ "eslint-plugin-mocha": "10.4.2",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-rulesdir": "0.2.2",
"eslint-plugin-tsdoc": "0.2.17",
"eslint-plugin-unused-imports": "3.1.0",
"execa": "8.0.1",
"expect": "29.7.0",
- "gts": "5.2.0",
+ "gts": "5.3.0",
"hereby": "1.8.9",
"license-checker": "25.0.1",
- "mocha": "10.3.0",
+ "mocha": "10.4.0",
"npm-run-all2": "6.1.2",
"prettier": "3.2.5",
"semver": "7.6.0",
"sinon": "17.0.1",
"source-map-support": "0.5.21",
"spdx-satisfies": "5.0.1",
- "tsd": "0.30.7",
- "tsx": "4.7.1",
+ "tsd": "0.31.0",
+ "tsx": "4.7.2",
"typescript": "5.3.3",
"wireit": "0.14.4"
}
@@ -80,6 +80,18 @@
"undici": "^5.25.4"
}
},
+ "node_modules/@actions/http-client/node_modules/undici": {
+ "version": "5.28.4",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.4.tgz",
+ "integrity": "sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==",
+ "dev": true,
+ "dependencies": {
+ "@fastify/busboy": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.0"
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.23.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
@@ -544,16 +556,16 @@
}
},
"node_modules/@microsoft/api-documenter": {
- "version": "7.23.35",
- "resolved": "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.23.35.tgz",
- "integrity": "sha512-zSHTX0abumOsfA3GsWJADFtiqxgwcoSCGSO+84e4s/SWotAqlUwXMYVJk6/huJFKSL+LG46gvcn7r8bsOd3K2Q==",
+ "version": "7.24.2",
+ "resolved": "https://registry.npmjs.org/@microsoft/api-documenter/-/api-documenter-7.24.2.tgz",
+ "integrity": "sha512-q03DXLBj7nzAzLyLRAVklBynqKgSFI/JBmrhF/mEEIpg8orNo4qKXWO1RSkD2IYrqvZV63b13mcUPYgcFdifQA==",
"dev": true,
"dependencies": {
- "@microsoft/api-extractor-model": "7.28.13",
+ "@microsoft/api-extractor-model": "7.28.14",
"@microsoft/tsdoc": "0.14.2",
- "@rushstack/node-core-library": "4.0.2",
- "@rushstack/terminal": "0.10.0",
- "@rushstack/ts-command-line": "4.19.0",
+ "@rushstack/node-core-library": "4.1.0",
+ "@rushstack/terminal": "0.10.1",
+ "@rushstack/ts-command-line": "4.19.2",
"js-yaml": "~3.13.1",
"resolve": "~1.22.1"
},
@@ -562,12 +574,12 @@
}
},
"node_modules/@microsoft/api-documenter/node_modules/@rushstack/terminal": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz",
- "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==",
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.1.tgz",
+ "integrity": "sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==",
"dev": true,
"dependencies": {
- "@rushstack/node-core-library": "4.0.2",
+ "@rushstack/node-core-library": "4.1.0",
"supports-color": "~8.1.1"
},
"peerDependencies": {
@@ -595,12 +607,12 @@
}
},
"node_modules/@microsoft/api-documenter/node_modules/@rushstack/ts-command-line": {
- "version": "4.19.0",
- "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.0.tgz",
- "integrity": "sha512-0sIHWOFGLFb6tC1zk2R0aM79ic3CF0XGzVBvhf6ytMyjDwt03DVb1qe5/5NQ0FGcvB5YyQ2WVfGsnxG6SANvHA==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.2.tgz",
+ "integrity": "sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==",
"dev": true,
"dependencies": {
- "@rushstack/terminal": "0.10.0",
+ "@rushstack/terminal": "0.10.1",
"@types/argparse": "1.0.38",
"argparse": "~1.0.9",
"string-argv": "~0.3.1"
@@ -635,47 +647,47 @@
"dev": true
},
"node_modules/@microsoft/api-extractor": {
- "version": "7.42.2",
- "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.42.2.tgz",
- "integrity": "sha512-HYiOQDO4WR+Pj4XQZZE5qK5R6e3MF6Ut5s+Hi2IkeI6MiCXkdmRugQH6ppc9YzTUiydRqZ+jshZD7UWNGSA8bg==",
+ "version": "7.43.1",
+ "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.43.1.tgz",
+ "integrity": "sha512-ohg40SsvFFgzHFAtYq5wKJc8ZDyY46bphjtnSvhSSlXpPTG7GHwyyXkn48UZiUCBwr2WC7TRC1Jfwz7nreuiyQ==",
"dev": true,
"dependencies": {
- "@microsoft/api-extractor-model": "7.28.13",
+ "@microsoft/api-extractor-model": "7.28.14",
"@microsoft/tsdoc": "0.14.2",
"@microsoft/tsdoc-config": "~0.16.1",
- "@rushstack/node-core-library": "4.0.2",
+ "@rushstack/node-core-library": "4.1.0",
"@rushstack/rig-package": "0.5.2",
- "@rushstack/terminal": "0.10.0",
- "@rushstack/ts-command-line": "4.19.0",
+ "@rushstack/terminal": "0.10.1",
+ "@rushstack/ts-command-line": "4.19.2",
"lodash": "~4.17.15",
"minimatch": "~3.0.3",
"resolve": "~1.22.1",
"semver": "~7.5.4",
"source-map": "~0.6.1",
- "typescript": "5.3.3"
+ "typescript": "5.4.2"
},
"bin": {
"api-extractor": "bin/api-extractor"
}
},
"node_modules/@microsoft/api-extractor-model": {
- "version": "7.28.13",
- "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz",
- "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==",
+ "version": "7.28.14",
+ "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.14.tgz",
+ "integrity": "sha512-Bery/c8A8SsKPSvA82cTTuy/+OcxZbLRmKhPkk91/AJOQzxZsShcrmHFAGeiEqSIrv1nPZ3tKq9kfMLdCHmsqg==",
"dev": true,
"dependencies": {
"@microsoft/tsdoc": "0.14.2",
"@microsoft/tsdoc-config": "~0.16.1",
- "@rushstack/node-core-library": "4.0.2"
+ "@rushstack/node-core-library": "4.1.0"
}
},
"node_modules/@microsoft/api-extractor/node_modules/@rushstack/terminal": {
- "version": "0.10.0",
- "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz",
- "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==",
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.1.tgz",
+ "integrity": "sha512-C6Vi/m/84IYJTkfzmXr1+W8Wi3MmBjVF/q3za91Gb3VYjKbpALHVxY6FgH625AnDe5Z0Kh4MHKWA3Z7bqgAezA==",
"dev": true,
"dependencies": {
- "@rushstack/node-core-library": "4.0.2",
+ "@rushstack/node-core-library": "4.1.0",
"supports-color": "~8.1.1"
},
"peerDependencies": {
@@ -703,12 +715,12 @@
}
},
"node_modules/@microsoft/api-extractor/node_modules/@rushstack/ts-command-line": {
- "version": "4.19.0",
- "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.0.tgz",
- "integrity": "sha512-0sIHWOFGLFb6tC1zk2R0aM79ic3CF0XGzVBvhf6ytMyjDwt03DVb1qe5/5NQ0FGcvB5YyQ2WVfGsnxG6SANvHA==",
+ "version": "4.19.2",
+ "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.2.tgz",
+ "integrity": "sha512-cqmXXmBEBlzo9WtyUrHtF9e6kl0LvBY7aTSVX4jfnBfXWZQWnPq9JTFPlQZ+L/ZwjZ4HrNwQsOVvhe9oOucZkw==",
"dev": true,
"dependencies": {
- "@rushstack/terminal": "0.10.0",
+ "@rushstack/terminal": "0.10.1",
"@types/argparse": "1.0.38",
"argparse": "~1.0.9",
"string-argv": "~0.3.1"
@@ -905,9 +917,9 @@
"link": true
},
"node_modules/@rushstack/node-core-library": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz",
- "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.1.0.tgz",
+ "integrity": "sha512-qz4JFBZJCf1YN5cAXa1dP6Mki/HrsQxc/oYGAGx29dF2cwF2YMxHoly0FBhMw3IEnxo5fMj0boVfoHVBkpkx/w==",
"dev": true,
"dependencies": {
"fs-extra": "~7.0.1",
@@ -1002,9 +1014,9 @@
"dev": true
},
"node_modules/@swc/core": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.2.tgz",
- "integrity": "sha512-vWgY07R/eqj1/a0vsRKLI9o9klGZfpLNOVEnrv4nrccxBgYPjcf22IWwAoaBJ+wpA7Q4fVjCUM8lP0m01dpxcg==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.4.13.tgz",
+ "integrity": "sha512-rOtusBE+2gaeRkAJn5E4zp5yzZekZOypzSOz5ZG6P1hFbd+Cc26fWEdK6sUSnrkkvTd0Oj33KXLB/4UkbK/UHA==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -1019,16 +1031,16 @@
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
- "@swc/core-darwin-arm64": "1.4.2",
- "@swc/core-darwin-x64": "1.4.2",
- "@swc/core-linux-arm-gnueabihf": "1.4.2",
- "@swc/core-linux-arm64-gnu": "1.4.2",
- "@swc/core-linux-arm64-musl": "1.4.2",
- "@swc/core-linux-x64-gnu": "1.4.2",
- "@swc/core-linux-x64-musl": "1.4.2",
- "@swc/core-win32-arm64-msvc": "1.4.2",
- "@swc/core-win32-ia32-msvc": "1.4.2",
- "@swc/core-win32-x64-msvc": "1.4.2"
+ "@swc/core-darwin-arm64": "1.4.13",
+ "@swc/core-darwin-x64": "1.4.13",
+ "@swc/core-linux-arm-gnueabihf": "1.4.13",
+ "@swc/core-linux-arm64-gnu": "1.4.13",
+ "@swc/core-linux-arm64-musl": "1.4.13",
+ "@swc/core-linux-x64-gnu": "1.4.13",
+ "@swc/core-linux-x64-musl": "1.4.13",
+ "@swc/core-win32-arm64-msvc": "1.4.13",
+ "@swc/core-win32-ia32-msvc": "1.4.13",
+ "@swc/core-win32-x64-msvc": "1.4.13"
},
"peerDependencies": {
"@swc/helpers": "^0.5.0"
@@ -1040,9 +1052,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-darwin-arm64": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.2.tgz",
- "integrity": "sha512-1uSdAn1MRK5C1m/TvLZ2RDvr0zLvochgrZ2xL+lRzugLlCTlSA+Q4TWtrZaOz+vnnFVliCpw7c7qu0JouhgQIw==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.4.13.tgz",
+ "integrity": "sha512-36P72FLpm5iq85IvoEjBvi22DiqkkEIanJ1M0E8bkxcFHUbjBrYfPY9T6cpPyK5oQqkaTBvNAc3j1BlVD6IH6w==",
"cpu": [
"arm64"
],
@@ -1056,9 +1068,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-darwin-x64": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.2.tgz",
- "integrity": "sha512-TYD28+dCQKeuxxcy7gLJUCFLqrwDZnHtC2z7cdeGfZpbI2mbfppfTf2wUPzqZk3gEC96zHd4Yr37V3Tvzar+lQ==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.4.13.tgz",
+ "integrity": "sha512-ye7OgKpDdyA8AMIVVdmD1ICDaFXgoEXORnVO8bBHyul0WN71yUBZMX+YxEx2lpWtiftA2vY/1MAuOR80vHkBCw==",
"cpu": [
"x64"
],
@@ -1072,9 +1084,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-linux-arm-gnueabihf": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.2.tgz",
- "integrity": "sha512-Eyqipf7ZPGj0vplKHo8JUOoU1un2sg5PjJMpEesX0k+6HKE2T8pdyeyXODN0YTFqzndSa/J43EEPXm+rHAsLFQ==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.4.13.tgz",
+ "integrity": "sha512-+x593Jlmu4c3lJtZUKRejWpV2MAij1Js5nmQLLdjo6ChR2D4B2rzj3iMiKn5gITew7fraF9t3fvXALdWh7HmUg==",
"cpu": [
"arm"
],
@@ -1088,9 +1100,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-linux-arm64-gnu": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.2.tgz",
- "integrity": "sha512-wZn02DH8VYPv3FC0ub4my52Rttsus/rFw+UUfzdb3tHMHXB66LqN+rR0ssIOZrH6K+VLN6qpTw9VizjyoH0BxA==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.4.13.tgz",
+ "integrity": "sha512-0x8OVw4dfyNerrs/9eZX9wNnmvwbwXSMCi+LbE6Xt1pXOIwvoLtFIXcV3NsrlkFboO3sr5UAQIwDxKqbIZA9pQ==",
"cpu": [
"arm64"
],
@@ -1104,9 +1116,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-linux-arm64-musl": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.2.tgz",
- "integrity": "sha512-3G0D5z9hUj9bXNcwmA1eGiFTwe5rWkuL3DsoviTj73TKLpk7u64ND0XjEfO0huVv4vVu9H1jodrKb7nvln/dlw==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.4.13.tgz",
+ "integrity": "sha512-Z9c4JiequtZvngPcxbCuAOkmWBxi2vInZbjjhD5I+Q9oiJdXUz1t2USGwsGPS41Xvk1BOA3ecK2Sn1ilY3titg==",
"cpu": [
"arm64"
],
@@ -1120,9 +1132,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-linux-x64-gnu": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.2.tgz",
- "integrity": "sha512-LFxn9U8cjmYHw3jrdPNqPAkBGglKE3tCZ8rA7hYyp0BFxuo7L2ZcEnPm4RFpmSCCsExFH+LEJWuMGgWERoktvg==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.4.13.tgz",
+ "integrity": "sha512-ChatHtk+vX0Ke5QG+jO+rIapw/KwZsi9MedCBHFXHH6iWF4z8d51cJeN68ykcn+vAXzjNeFNdlNy5Vbkd1zAqg==",
"cpu": [
"x64"
],
@@ -1136,9 +1148,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-linux-x64-musl": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.2.tgz",
- "integrity": "sha512-dp0fAmreeVVYTUcb4u9njTPrYzKnbIH0EhH2qvC9GOYNNREUu2GezSIDgonjOXkHiTCvopG4xU7y56XtXj4VrQ==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.4.13.tgz",
+ "integrity": "sha512-0Pz39YR530mXpsztwQkmEKdkkZy4fY4Smdh4pkm6Ly8Nndyo0te/l4bcAGqN24Jp7aVwF/QSy14SAtw4HRjU9g==",
"cpu": [
"x64"
],
@@ -1152,9 +1164,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-win32-arm64-msvc": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.2.tgz",
- "integrity": "sha512-HlVIiLMQkzthAdqMslQhDkoXJ5+AOLUSTV6fm6shFKZKqc/9cJvr4S8UveNERL9zUficA36yM3bbfo36McwnvQ==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.4.13.tgz",
+ "integrity": "sha512-LVZfhlD+jHcAbz5NN+gAJ1BEasB0WpcvUzcsJt0nQSRsojgzPzFjJ+fzEBnvT7SMtqKkrnVJ0OmDYeh88bDRpw==",
"cpu": [
"arm64"
],
@@ -1168,9 +1180,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-win32-ia32-msvc": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.2.tgz",
- "integrity": "sha512-WCF8faPGjCl4oIgugkp+kL9nl3nUATlzKXCEGFowMEmVVCFM0GsqlmGdPp1pjZoWc9tpYanoXQDnp5IvlDSLhA==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.4.13.tgz",
+ "integrity": "sha512-78hxHWUvUZtWsnhcf8DKwhBcNFJw+j4y4fN2B9ioXmBWX2tIyw+BqUHOrismOtjPihaZmwe/Ok2e4qmkawE2fw==",
"cpu": [
"ia32"
],
@@ -1184,9 +1196,9 @@
}
},
"node_modules/@swc/core/node_modules/@swc/core-win32-x64-msvc": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.2.tgz",
- "integrity": "sha512-oV71rwiSpA5xre2C5570BhCsg1HF97SNLsZ/12xv7zayGzqr3yvFALFJN8tHKpqUdCB4FGPjoP3JFdV3i+1wUw==",
+ "version": "1.4.13",
+ "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.4.13.tgz",
+ "integrity": "sha512-WSfy1u2Xde6jU7UpHIInCUMW98Zw9iZglddKUAvmr1obkZji5U6EX0Oca3asEJdZPFb+2lMLjt0Mh5a1YisROg==",
"cpu": [
"x64"
],
@@ -1216,15 +1228,6 @@
"resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
"integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="
},
- "node_modules/@tsd/typescript": {
- "version": "5.3.3",
- "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.3.3.tgz",
- "integrity": "sha512-CQlfzol0ldaU+ftWuG52vH29uRoKboLinLy84wS8TQOu+m+tWoaUfk4svL4ij2V8M5284KymJBlHUusKj6k34w==",
- "dev": true,
- "engines": {
- "node": ">=14.17"
- }
- },
"node_modules/@types/argparse": {
"version": "1.0.38",
"resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz",
@@ -1479,25 +1482,25 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.1.0.tgz",
- "integrity": "sha512-j6vT/kCulhG5wBmGtstKeiVr1rdXE4nk+DT1k6trYkwlrvW9eOF5ZbgKnd/YR6PcM4uTEXa0h6Fcvf6X7Dxl0w==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.6.0.tgz",
+ "integrity": "sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==",
"dev": true,
"dependencies": {
- "@eslint-community/regexpp": "^4.5.1",
- "@typescript-eslint/scope-manager": "7.1.0",
- "@typescript-eslint/type-utils": "7.1.0",
- "@typescript-eslint/utils": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@eslint-community/regexpp": "^4.10.0",
+ "@typescript-eslint/scope-manager": "7.6.0",
+ "@typescript-eslint/type-utils": "7.6.0",
+ "@typescript-eslint/utils": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4",
"graphemer": "^1.4.0",
- "ignore": "^5.2.4",
+ "ignore": "^5.3.1",
"natural-compare": "^1.4.0",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1514,16 +1517,16 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz",
- "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz",
+ "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0"
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1531,12 +1534,12 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
- "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
+ "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1544,18 +1547,18 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.1.0.tgz",
- "integrity": "sha512-UZIhv8G+5b5skkcuhgvxYWHjk7FW7/JP5lPASMEUoliAPwIH/rxoUSQPia2cuOj9AmDZmwUl1usKm85t5VUMew==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.6.0.tgz",
+ "integrity": "sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "7.1.0",
- "@typescript-eslint/utils": "7.1.0",
+ "@typescript-eslint/typescript-estree": "7.6.0",
+ "@typescript-eslint/utils": "7.6.0",
"debug": "^4.3.4",
- "ts-api-utils": "^1.0.1"
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1571,22 +1574,22 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz",
- "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz",
+ "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1599,29 +1602,44 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/types": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
- "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
+ "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
- "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz",
+ "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.6.0",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1629,32 +1647,44 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys/node_modules/@typescript-eslint/types": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
- "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
+ "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/@typescript-eslint/parser": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.1.0.tgz",
- "integrity": "sha512-V1EknKUubZ1gWFjiOZhDSNToOjs63/9O0puCgGS8aDOgpZY326fzFu15QAUjwaXzRZjf/qdsdBrckYdv9YxB8w==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.6.0.tgz",
+ "integrity": "sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "7.1.0",
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/typescript-estree": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/scope-manager": "7.6.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/typescript-estree": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1670,16 +1700,16 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz",
- "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz",
+ "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0"
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1687,12 +1717,12 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
- "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
+ "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1700,22 +1730,22 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz",
- "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz",
+ "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1727,17 +1757,44 @@
}
}
},
+ "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree/node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
- "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz",
+ "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.6.0",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1745,21 +1802,21 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.1.0.tgz",
- "integrity": "sha512-WUFba6PZC5OCGEmbweGpnNJytJiLG7ZvDBJJoUcX4qZYf1mGZ97mO2Mps6O2efxJcJdRNpqweCistDbZMwIVHw==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.6.0.tgz",
+ "integrity": "sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.4.0",
- "@types/json-schema": "^7.0.12",
- "@types/semver": "^7.5.0",
- "@typescript-eslint/scope-manager": "7.1.0",
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/typescript-estree": "7.1.0",
- "semver": "^7.5.4"
+ "@types/json-schema": "^7.0.15",
+ "@types/semver": "^7.5.8",
+ "@typescript-eslint/scope-manager": "7.6.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/typescript-estree": "7.6.0",
+ "semver": "^7.6.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1770,16 +1827,16 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.1.0.tgz",
- "integrity": "sha512-6TmN4OJiohHfoOdGZ3huuLhpiUgOGTpgXNUPJgeZOZR3DnIpdSgtt83RS35OYNNXxM4TScVlpVKC9jyQSETR1A==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.6.0.tgz",
+ "integrity": "sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0"
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1787,16 +1844,16 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
- "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz",
+ "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.6.0",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1804,12 +1861,12 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.1.0.tgz",
- "integrity": "sha512-qTWjWieJ1tRJkxgZYXx6WUYtWlBc48YRxgY2JN1aGeVpkhmnopq+SUC8UEVGNXIvWH7XyuTjwALfG6bFEgCkQA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.6.0.tgz",
+ "integrity": "sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==",
"dev": true,
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1817,22 +1874,22 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.1.0.tgz",
- "integrity": "sha512-k7MyrbD6E463CBbSpcOnwa8oXRdHzH1WiVzOipK3L5KSML92ZKgUBrTlehdi7PEIMT8k0bQixHUGXggPAlKnOQ==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.6.0.tgz",
+ "integrity": "sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "@typescript-eslint/visitor-keys": "7.1.0",
+ "@typescript-eslint/types": "7.6.0",
+ "@typescript-eslint/visitor-keys": "7.6.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "minimatch": "9.0.3",
- "semver": "^7.5.4",
- "ts-api-utils": "^1.0.1"
+ "minimatch": "^9.0.4",
+ "semver": "^7.6.0",
+ "ts-api-utils": "^1.3.0"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
@@ -1845,22 +1902,49 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree/node_modules/@typescript-eslint/visitor-keys": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.1.0.tgz",
- "integrity": "sha512-FhUqNWluiGNzlvnDZiXad4mZRhtghdoKW6e98GoEOYSu5cND+E39rG5KwJMUzeENwm1ztYBRqof8wMLP+wNPIA==",
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.6.0.tgz",
+ "integrity": "sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "7.1.0",
- "eslint-visitor-keys": "^3.4.1"
+ "@typescript-eslint/types": "7.6.0",
+ "eslint-visitor-keys": "^3.4.3"
},
"engines": {
- "node": "^16.0.0 || >=18.0.0"
+ "node": "^18.18.0 || >=20.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+ "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree/node_modules/ts-api-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
+ "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/@ungap/structured-clone": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
@@ -2755,14 +2839,6 @@
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"dev": true
},
- "node_modules/cross-fetch": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-4.0.0.tgz",
- "integrity": "sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==",
- "dependencies": {
- "node-fetch": "^2.6.12"
- }
- },
"node_modules/cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@@ -2926,11 +3002,6 @@
"node": ">= 14"
}
},
- "node_modules/devtools-protocol": {
- "version": "0.0.1249869",
- "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1249869.tgz",
- "integrity": "sha512-Ctp4hInA0BEavlUoRy9mhGq0i+JSo/AwVyX2EFgZmV1kYB+Zq+EMBAn52QWu6FbRr10hRb6pBl420upbp4++vg=="
- },
"node_modules/dezalgo": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.4.tgz",
@@ -2996,6 +3067,7 @@
"version": "0.1.13",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
"optional": true,
"dependencies": {
"iconv-lite": "^0.6.2"
@@ -3005,6 +3077,7 @@
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "dev": true,
"optional": true,
"dependencies": {
"safer-buffer": ">= 2.1.2 < 3.0.0"
@@ -3173,9 +3246,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.1.tgz",
- "integrity": "sha512-OJwEgrpWm/PCMsLVWXKqvcjme3bHNpOgN7Tb6cQnR5n0TPbQx1/Xrn7rqM+wn17bYeT6MGB5sn1Bh5YiGi70nA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz",
+ "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==",
"dev": true,
"hasInstallScript": true,
"bin": {
@@ -3185,35 +3258,35 @@
"node": ">=12"
},
"optionalDependencies": {
- "@esbuild/aix-ppc64": "0.20.1",
- "@esbuild/android-arm": "0.20.1",
- "@esbuild/android-arm64": "0.20.1",
- "@esbuild/android-x64": "0.20.1",
- "@esbuild/darwin-arm64": "0.20.1",
- "@esbuild/darwin-x64": "0.20.1",
- "@esbuild/freebsd-arm64": "0.20.1",
- "@esbuild/freebsd-x64": "0.20.1",
- "@esbuild/linux-arm": "0.20.1",
- "@esbuild/linux-arm64": "0.20.1",
- "@esbuild/linux-ia32": "0.20.1",
- "@esbuild/linux-loong64": "0.20.1",
- "@esbuild/linux-mips64el": "0.20.1",
- "@esbuild/linux-ppc64": "0.20.1",
- "@esbuild/linux-riscv64": "0.20.1",
- "@esbuild/linux-s390x": "0.20.1",
- "@esbuild/linux-x64": "0.20.1",
- "@esbuild/netbsd-x64": "0.20.1",
- "@esbuild/openbsd-x64": "0.20.1",
- "@esbuild/sunos-x64": "0.20.1",
- "@esbuild/win32-arm64": "0.20.1",
- "@esbuild/win32-ia32": "0.20.1",
- "@esbuild/win32-x64": "0.20.1"
+ "@esbuild/aix-ppc64": "0.20.2",
+ "@esbuild/android-arm": "0.20.2",
+ "@esbuild/android-arm64": "0.20.2",
+ "@esbuild/android-x64": "0.20.2",
+ "@esbuild/darwin-arm64": "0.20.2",
+ "@esbuild/darwin-x64": "0.20.2",
+ "@esbuild/freebsd-arm64": "0.20.2",
+ "@esbuild/freebsd-x64": "0.20.2",
+ "@esbuild/linux-arm": "0.20.2",
+ "@esbuild/linux-arm64": "0.20.2",
+ "@esbuild/linux-ia32": "0.20.2",
+ "@esbuild/linux-loong64": "0.20.2",
+ "@esbuild/linux-mips64el": "0.20.2",
+ "@esbuild/linux-ppc64": "0.20.2",
+ "@esbuild/linux-riscv64": "0.20.2",
+ "@esbuild/linux-s390x": "0.20.2",
+ "@esbuild/linux-x64": "0.20.2",
+ "@esbuild/netbsd-x64": "0.20.2",
+ "@esbuild/openbsd-x64": "0.20.2",
+ "@esbuild/sunos-x64": "0.20.2",
+ "@esbuild/win32-arm64": "0.20.2",
+ "@esbuild/win32-ia32": "0.20.2",
+ "@esbuild/win32-x64": "0.20.2"
}
},
"node_modules/esbuild/node_modules/@esbuild/aix-ppc64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.1.tgz",
- "integrity": "sha512-m55cpeupQ2DbuRGQMMZDzbv9J9PgVelPjlcmM5kxHnrBdBx6REaEd7LamYV7Dm8N7rCyR/XwU6rVP8ploKtIkA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz",
+ "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==",
"cpu": [
"ppc64"
],
@@ -3227,9 +3300,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/android-arm": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.1.tgz",
- "integrity": "sha512-4j0+G27/2ZXGWR5okcJi7pQYhmkVgb4D7UKwxcqrjhvp5TKWx3cUjgB1CGj1mfdmJBQ9VnUGgUhign+FPF2Zgw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz",
+ "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==",
"cpu": [
"arm"
],
@@ -3243,9 +3316,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/android-arm64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.1.tgz",
- "integrity": "sha512-hCnXNF0HM6AjowP+Zou0ZJMWWa1VkD77BXe959zERgGJBBxB+sV+J9f/rcjeg2c5bsukD/n17RKWXGFCO5dD5A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz",
+ "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==",
"cpu": [
"arm64"
],
@@ -3259,9 +3332,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/android-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.1.tgz",
- "integrity": "sha512-MSfZMBoAsnhpS+2yMFYIQUPs8Z19ajwfuaSZx+tSl09xrHZCjbeXXMsUF/0oq7ojxYEpsSo4c0SfjxOYXRbpaA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz",
+ "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==",
"cpu": [
"x64"
],
@@ -3275,9 +3348,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/darwin-arm64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.1.tgz",
- "integrity": "sha512-Ylk6rzgMD8klUklGPzS414UQLa5NPXZD5tf8JmQU8GQrj6BrFA/Ic9tb2zRe1kOZyCbGl+e8VMbDRazCEBqPvA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz",
+ "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==",
"cpu": [
"arm64"
],
@@ -3291,9 +3364,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/darwin-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.1.tgz",
- "integrity": "sha512-pFIfj7U2w5sMp52wTY1XVOdoxw+GDwy9FsK3OFz4BpMAjvZVs0dT1VXs8aQm22nhwoIWUmIRaE+4xow8xfIDZA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz",
+ "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==",
"cpu": [
"x64"
],
@@ -3307,9 +3380,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.1.tgz",
- "integrity": "sha512-UyW1WZvHDuM4xDz0jWun4qtQFauNdXjXOtIy7SYdf7pbxSWWVlqhnR/T2TpX6LX5NI62spt0a3ldIIEkPM6RHw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz",
+ "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==",
"cpu": [
"arm64"
],
@@ -3323,9 +3396,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/freebsd-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.1.tgz",
- "integrity": "sha512-itPwCw5C+Jh/c624vcDd9kRCCZVpzpQn8dtwoYIt2TJF3S9xJLiRohnnNrKwREvcZYx0n8sCSbvGH349XkcQeg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz",
+ "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==",
"cpu": [
"x64"
],
@@ -3339,9 +3412,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-arm": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.1.tgz",
- "integrity": "sha512-LojC28v3+IhIbfQ+Vu4Ut5n3wKcgTu6POKIHN9Wpt0HnfgUGlBuyDDQR4jWZUZFyYLiz4RBBBmfU6sNfn6RhLw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz",
+ "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==",
"cpu": [
"arm"
],
@@ -3355,9 +3428,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-arm64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.1.tgz",
- "integrity": "sha512-cX8WdlF6Cnvw/DO9/X7XLH2J6CkBnz7Twjpk56cshk9sjYVcuh4sXQBy5bmTwzBjNVZze2yaV1vtcJS04LbN8w==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz",
+ "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==",
"cpu": [
"arm64"
],
@@ -3371,9 +3444,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-ia32": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.1.tgz",
- "integrity": "sha512-4H/sQCy1mnnGkUt/xszaLlYJVTz3W9ep52xEefGtd6yXDQbz/5fZE5dFLUgsPdbUOQANcVUa5iO6g3nyy5BJiw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz",
+ "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==",
"cpu": [
"ia32"
],
@@ -3387,9 +3460,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-loong64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.1.tgz",
- "integrity": "sha512-c0jgtB+sRHCciVXlyjDcWb2FUuzlGVRwGXgI+3WqKOIuoo8AmZAddzeOHeYLtD+dmtHw3B4Xo9wAUdjlfW5yYA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz",
+ "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==",
"cpu": [
"loong64"
],
@@ -3403,9 +3476,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-mips64el": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.1.tgz",
- "integrity": "sha512-TgFyCfIxSujyuqdZKDZ3yTwWiGv+KnlOeXXitCQ+trDODJ+ZtGOzLkSWngynP0HZnTsDyBbPy7GWVXWaEl6lhA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz",
+ "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==",
"cpu": [
"mips64el"
],
@@ -3419,9 +3492,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-ppc64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.1.tgz",
- "integrity": "sha512-b+yuD1IUeL+Y93PmFZDZFIElwbmFfIKLKlYI8M6tRyzE6u7oEP7onGk0vZRh8wfVGC2dZoy0EqX1V8qok4qHaw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz",
+ "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==",
"cpu": [
"ppc64"
],
@@ -3435,9 +3508,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-riscv64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.1.tgz",
- "integrity": "sha512-wpDlpE0oRKZwX+GfomcALcouqjjV8MIX8DyTrxfyCfXxoKQSDm45CZr9fanJ4F6ckD4yDEPT98SrjvLwIqUCgg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz",
+ "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==",
"cpu": [
"riscv64"
],
@@ -3451,9 +3524,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-s390x": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.1.tgz",
- "integrity": "sha512-5BepC2Au80EohQ2dBpyTquqGCES7++p7G+7lXe1bAIvMdXm4YYcEfZtQrP4gaoZ96Wv1Ute61CEHFU7h4FMueQ==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz",
+ "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==",
"cpu": [
"s390x"
],
@@ -3467,9 +3540,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/linux-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.1.tgz",
- "integrity": "sha512-5gRPk7pKuaIB+tmH+yKd2aQTRpqlf1E4f/mC+tawIm/CGJemZcHZpp2ic8oD83nKgUPMEd0fNanrnFljiruuyA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz",
+ "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==",
"cpu": [
"x64"
],
@@ -3483,9 +3556,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/netbsd-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.1.tgz",
- "integrity": "sha512-4fL68JdrLV2nVW2AaWZBv3XEm3Ae3NZn/7qy2KGAt3dexAgSVT+Hc97JKSZnqezgMlv9x6KV0ZkZY7UO5cNLCg==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==",
"cpu": [
"x64"
],
@@ -3499,9 +3572,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/openbsd-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.1.tgz",
- "integrity": "sha512-GhRuXlvRE+twf2ES+8REbeCb/zeikNqwD3+6S5y5/x+DYbAQUNl0HNBs4RQJqrechS4v4MruEr8ZtAin/hK5iw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz",
+ "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==",
"cpu": [
"x64"
],
@@ -3515,9 +3588,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/sunos-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.1.tgz",
- "integrity": "sha512-ZnWEyCM0G1Ex6JtsygvC3KUUrlDXqOihw8RicRuQAzw+c4f1D66YlPNNV3rkjVW90zXVsHwZYWbJh3v+oQFM9Q==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz",
+ "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==",
"cpu": [
"x64"
],
@@ -3531,9 +3604,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/win32-arm64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.1.tgz",
- "integrity": "sha512-QZ6gXue0vVQY2Oon9WyLFCdSuYbXSoxaZrPuJ4c20j6ICedfsDilNPYfHLlMH7vGfU5DQR0czHLmJvH4Nzis/A==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz",
+ "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==",
"cpu": [
"arm64"
],
@@ -3547,9 +3620,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/win32-ia32": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.1.tgz",
- "integrity": "sha512-HzcJa1NcSWTAU0MJIxOho8JftNp9YALui3o+Ny7hCh0v5f90nprly1U3Sj1Ldj/CvKKdvvFsCRvDkpsEMp4DNw==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz",
+ "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==",
"cpu": [
"ia32"
],
@@ -3563,9 +3636,9 @@
}
},
"node_modules/esbuild/node_modules/@esbuild/win32-x64": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.1.tgz",
- "integrity": "sha512-0MBh53o6XtI6ctDnRMeQ+xoCN8kD2qI1rY1KgF/xdWQwoFeKou7puvDfV8/Wv4Ctx2rRpET/gGdz3YlNtNACSA==",
+ "version": "0.20.2",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz",
+ "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==",
"cpu": [
"x64"
],
@@ -3914,12 +3987,13 @@
}
},
"node_modules/eslint-plugin-mocha": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.3.0.tgz",
- "integrity": "sha512-IWzbg2K6B1Q7h37Ih4zMyW+nhmw1JvUlHlbCUUUu6PfOOAUGCB0gxmvv7/U+TQQ6e8yHUv+q7KMdIIum4bx+PA==",
+ "version": "10.4.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-10.4.2.tgz",
+ "integrity": "sha512-cur4dVYnSEWTBwdqIBQFxa/9siAhesu0TX+lbJ4ClE9j0eNMNe6BSx3vkFFNz6tGoveyMyELFXa30f3fvuAVDg==",
"dev": true,
"dependencies": {
"eslint-utils": "^3.0.0",
+ "globals": "^13.24.0",
"rambda": "^7.4.0"
},
"engines": {
@@ -4720,6 +4794,28 @@
"node": ">= 10.0.0"
}
},
+ "node_modules/glob": {
+ "version": "10.3.12",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
+ "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
+ "dev": true,
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.6",
+ "minimatch": "^9.0.1",
+ "minipass": "^7.0.4",
+ "path-scurry": "^1.10.2"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
"node_modules/glob-parent": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -4732,6 +4828,31 @@
"node": ">=10.13.0"
}
},
+ "node_modules/glob/node_modules/path-scurry": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
+ "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob/node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
"node_modules/globals": {
"version": "13.24.0",
"resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
@@ -4806,24 +4927,24 @@
"dev": true
},
"node_modules/gts": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/gts/-/gts-5.2.0.tgz",
- "integrity": "sha512-25qOnePUUX7upFc4ycqWersDBq+o1X6hXUTW56JOWCxPYKJXQ1RWzqT9q+2SU3LfPKJf+4sz4Dw3VT0p96Kv6g==",
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/gts/-/gts-5.3.0.tgz",
+ "integrity": "sha512-/V0nbaWLBv8g0v2kol5M7Vf+kHXk19Ew5sa3wQJXeUaccesXg7AFo7eEInoIpR+aIJ3QDjoYt4zHYeFr8w8rng==",
"dev": true,
"dependencies": {
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"chalk": "^4.1.2",
- "eslint": "8.50.0",
- "eslint-config-prettier": "9.0.0",
+ "eslint": "8.53.0",
+ "eslint-config-prettier": "9.1.0",
"eslint-plugin-node": "11.1.0",
- "eslint-plugin-prettier": "5.0.0",
+ "eslint-plugin-prettier": "5.1.3",
"execa": "^5.0.0",
"inquirer": "^7.3.3",
"json5": "^2.1.3",
"meow": "^9.0.0",
"ncp": "^2.0.0",
- "prettier": "3.0.3",
+ "prettier": "3.1.1",
"rimraf": "3.0.2",
"write-file-atomic": "^4.0.0"
},
@@ -4837,15 +4958,6 @@
"typescript": ">=3"
}
},
- "node_modules/gts/node_modules/@eslint/js": {
- "version": "8.50.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz",
- "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==",
- "dev": true,
- "engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
- }
- },
"node_modules/gts/node_modules/@typescript-eslint/eslint-plugin": {
"version": "5.62.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz",
@@ -5058,18 +5170,19 @@
}
},
"node_modules/gts/node_modules/eslint": {
- "version": "8.50.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz",
- "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==",
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.53.0.tgz",
+ "integrity": "sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
- "@eslint/eslintrc": "^2.1.2",
- "@eslint/js": "8.50.0",
- "@humanwhocodes/config-array": "^0.11.11",
+ "@eslint/eslintrc": "^2.1.3",
+ "@eslint/js": "8.53.0",
+ "@humanwhocodes/config-array": "^0.11.13",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
+ "@ungap/structured-clone": "^1.2.0",
"ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -5111,45 +5224,13 @@
"url": "https://opencollective.com/eslint"
}
},
- "node_modules/gts/node_modules/eslint-config-prettier": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.0.0.tgz",
- "integrity": "sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==",
+ "node_modules/gts/node_modules/eslint/node_modules/@eslint/js": {
+ "version": "8.53.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.53.0.tgz",
+ "integrity": "sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w==",
"dev": true,
- "bin": {
- "eslint-config-prettier": "bin/cli.js"
- },
- "peerDependencies": {
- "eslint": ">=7.0.0"
- }
- },
- "node_modules/gts/node_modules/eslint-plugin-prettier": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz",
- "integrity": "sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w==",
- "dev": true,
- "dependencies": {
- "prettier-linter-helpers": "^1.0.0",
- "synckit": "^0.8.5"
- },
"engines": {
- "node": "^14.18.0 || >=16.0.0"
- },
- "funding": {
- "url": "https://opencollective.com/prettier"
- },
- "peerDependencies": {
- "@types/eslint": ">=8.0.0",
- "eslint": ">=8.0.0",
- "prettier": ">=3.0.0"
- },
- "peerDependenciesMeta": {
- "@types/eslint": {
- "optional": true
- },
- "eslint-config-prettier": {
- "optional": true
- }
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/gts/node_modules/estraverse": {
@@ -5266,9 +5347,9 @@
}
},
"node_modules/gts/node_modules/prettier": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz",
- "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==",
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.1.tgz",
+ "integrity": "sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==",
"dev": true,
"bin": {
"prettier": "bin/prettier.cjs"
@@ -6616,9 +6697,9 @@
}
},
"node_modules/mocha": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.3.0.tgz",
- "integrity": "sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==",
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz",
+ "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==",
"dependencies": {
"ansi-colors": "4.1.1",
"browser-stdout": "1.3.1",
@@ -6750,25 +6831,6 @@
"path-to-regexp": "^6.2.1"
}
},
- "node_modules/node-fetch": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
- "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
- "dependencies": {
- "whatwg-url": "^5.0.0"
- },
- "engines": {
- "node": "4.x || >=6.0.0"
- },
- "peerDependencies": {
- "encoding": "^0.1.0"
- },
- "peerDependenciesMeta": {
- "encoding": {
- "optional": true
- }
- }
- },
"node_modules/nopt": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz",
@@ -7239,6 +7301,7 @@
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz",
"integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==",
+ "dev": true,
"dependencies": {
"lru-cache": "^9.1.1 || ^10.0.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
@@ -7254,6 +7317,7 @@
"version": "10.2.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
"integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "dev": true,
"engines": {
"node": "14 || >=16.14"
}
@@ -8183,7 +8247,7 @@
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
- "devOptional": true
+ "dev": true
},
"node_modules/semver": {
"version": "7.6.0",
@@ -8853,11 +8917,6 @@
"node": ">=8.0"
}
},
- "node_modules/tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
- },
"node_modules/treeify": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/treeify/-/treeify-1.1.0.tgz",
@@ -8876,18 +8935,6 @@
"node": ">=8"
}
},
- "node_modules/ts-api-utils": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz",
- "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==",
- "dev": true,
- "engines": {
- "node": ">=16"
- },
- "peerDependencies": {
- "typescript": ">=4.2.0"
- }
- },
"node_modules/tsconfig-paths": {
"version": "3.15.0",
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz",
@@ -8913,12 +8960,12 @@
}
},
"node_modules/tsd": {
- "version": "0.30.7",
- "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.30.7.tgz",
- "integrity": "sha512-oTiJ28D6B/KXoU3ww/Eji+xqHJojiuPVMwA12g4KYX1O72N93Nb6P3P3h2OAhhf92Xl8NIhb/xFmBZd5zw/xUw==",
+ "version": "0.31.0",
+ "resolved": "https://registry.npmjs.org/tsd/-/tsd-0.31.0.tgz",
+ "integrity": "sha512-yjBiQ5n8OMv/IZOuhDjBy0ZLCoJ7rky/RxRh5W4sJ0oNNCU/kf6s3puPAkGNi59PptDdkcpUm+RsKSdjR2YbNg==",
"dev": true,
"dependencies": {
- "@tsd/typescript": "~5.3.3",
+ "@tsd/typescript": "~5.4.3",
"eslint-formatter-pretty": "^4.1.0",
"globby": "^11.0.1",
"jest-diff": "^29.0.3",
@@ -8933,6 +8980,15 @@
"node": ">=14.16"
}
},
+ "node_modules/tsd/node_modules/@tsd/typescript": {
+ "version": "5.4.4",
+ "resolved": "https://registry.npmjs.org/@tsd/typescript/-/typescript-5.4.4.tgz",
+ "integrity": "sha512-sqE6Rz9UNHBuCtuREo/PwsuUaegP1KDSfxMd+9K1qPpt7XO8BmkIImUp7zAqyvwXWUHs+sj6osEkkpyE0tFgfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
"node_modules/tslib": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
@@ -8955,9 +9011,9 @@
}
},
"node_modules/tsx": {
- "version": "4.7.1",
- "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.1.tgz",
- "integrity": "sha512-8d6VuibXHtlN5E3zFkgY8u4DX7Y3Z27zvvPKVmLon/D4AjuKzarkUBTLDBgj9iTQ0hg5xM7c/mYiRVM+HETf0g==",
+ "version": "4.7.2",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.7.2.tgz",
+ "integrity": "sha512-BCNd4kz6fz12fyrgCTEdZHGJ9fWTGeUzXmQysh0RVocDY3h4frk05ZNCXSy4kIenF7y/QnrdiVpTsyNRn6vlAw==",
"dev": true,
"dependencies": {
"esbuild": "~0.19.10",
@@ -9540,18 +9596,6 @@
"through": "^2.3.8"
}
},
- "node_modules/undici": {
- "version": "5.28.3",
- "resolved": "https://registry.npmjs.org/undici/-/undici-5.28.3.tgz",
- "integrity": "sha512-3ItfzbrhDlINjaP0duwnNsKpDQk3acHI3gVJ1z4fmwMK31k5G9OVIAMLSIaP6w4FaGkaAkN6zaQO9LUvZ1t7VA==",
- "dev": true,
- "dependencies": {
- "@fastify/busboy": "^2.0.0"
- },
- "engines": {
- "node": ">=14.0"
- }
- },
"node_modules/undici-types": {
"version": "5.25.3",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
@@ -9641,20 +9685,6 @@
"defaults": "^1.0.3"
}
},
- "node_modules/webidl-conversions": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
- "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
- },
- "node_modules/whatwg-url": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
- "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
- "dependencies": {
- "tr46": "~0.0.3",
- "webidl-conversions": "^3.0.0"
- }
- },
"node_modules/which": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
@@ -9944,14 +9974,13 @@
"version": "3.22.4",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.22.4.tgz",
"integrity": "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==",
- "dev": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
},
"packages/browsers": {
"name": "@puppeteer/browsers",
- "version": "2.1.0",
+ "version": "2.2.2",
"license": "Apache-2.0",
"dependencies": {
"debug": "4.3.4",
@@ -11996,9 +12025,9 @@
}
},
"packages/ng-schematics/node_modules/@angular/cli/node_modules/pacote/node_modules/tar": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz",
- "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==",
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
"dev": true,
"dependencies": {
"chownr": "^2.0.0",
@@ -12206,13 +12235,14 @@
}
},
"packages/puppeteer": {
- "version": "22.4.0",
+ "version": "22.6.5",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
- "@puppeteer/browsers": "2.1.0",
+ "@puppeteer/browsers": "2.2.2",
"cosmiconfig": "9.0.0",
- "puppeteer-core": "22.4.0"
+ "devtools-protocol": "0.0.1262051",
+ "puppeteer-core": "22.6.5"
},
"bin": {
"puppeteer": "lib/esm/puppeteer/node/cli.js"
@@ -12225,14 +12255,13 @@
}
},
"packages/puppeteer-core": {
- "version": "22.4.0",
+ "version": "22.6.5",
"license": "Apache-2.0",
"dependencies": {
- "@puppeteer/browsers": "2.1.0",
- "chromium-bidi": "0.5.12",
- "cross-fetch": "4.0.0",
+ "@puppeteer/browsers": "2.2.2",
+ "chromium-bidi": "0.5.17",
"debug": "4.3.4",
- "devtools-protocol": "0.0.1249869",
+ "devtools-protocol": "0.0.1262051",
"ws": "8.16.0"
},
"devDependencies": {
@@ -12253,17 +12282,23 @@
"license": "MIT"
},
"packages/puppeteer-core/node_modules/chromium-bidi": {
- "version": "0.5.12",
- "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.12.tgz",
- "integrity": "sha512-sZMgEBWKbupD0Q7lyFu8AWkrE+rs5ycE12jFkGwIgD/VS8lDPtelPlXM7LYaq4zrkZ/O2L3f4afHUHL0ICdKog==",
+ "version": "0.5.17",
+ "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.5.17.tgz",
+ "integrity": "sha512-BqOuIWUgTPj8ayuBFJUYCCuwIcwjBsb3/614P7tt1bEPJ4i1M0kCdIl0Wi9xhtswBXnfO2bTpTMkHD71H8rJMg==",
"dependencies": {
"mitt": "3.0.1",
- "urlpattern-polyfill": "10.0.0"
+ "urlpattern-polyfill": "10.0.0",
+ "zod": "3.22.4"
},
"peerDependencies": {
"devtools-protocol": "*"
}
},
+ "packages/puppeteer-core/node_modules/devtools-protocol": {
+ "version": "0.0.1262051",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1262051.tgz",
+ "integrity": "sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g=="
+ },
"packages/puppeteer-core/node_modules/rxjs": {
"version": "7.8.1",
"dev": true,
@@ -12306,6 +12341,11 @@
}
}
},
+ "packages/puppeteer/node_modules/devtools-protocol": {
+ "version": "0.0.1262051",
+ "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1262051.tgz",
+ "integrity": "sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g=="
+ },
"packages/puppeteer/node_modules/parse-json": {
"version": "5.2.0",
"license": "MIT",
@@ -12353,26 +12393,20 @@
"name": "@puppeteer-test/installation",
"version": "latest",
"dependencies": {
- "glob": "10.3.10",
- "mocha": "10.3.0"
+ "glob": "10.3.12",
+ "mocha": "10.4.0"
}
},
- "test/node_modules/diff": {
- "version": "5.2.0",
- "license": "BSD-3-Clause",
- "engines": {
- "node": ">=0.3.1"
- }
- },
- "test/node_modules/glob": {
- "version": "10.3.10",
- "license": "ISC",
+ "test/installation/node_modules/glob": {
+ "version": "10.3.12",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
+ "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
"dependencies": {
"foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
+ "jackspeak": "^2.3.6",
"minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
+ "minipass": "^7.0.4",
+ "path-scurry": "^1.10.2"
},
"bin": {
"glob": "dist/esm/bin.mjs"
@@ -12384,16 +12418,46 @@
"url": "https://github.com/sponsors/isaacs"
}
},
+ "test/installation/node_modules/glob/node_modules/path-scurry": {
+ "version": "1.10.2",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
+ "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "test/installation/node_modules/glob/node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "test/node_modules/diff": {
+ "version": "5.2.0",
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
"tools/docgen": {
"name": "@puppeteer/docgen",
"version": "0.1.0",
"license": "Apache-2.0",
"devDependencies": {
- "@microsoft/api-documenter": "7.23.35",
- "@microsoft/api-extractor": "7.42.2",
- "@microsoft/api-extractor-model": "7.28.13",
+ "@microsoft/api-documenter": "7.24.2",
+ "@microsoft/api-extractor": "7.43.1",
+ "@microsoft/api-extractor-model": "7.28.14",
"@microsoft/tsdoc": "0.14.2",
- "@rushstack/node-core-library": "4.0.2"
+ "@rushstack/node-core-library": "4.1.0"
}
},
"tools/doctest": {
@@ -12404,13 +12468,13 @@
"doctest": "bin/doctest.js"
},
"devDependencies": {
- "@swc/core": "1.4.2",
+ "@swc/core": "1.4.13",
"@types/doctrine": "0.0.9",
"@types/source-map-support": "0.5.10",
"@types/yargs": "17.0.32",
"acorn": "8.11.3",
"doctrine": "3.0.0",
- "glob": "10.3.10",
+ "glob": "10.3.12",
"pkg-dir": "8.0.0",
"source-map": "0.7.4",
"source-map-support": "0.5.21",
@@ -12430,27 +12494,6 @@
"node": ">=12"
}
},
- "tools/doctest/node_modules/glob": {
- "version": "10.3.10",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
- "minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"tools/doctest/node_modules/source-map": {
"version": "0.7.4",
"dev": true,
@@ -12490,7 +12533,7 @@
"license": "Apache-2.0",
"devDependencies": {
"@prettier/sync": "0.5.1",
- "@typescript-eslint/utils": "7.1.0"
+ "@typescript-eslint/utils": "7.6.0"
}
},
"tools/mocha-runner": {
@@ -12503,7 +12546,7 @@
"devDependencies": {
"@types/yargs": "17.0.32",
"c8": "9.1.0",
- "glob": "10.3.10",
+ "glob": "10.3.12",
"yargs": "17.7.2",
"zod": "3.22.4"
}
@@ -12521,27 +12564,6 @@
"node": ">=12"
}
},
- "tools/mocha-runner/node_modules/glob": {
- "version": "10.3.10",
- "dev": true,
- "license": "ISC",
- "dependencies": {
- "foreground-child": "^3.1.0",
- "jackspeak": "^2.3.5",
- "minimatch": "^9.0.1",
- "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
- "path-scurry": "^1.10.1"
- },
- "bin": {
- "glob": "dist/esm/bin.mjs"
- },
- "engines": {
- "node": ">=16 || 14 >=14.17"
- },
- "funding": {
- "url": "https://github.com/sponsors/isaacs"
- }
- },
"tools/mocha-runner/node_modules/yargs": {
"version": "17.7.2",
"dev": true,
diff --git a/remote/test/puppeteer/package.json b/remote/test/puppeteer/package.json
index 0ffdceedf7..a871a1d459 100644
--- a/remote/test/puppeteer/package.json
+++ b/remote/test/puppeteer/package.json
@@ -142,13 +142,13 @@
"@types/node": "20.8.4",
"@types/semver": "7.5.8",
"@types/sinon": "17.0.3",
- "@typescript-eslint/eslint-plugin": "7.1.0",
- "@typescript-eslint/parser": "7.1.0",
- "esbuild": "0.20.1",
+ "@typescript-eslint/eslint-plugin": "7.6.0",
+ "@typescript-eslint/parser": "7.6.0",
+ "esbuild": "0.20.2",
"eslint-config-prettier": "9.1.0",
"eslint-import-resolver-typescript": "3.6.1",
"eslint-plugin-import": "2.29.1",
- "eslint-plugin-mocha": "10.3.0",
+ "eslint-plugin-mocha": "10.4.2",
"eslint-plugin-prettier": "5.1.3",
"eslint-plugin-rulesdir": "0.2.2",
"eslint-plugin-tsdoc": "0.2.17",
@@ -156,18 +156,18 @@
"eslint": "8.57.0",
"execa": "8.0.1",
"expect": "29.7.0",
- "gts": "5.2.0",
+ "gts": "5.3.0",
"hereby": "1.8.9",
"license-checker": "25.0.1",
- "mocha": "10.3.0",
+ "mocha": "10.4.0",
"npm-run-all2": "6.1.2",
"prettier": "3.2.5",
"semver": "7.6.0",
"sinon": "17.0.1",
"source-map-support": "0.5.21",
"spdx-satisfies": "5.0.1",
- "tsd": "0.30.7",
- "tsx": "4.7.1",
+ "tsd": "0.31.0",
+ "tsx": "4.7.2",
"typescript": "5.3.3",
"wireit": "0.14.4"
},
diff --git a/remote/test/puppeteer/packages/browsers/CHANGELOG.md b/remote/test/puppeteer/packages/browsers/CHANGELOG.md
index a2798068e9..75fa1c370b 100644
--- a/remote/test/puppeteer/packages/browsers/CHANGELOG.md
+++ b/remote/test/puppeteer/packages/browsers/CHANGELOG.md
@@ -1,5 +1,32 @@
# Changelog
+## [2.2.2](https://github.com/puppeteer/puppeteer/compare/browsers-v2.2.1...browsers-v2.2.2) (2024-04-15)
+
+
+### Bug Fixes
+
+* remove NetworkServiceInProcess2 set by default ([#12261](https://github.com/puppeteer/puppeteer/issues/12261)) ([ff4f70f](https://github.com/puppeteer/puppeteer/commit/ff4f70f4ae7ca8deb0becbec2e49b35322dba336)), closes [#12257](https://github.com/puppeteer/puppeteer/issues/12257)
+
+## [2.2.1](https://github.com/puppeteer/puppeteer/compare/browsers-v2.2.0...browsers-v2.2.1) (2024-04-05)
+
+
+### Bug Fixes
+
+* do not use fallback download URLs if custom baseUrl is provided ([#12206](https://github.com/puppeteer/puppeteer/issues/12206)) ([ab560bc](https://github.com/puppeteer/puppeteer/commit/ab560bcf6fee57cabde94d9d261d28ffc2112948))
+* only set up a single process event listener in launch ([#12200](https://github.com/puppeteer/puppeteer/issues/12200)) ([7bc5e0f](https://github.com/puppeteer/puppeteer/commit/7bc5e0fb2dc443765e2512e4dc15fb2bcc1cb4be))
+
+## [2.2.0](https://github.com/puppeteer/puppeteer/compare/browsers-v2.1.0...browsers-v2.2.0) (2024-03-15)
+
+
+### Features
+
+* allow downloading Firefox channels other than nightly ([#12051](https://github.com/puppeteer/puppeteer/issues/12051)) ([e4cc2f9](https://github.com/puppeteer/puppeteer/commit/e4cc2f9ee944f2507a03cf8f5af99759c97ee2ec))
+
+
+### Bug Fixes
+
+* don't keep connection alive ([#12096](https://github.com/puppeteer/puppeteer/issues/12096)) ([0a142bf](https://github.com/puppeteer/puppeteer/commit/0a142bf0aa8a6666d1ca230d05a1ece0e03ad7d4))
+
## [2.1.0](https://github.com/puppeteer/puppeteer/compare/browsers-v2.0.1...browsers-v2.1.0) (2024-02-21)
diff --git a/remote/test/puppeteer/packages/browsers/README.md b/remote/test/puppeteer/packages/browsers/README.md
index f5342126c6..a05a4d38b8 100644
--- a/remote/test/puppeteer/packages/browsers/README.md
+++ b/remote/test/puppeteer/packages/browsers/README.md
@@ -10,7 +10,7 @@ Use `npx` to run the CLI:
npx @puppeteer/browsers --help
```
-CLI help will provide all documentation you need to use the CLI.
+Built-in per-command `help` will provide all documentation you need to use the CLI.
```bash
npx @puppeteer/browsers --help # help for all commands
@@ -18,10 +18,28 @@ npx @puppeteer/browsers install --help # help for the install command
npx @puppeteer/browsers launch --help # help for the launch command
```
+Some example to give an idea of what the CLI looks like (use the `--help` command for more examples):
+
+```sh
+# Download the latest available Chrome for Testing binary corresponding to the Stable channel.
+npx @puppeteer/browsers install chrome@stable
+
+# Download a specific Chrome for Testing version.
+npx @puppeteer/browsers install chrome@116.0.5793.0
+
+# Download the latest Chrome for Testing version for the given milestone.
+npx @puppeteer/browsers install chrome@117
+
+# Download the latest available ChromeDriver version corresponding to the Canary channel.
+npx @puppeteer/browsers install chromedriver@canary
+
+# Download a specific ChromeDriver version.
+npx @puppeteer/browsers install chromedriver@116.0.5793.0
+```
+
## Known limitations
-1. We support installing and running Firefox, Chrome and Chromium. The `latest`, `beta`, `dev`, `canary`, `stable` keywords are only supported for the install command. For the `launch` command you need to specify an exact build ID. The build ID is provided by the `install` command (see `npx @puppeteer/browsers install --help` for the format).
-2. Launching the system browsers is only possible for Chrome/Chromium.
+1. Launching the system browsers is only possible for Chrome/Chromium.
## API
diff --git a/remote/test/puppeteer/packages/browsers/package.json b/remote/test/puppeteer/packages/browsers/package.json
index 0f2afa74de..f9f2b1c5ea 100644
--- a/remote/test/puppeteer/packages/browsers/package.json
+++ b/remote/test/puppeteer/packages/browsers/package.json
@@ -1,6 +1,6 @@
{
"name": "@puppeteer/browsers",
- "version": "2.1.0",
+ "version": "2.2.2",
"description": "Download and launch browsers",
"scripts": {
"build:docs": "wireit",
diff --git a/remote/test/puppeteer/packages/browsers/src/CLI.ts b/remote/test/puppeteer/packages/browsers/src/CLI.ts
index 281f22c9f5..3bae584e62 100644
--- a/remote/test/puppeteer/packages/browsers/src/CLI.ts
+++ b/remote/test/puppeteer/packages/browsers/src/CLI.ts
@@ -222,7 +222,31 @@ export class CLI {
);
yargs.example(
'$0 install firefox',
- 'Install the latest available build of the Firefox browser.'
+ 'Install the latest nightly available build of the Firefox browser.'
+ );
+ yargs.example(
+ '$0 install firefox@stable',
+ 'Install the latest stable build of the Firefox browser.'
+ );
+ yargs.example(
+ '$0 install firefox@beta',
+ 'Install the latest beta build of the Firefox browser.'
+ );
+ yargs.example(
+ '$0 install firefox@devedition',
+ 'Install the latest devedition build of the Firefox browser.'
+ );
+ yargs.example(
+ '$0 install firefox@esr',
+ 'Install the latest ESR build of the Firefox browser.'
+ );
+ yargs.example(
+ '$0 install firefox@nightly',
+ 'Install the latest nightly build of the Firefox browser.'
+ );
+ yargs.example(
+ '$0 install firefox@stable_111.0.1',
+ 'Install a specific version of the Firefox browser.'
);
yargs.example(
'$0 install firefox --platform mac',
@@ -395,7 +419,7 @@ export function makeProgressCallback(
return (downloadedBytes: number, totalBytes: number) => {
if (!progressBar) {
progressBar = new ProgressBar(
- `Downloading ${browser} r${buildId} - ${toMegabytes(
+ `Downloading ${browser} ${buildId} - ${toMegabytes(
totalBytes
)} [:bar] :percent :etas `,
{
diff --git a/remote/test/puppeteer/packages/browsers/src/browser-data/browser-data.ts b/remote/test/puppeteer/packages/browsers/src/browser-data/browser-data.ts
index 3e78030aa7..fa7ec9be14 100644
--- a/remote/test/puppeteer/packages/browsers/src/browser-data/browser-data.ts
+++ b/remote/test/puppeteer/packages/browsers/src/browser-data/browser-data.ts
@@ -54,28 +54,36 @@ export const versionComparators = {
export {Browser, BrowserPlatform, ChromeReleaseChannel};
/**
- * @public
+ * @internal
*/
-export async function resolveBuildId(
+async function resolveBuildIdForBrowserTag(
browser: Browser,
platform: BrowserPlatform,
- tag: string
+ tag: BrowserTag
): Promise<string> {
switch (browser) {
case Browser.FIREFOX:
- switch (tag as BrowserTag) {
+ switch (tag) {
case BrowserTag.LATEST:
- return await firefox.resolveBuildId('FIREFOX_NIGHTLY');
+ return await firefox.resolveBuildId(firefox.FirefoxChannel.NIGHTLY);
case BrowserTag.BETA:
+ return await firefox.resolveBuildId(firefox.FirefoxChannel.BETA);
+ case BrowserTag.NIGHTLY:
+ return await firefox.resolveBuildId(firefox.FirefoxChannel.NIGHTLY);
+ case BrowserTag.DEVEDITION:
+ return await firefox.resolveBuildId(
+ firefox.FirefoxChannel.DEVEDITION
+ );
+ case BrowserTag.STABLE:
+ return await firefox.resolveBuildId(firefox.FirefoxChannel.STABLE);
+ case BrowserTag.ESR:
+ return await firefox.resolveBuildId(firefox.FirefoxChannel.ESR);
case BrowserTag.CANARY:
case BrowserTag.DEV:
- case BrowserTag.STABLE:
- throw new Error(
- `${tag} is not supported for ${browser}. Use 'latest' instead.`
- );
+ throw new Error(`${tag.toUpperCase()} is not available for Firefox`);
}
case Browser.CHROME: {
- switch (tag as BrowserTag) {
+ switch (tag) {
case BrowserTag.LATEST:
return await chrome.resolveBuildId(ChromeReleaseChannel.CANARY);
case BrowserTag.BETA:
@@ -86,13 +94,11 @@ export async function resolveBuildId(
return await chrome.resolveBuildId(ChromeReleaseChannel.DEV);
case BrowserTag.STABLE:
return await chrome.resolveBuildId(ChromeReleaseChannel.STABLE);
- default:
- const result = await chrome.resolveBuildId(tag);
- if (result) {
- return result;
- }
+ case BrowserTag.NIGHTLY:
+ case BrowserTag.DEVEDITION:
+ case BrowserTag.ESR:
+ throw new Error(`${tag.toUpperCase()} is not available for Chrome`);
}
- return tag;
}
case Browser.CHROMEDRIVER: {
switch (tag) {
@@ -105,13 +111,13 @@ export async function resolveBuildId(
return await chromedriver.resolveBuildId(ChromeReleaseChannel.DEV);
case BrowserTag.STABLE:
return await chromedriver.resolveBuildId(ChromeReleaseChannel.STABLE);
- default:
- const result = await chromedriver.resolveBuildId(tag);
- if (result) {
- return result;
- }
+ case BrowserTag.NIGHTLY:
+ case BrowserTag.DEVEDITION:
+ case BrowserTag.ESR:
+ throw new Error(
+ `${tag.toUpperCase()} is not available for ChromeDriver`
+ );
}
- return tag;
}
case Browser.CHROMEHEADLESSSHELL: {
switch (tag) {
@@ -132,29 +138,68 @@ export async function resolveBuildId(
return await chromeHeadlessShell.resolveBuildId(
ChromeReleaseChannel.STABLE
);
- default:
- const result = await chromeHeadlessShell.resolveBuildId(tag);
- if (result) {
- return result;
- }
+ case BrowserTag.NIGHTLY:
+ case BrowserTag.DEVEDITION:
+ case BrowserTag.ESR:
+ throw new Error(`${tag} is not available for chrome-headless-shell`);
}
- return tag;
}
case Browser.CHROMIUM:
- switch (tag as BrowserTag) {
+ switch (tag) {
case BrowserTag.LATEST:
return await chromium.resolveBuildId(platform);
- case BrowserTag.BETA:
+ case BrowserTag.NIGHTLY:
case BrowserTag.CANARY:
case BrowserTag.DEV:
+ case BrowserTag.DEVEDITION:
+ case BrowserTag.BETA:
case BrowserTag.STABLE:
+ case BrowserTag.ESR:
throw new Error(
- `${tag} is not supported for ${browser}. Use 'latest' instead.`
+ `${tag} is not supported for Chromium. Use 'latest' instead.`
);
}
}
- // We assume the tag is the buildId if it didn't match any keywords.
- return tag;
+}
+
+/**
+ * @public
+ */
+export async function resolveBuildId(
+ browser: Browser,
+ platform: BrowserPlatform,
+ tag: string
+): Promise<string> {
+ const browserTag = tag as BrowserTag;
+ if (Object.values(BrowserTag).includes(browserTag)) {
+ return await resolveBuildIdForBrowserTag(browser, platform, browserTag);
+ }
+
+ switch (browser) {
+ case Browser.FIREFOX:
+ return tag;
+ case Browser.CHROME:
+ const chromeResult = await chrome.resolveBuildId(tag);
+ if (chromeResult) {
+ return chromeResult;
+ }
+ return tag;
+ case Browser.CHROMEDRIVER:
+ const chromeDriverResult = await chromedriver.resolveBuildId(tag);
+ if (chromeDriverResult) {
+ return chromeDriverResult;
+ }
+ return tag;
+ case Browser.CHROMEHEADLESSSHELL:
+ const chromeHeadlessShellResult =
+ await chromeHeadlessShell.resolveBuildId(tag);
+ if (chromeHeadlessShellResult) {
+ return chromeHeadlessShellResult;
+ }
+ return tag;
+ case Browser.CHROMIUM:
+ return tag;
+ }
}
/**
diff --git a/remote/test/puppeteer/packages/browsers/src/browser-data/firefox.ts b/remote/test/puppeteer/packages/browsers/src/browser-data/firefox.ts
index 87e3804c8f..95e03c54c0 100644
--- a/remote/test/puppeteer/packages/browsers/src/browser-data/firefox.ts
+++ b/remote/test/puppeteer/packages/browsers/src/browser-data/firefox.ts
@@ -11,7 +11,7 @@ import {getJSON} from '../httpUtil.js';
import {BrowserPlatform, type ProfileOptions} from './types.js';
-function archive(platform: BrowserPlatform, buildId: string): string {
+function archiveNightly(platform: BrowserPlatform, buildId: string): string {
switch (platform) {
case BrowserPlatform.LINUX:
return `firefox-${buildId}.en-US.${platform}-x86_64.tar.bz2`;
@@ -24,48 +24,146 @@ function archive(platform: BrowserPlatform, buildId: string): string {
}
}
+function archive(platform: BrowserPlatform, buildId: string): string {
+ switch (platform) {
+ case BrowserPlatform.LINUX:
+ return `firefox-${buildId}.tar.bz2`;
+ case BrowserPlatform.MAC_ARM:
+ case BrowserPlatform.MAC:
+ return `Firefox ${buildId}.dmg`;
+ case BrowserPlatform.WIN32:
+ case BrowserPlatform.WIN64:
+ return `Firefox Setup ${buildId}.exe`;
+ }
+}
+
+function platformName(platform: BrowserPlatform): string {
+ switch (platform) {
+ case BrowserPlatform.LINUX:
+ return `linux-x86_64`;
+ case BrowserPlatform.MAC_ARM:
+ case BrowserPlatform.MAC:
+ return `mac`;
+ case BrowserPlatform.WIN32:
+ case BrowserPlatform.WIN64:
+ return platform;
+ }
+}
+
+function parseBuildId(buildId: string): [FirefoxChannel, string] {
+ for (const value of Object.values(FirefoxChannel)) {
+ if (buildId.startsWith(value + '_')) {
+ buildId = buildId.substring(value.length + 1);
+ return [value, buildId];
+ }
+ }
+ // Older versions do not have channel as the prefix.«
+ return [FirefoxChannel.NIGHTLY, buildId];
+}
+
export function resolveDownloadUrl(
platform: BrowserPlatform,
buildId: string,
- baseUrl = 'https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central'
+ baseUrl?: string
): string {
- return `${baseUrl}/${resolveDownloadPath(platform, buildId).join('/')}`;
+ const [channel, resolvedBuildId] = parseBuildId(buildId);
+ switch (channel) {
+ case FirefoxChannel.NIGHTLY:
+ baseUrl ??=
+ 'https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central';
+ break;
+ case FirefoxChannel.DEVEDITION:
+ baseUrl ??= 'https://archive.mozilla.org/pub/devedition/releases';
+ break;
+ case FirefoxChannel.BETA:
+ case FirefoxChannel.STABLE:
+ case FirefoxChannel.ESR:
+ baseUrl ??= 'https://archive.mozilla.org/pub/firefox/releases';
+ break;
+ }
+ switch (channel) {
+ case FirefoxChannel.NIGHTLY:
+ return `${baseUrl}/${resolveDownloadPath(platform, resolvedBuildId).join('/')}`;
+ case FirefoxChannel.DEVEDITION:
+ case FirefoxChannel.BETA:
+ case FirefoxChannel.STABLE:
+ case FirefoxChannel.ESR:
+ return `${baseUrl}/${resolvedBuildId}/${platformName(platform)}/en-US/${archive(platform, resolvedBuildId)}`;
+ }
}
export function resolveDownloadPath(
platform: BrowserPlatform,
buildId: string
): string[] {
- return [archive(platform, buildId)];
+ return [archiveNightly(platform, buildId)];
}
export function relativeExecutablePath(
platform: BrowserPlatform,
- _buildId: string
+ buildId: string
): string {
- switch (platform) {
- case BrowserPlatform.MAC_ARM:
- case BrowserPlatform.MAC:
- return path.join('Firefox Nightly.app', 'Contents', 'MacOS', 'firefox');
- case BrowserPlatform.LINUX:
- return path.join('firefox', 'firefox');
- case BrowserPlatform.WIN32:
- case BrowserPlatform.WIN64:
- return path.join('firefox', 'firefox.exe');
+ const [channel] = parseBuildId(buildId);
+ switch (channel) {
+ case FirefoxChannel.NIGHTLY:
+ switch (platform) {
+ case BrowserPlatform.MAC_ARM:
+ case BrowserPlatform.MAC:
+ return path.join(
+ 'Firefox Nightly.app',
+ 'Contents',
+ 'MacOS',
+ 'firefox'
+ );
+ case BrowserPlatform.LINUX:
+ return path.join('firefox', 'firefox');
+ case BrowserPlatform.WIN32:
+ case BrowserPlatform.WIN64:
+ return path.join('firefox', 'firefox.exe');
+ }
+ case FirefoxChannel.BETA:
+ case FirefoxChannel.DEVEDITION:
+ case FirefoxChannel.ESR:
+ case FirefoxChannel.STABLE:
+ switch (platform) {
+ case BrowserPlatform.MAC_ARM:
+ case BrowserPlatform.MAC:
+ return path.join('Firefox.app', 'Contents', 'MacOS', 'firefox');
+ case BrowserPlatform.LINUX:
+ return path.join('firefox', 'firefox');
+ case BrowserPlatform.WIN32:
+ case BrowserPlatform.WIN64:
+ return path.join('core', 'firefox.exe');
+ }
}
}
+export enum FirefoxChannel {
+ STABLE = 'stable',
+ ESR = 'esr',
+ DEVEDITION = 'devedition',
+ BETA = 'beta',
+ NIGHTLY = 'nightly',
+}
+
export async function resolveBuildId(
- channel: 'FIREFOX_NIGHTLY' = 'FIREFOX_NIGHTLY'
+ channel: FirefoxChannel = FirefoxChannel.NIGHTLY
): Promise<string> {
+ const channelToVersionKey = {
+ [FirefoxChannel.ESR]: 'FIREFOX_ESR',
+ [FirefoxChannel.STABLE]: 'LATEST_FIREFOX_VERSION',
+ [FirefoxChannel.DEVEDITION]: 'FIREFOX_DEVEDITION',
+ [FirefoxChannel.BETA]: 'FIREFOX_DEVEDITION',
+ [FirefoxChannel.NIGHTLY]: 'FIREFOX_NIGHTLY',
+ };
const versions = (await getJSON(
new URL('https://product-details.mozilla.org/1.0/firefox_versions.json')
)) as Record<string, string>;
- const version = versions[channel];
+ const version = versions[channelToVersionKey[channel]];
if (!version) {
throw new Error(`Channel ${channel} is not found.`);
}
- return version;
+ return channel + '_' + version;
}
export async function createProfile(options: ProfileOptions): Promise<void> {
diff --git a/remote/test/puppeteer/packages/browsers/src/browser-data/types.ts b/remote/test/puppeteer/packages/browsers/src/browser-data/types.ts
index ac72661a2d..4990350659 100644
--- a/remote/test/puppeteer/packages/browsers/src/browser-data/types.ts
+++ b/remote/test/puppeteer/packages/browsers/src/browser-data/types.ts
@@ -36,9 +36,12 @@ export enum BrowserPlatform {
*/
export enum BrowserTag {
CANARY = 'canary',
+ NIGHTLY = 'nightly',
BETA = 'beta',
DEV = 'dev',
+ DEVEDITION = 'devedition',
STABLE = 'stable',
+ ESR = 'esr',
LATEST = 'latest',
}
diff --git a/remote/test/puppeteer/packages/browsers/src/fileUtil.ts b/remote/test/puppeteer/packages/browsers/src/fileUtil.ts
index 50a6897853..28168afad1 100644
--- a/remote/test/puppeteer/packages/browsers/src/fileUtil.ts
+++ b/remote/test/puppeteer/packages/browsers/src/fileUtil.ts
@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import {exec as execChildProcess} from 'child_process';
+import {exec as execChildProcess, spawnSync} from 'child_process';
import {createReadStream} from 'fs';
import {mkdir, readdir} from 'fs/promises';
import * as path from 'path';
@@ -30,6 +30,18 @@ export async function unpackArchive(
} else if (archivePath.endsWith('.dmg')) {
await mkdir(folderPath);
await installDMG(archivePath, folderPath);
+ } else if (archivePath.endsWith('.exe')) {
+ // Firefox on Windows.
+ const result = spawnSync(archivePath, [`/ExtractDir=${folderPath}`], {
+ env: {
+ __compat_layer: 'RunAsInvoker',
+ },
+ });
+ if (result.status !== 0) {
+ throw new Error(
+ `Failed to extract ${archivePath} to ${folderPath}: ${result.output}`
+ );
+ }
} else {
throw new Error(`Unsupported archive format: ${archivePath}`);
}
diff --git a/remote/test/puppeteer/packages/browsers/src/httpUtil.ts b/remote/test/puppeteer/packages/browsers/src/httpUtil.ts
index 96f7fc9f36..084bae599c 100644
--- a/remote/test/puppeteer/packages/browsers/src/httpUtil.ts
+++ b/remote/test/puppeteer/packages/browsers/src/httpUtil.ts
@@ -54,6 +54,9 @@ export function httpRequest(
res.headers.location
) {
httpRequest(new URL(res.headers.location), method, response);
+ // consume response data to free up memory
+ // And prevents the connection from being kept alive
+ res.resume();
} else {
response(res);
}
diff --git a/remote/test/puppeteer/packages/browsers/src/install.ts b/remote/test/puppeteer/packages/browsers/src/install.ts
index e78b2c3461..f585021df2 100644
--- a/remote/test/puppeteer/packages/browsers/src/install.ts
+++ b/remote/test/puppeteer/packages/browsers/src/install.ts
@@ -92,6 +92,11 @@ export interface InstallOptions {
* @defaultValue `true`
*/
unpack?: boolean;
+ /**
+ * @internal
+ * @defaultValue `false`
+ */
+ forceFallbackForTesting?: boolean;
}
/**
@@ -125,6 +130,10 @@ export async function install(
try {
return await installUrl(url, options);
} catch (err) {
+ // If custom baseUrl is provided, do not fall back to CfT dashboard.
+ if (options.baseUrl && !options.forceFallbackForTesting) {
+ throw err;
+ }
debugInstall(`Error downloading from ${url}.`);
switch (options.browser) {
case Browser.CHROME:
diff --git a/remote/test/puppeteer/packages/browsers/src/launch.ts b/remote/test/puppeteer/packages/browsers/src/launch.ts
index dfb0fbf633..434f34c0f6 100644
--- a/remote/test/puppeteer/packages/browsers/src/launch.ts
+++ b/remote/test/puppeteer/packages/browsers/src/launch.ts
@@ -135,6 +135,59 @@ export const CDP_WEBSOCKET_ENDPOINT_REGEX =
export const WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX =
/^WebDriver BiDi listening on (ws:\/\/.*)$/;
+type EventHandler = (...args: any[]) => void;
+const processListeners = new Map<string, EventHandler[]>();
+const dispatchers = {
+ exit: (...args: any[]) => {
+ processListeners.get('exit')?.forEach(handler => {
+ return handler(...args);
+ });
+ },
+ SIGINT: (...args: any[]) => {
+ processListeners.get('SIGINT')?.forEach(handler => {
+ return handler(...args);
+ });
+ },
+ SIGHUP: (...args: any[]) => {
+ processListeners.get('SIGHUP')?.forEach(handler => {
+ return handler(...args);
+ });
+ },
+ SIGTERM: (...args: any[]) => {
+ processListeners.get('SIGTERM')?.forEach(handler => {
+ return handler(...args);
+ });
+ },
+};
+
+function subscribeToProcessEvent(
+ event: 'exit' | 'SIGINT' | 'SIGHUP' | 'SIGTERM',
+ handler: EventHandler
+): void {
+ const listeners = processListeners.get(event) || [];
+ if (listeners.length === 0) {
+ process.on(event, dispatchers[event]);
+ }
+ listeners.push(handler);
+ processListeners.set(event, listeners);
+}
+
+function unsubscribeFromProcessEvent(
+ event: 'exit' | 'SIGINT' | 'SIGHUP' | 'SIGTERM',
+ handler: EventHandler
+): void {
+ const listeners = processListeners.get(event) || [];
+ const existingListenerIdx = listeners.indexOf(handler);
+ if (existingListenerIdx === -1) {
+ return;
+ }
+ listeners.splice(existingListenerIdx, 1);
+ processListeners.set(event, listeners);
+ if (listeners.length === 0) {
+ process.off(event, dispatchers[event]);
+ }
+}
+
/**
* @public
*/
@@ -201,15 +254,15 @@ export class Process {
this.#browserProcess.stderr?.pipe(process.stderr);
this.#browserProcess.stdout?.pipe(process.stdout);
}
- process.on('exit', this.#onDriverProcessExit);
+ subscribeToProcessEvent('exit', this.#onDriverProcessExit);
if (opts.handleSIGINT) {
- process.on('SIGINT', this.#onDriverProcessSignal);
+ subscribeToProcessEvent('SIGINT', this.#onDriverProcessSignal);
}
if (opts.handleSIGTERM) {
- process.on('SIGTERM', this.#onDriverProcessSignal);
+ subscribeToProcessEvent('SIGTERM', this.#onDriverProcessSignal);
}
if (opts.handleSIGHUP) {
- process.on('SIGHUP', this.#onDriverProcessSignal);
+ subscribeToProcessEvent('SIGHUP', this.#onDriverProcessSignal);
}
if (opts.onExit) {
this.#onExitHook = opts.onExit;
@@ -262,10 +315,10 @@ export class Process {
}
#clearListeners(): void {
- process.off('exit', this.#onDriverProcessExit);
- process.off('SIGINT', this.#onDriverProcessSignal);
- process.off('SIGTERM', this.#onDriverProcessSignal);
- process.off('SIGHUP', this.#onDriverProcessSignal);
+ unsubscribeFromProcessEvent('exit', this.#onDriverProcessExit);
+ unsubscribeFromProcessEvent('SIGINT', this.#onDriverProcessSignal);
+ unsubscribeFromProcessEvent('SIGTERM', this.#onDriverProcessSignal);
+ unsubscribeFromProcessEvent('SIGHUP', this.#onDriverProcessSignal);
}
#onDriverProcessExit = (_code: number) => {
diff --git a/remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts b/remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts
index f669d1c57c..d7c9dfbf4a 100644
--- a/remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts
+++ b/remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts
@@ -138,6 +138,7 @@ describe('Chrome install', () => {
});
it('falls back to the chrome-for-testing dashboard URLs if URL is not available', async function () {
+ this.timeout(60000);
const expectedOutputPath = path.join(
tmpDir,
'chrome',
@@ -150,6 +151,7 @@ describe('Chrome install', () => {
platform: BrowserPlatform.LINUX,
buildId: testChromeBuildId,
baseUrl: 'https://127.0.0.1',
+ forceFallbackForTesting: true,
});
assert.strictEqual(fs.existsSync(expectedOutputPath), true);
});
diff --git a/remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts b/remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts
index c420d9e0b6..dc3d118d67 100644
--- a/remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts
+++ b/remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts
@@ -77,7 +77,6 @@ describe('Chrome', () => {
'--disable-renderer-backgrounding',
'--disable-sync',
'--enable-automation',
- '--enable-features=NetworkServiceInProcess2',
'--export-tagged-pdf',
'--force-color-profile=srgb',
'--headless=new',
diff --git a/remote/test/puppeteer/packages/browsers/test/src/chromium/launch.spec.ts b/remote/test/puppeteer/packages/browsers/test/src/chromium/launch.spec.ts
index 8cf7c8255b..e382761981 100644
--- a/remote/test/puppeteer/packages/browsers/test/src/chromium/launch.spec.ts
+++ b/remote/test/puppeteer/packages/browsers/test/src/chromium/launch.spec.ts
@@ -77,7 +77,6 @@ describe('Chromium', () => {
'--disable-renderer-backgrounding',
'--disable-sync',
'--enable-automation',
- '--enable-features=NetworkServiceInProcess2',
'--export-tagged-pdf',
'--force-color-profile=srgb',
'--headless=new',
diff --git a/remote/test/puppeteer/packages/browsers/test/src/firefox/firefox-data.spec.ts b/remote/test/puppeteer/packages/browsers/test/src/firefox/firefox-data.spec.ts
index b5dd2db0b3..22962b8a68 100644
--- a/remote/test/puppeteer/packages/browsers/test/src/firefox/firefox-data.spec.ts
+++ b/remote/test/puppeteer/packages/browsers/test/src/firefox/firefox-data.spec.ts
@@ -18,7 +18,7 @@ import {
} from '../../../lib/cjs/browser-data/firefox.js';
describe('Firefox', () => {
- it('should resolve download URLs', () => {
+ it('should resolve download URLs for Nightly', () => {
assert.strictEqual(
resolveDownloadUrl(BrowserPlatform.LINUX, '111.0a1'),
'https://archive.mozilla.org/pub/firefox/nightly/latest-mozilla-central/firefox-111.0a1.en-US.linux-x86_64.tar.bz2'
@@ -41,6 +41,75 @@ describe('Firefox', () => {
);
});
+ it('should resolve download URLs for beta', () => {
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.LINUX, 'beta_115.0b8'),
+ 'https://archive.mozilla.org/pub/firefox/releases/115.0b8/linux-x86_64/en-US/firefox-115.0b8.tar.bz2'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC, 'beta_115.0b8'),
+ 'https://archive.mozilla.org/pub/firefox/releases/115.0b8/mac/en-US/Firefox 115.0b8.dmg'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC_ARM, 'beta_115.0b8'),
+ 'https://archive.mozilla.org/pub/firefox/releases/115.0b8/mac/en-US/Firefox 115.0b8.dmg'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN32, 'beta_115.0b8'),
+ 'https://archive.mozilla.org/pub/firefox/releases/115.0b8/win32/en-US/Firefox Setup 115.0b8.exe'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN64, 'beta_115.0b8'),
+ 'https://archive.mozilla.org/pub/firefox/releases/115.0b8/win64/en-US/Firefox Setup 115.0b8.exe'
+ );
+ });
+
+ it('should resolve download URLs for stable', () => {
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.LINUX, 'stable_111.0.1'),
+ 'https://archive.mozilla.org/pub/firefox/releases/111.0.1/linux-x86_64/en-US/firefox-111.0.1.tar.bz2'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC, 'stable_111.0.1'),
+ 'https://archive.mozilla.org/pub/firefox/releases/111.0.1/mac/en-US/Firefox 111.0.1.dmg'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC_ARM, 'stable_111.0.1'),
+ 'https://archive.mozilla.org/pub/firefox/releases/111.0.1/mac/en-US/Firefox 111.0.1.dmg'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN32, 'stable_111.0.1'),
+ 'https://archive.mozilla.org/pub/firefox/releases/111.0.1/win32/en-US/Firefox Setup 111.0.1.exe'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN64, 'stable_111.0.1'),
+ 'https://archive.mozilla.org/pub/firefox/releases/111.0.1/win64/en-US/Firefox Setup 111.0.1.exe'
+ );
+ });
+
+ it('should resolve download URLs for devedition', () => {
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.LINUX, 'devedition_115.0b8'),
+ 'https://archive.mozilla.org/pub/devedition/releases/115.0b8/linux-x86_64/en-US/firefox-115.0b8.tar.bz2'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC, 'devedition_115.0b8'),
+ 'https://archive.mozilla.org/pub/devedition/releases/115.0b8/mac/en-US/Firefox 115.0b8.dmg'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC_ARM, 'devedition_115.0b8'),
+ 'https://archive.mozilla.org/pub/devedition/releases/115.0b8/mac/en-US/Firefox 115.0b8.dmg'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN32, 'devedition_115.0b8'),
+ 'https://archive.mozilla.org/pub/devedition/releases/115.0b8/win32/en-US/Firefox Setup 115.0b8.exe'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN64, 'devedition_115.0b8'),
+ 'https://archive.mozilla.org/pub/devedition/releases/115.0b8/win64/en-US/Firefox Setup 115.0b8.exe'
+ );
+ });
+
it('should resolve executable paths', () => {
assert.strictEqual(
relativeExecutablePath(BrowserPlatform.LINUX, '111.0a1'),
diff --git a/remote/test/puppeteer/packages/browsers/test/src/versions.ts b/remote/test/puppeteer/packages/browsers/test/src/versions.ts
index 83f26ca41a..097973b82d 100644
--- a/remote/test/puppeteer/packages/browsers/test/src/versions.ts
+++ b/remote/test/puppeteer/packages/browsers/test/src/versions.ts
@@ -6,6 +6,6 @@
export const testChromeBuildId = '121.0.6167.85';
export const testChromiumBuildId = '1083080';
-export const testFirefoxBuildId = '125.0a1';
+export const testFirefoxBuildId = '126.0a1';
export const testChromeDriverBuildId = '121.0.6167.85';
export const testChromeHeadlessShellBuildId = '121.0.6167.85';
diff --git a/remote/test/puppeteer/packages/ng-schematics/.eslintignore b/remote/test/puppeteer/packages/ng-schematics/.eslintignore
index 8424d7004d..c4c05af793 100644
--- a/remote/test/puppeteer/packages/ng-schematics/.eslintignore
+++ b/remote/test/puppeteer/packages/ng-schematics/.eslintignore
@@ -1,5 +1,5 @@
# Ignore File that will be copied to Angular
/files/
-# Ignore sandbox enviroment
+# Ignore sandbox environment
./sandbox/
diff --git a/remote/test/puppeteer/packages/ng-schematics/README.md b/remote/test/puppeteer/packages/ng-schematics/README.md
index 975f74a704..2c84b7bc9e 100644
--- a/remote/test/puppeteer/packages/ng-schematics/README.md
+++ b/remote/test/puppeteer/packages/ng-schematics/README.md
@@ -85,7 +85,7 @@ node tools/smoke.mjs
The schematics utilize `@angular-devkit/schematics/testing` for verifying correct file creation and `package.json` updates. To execute the test suit:
-```bash
+```bash npm2yarn
npm run test
```
diff --git a/remote/test/puppeteer/packages/puppeteer-core/CHANGELOG.md b/remote/test/puppeteer/packages/puppeteer-core/CHANGELOG.md
index 5076077c9f..eeaecef87d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/CHANGELOG.md
+++ b/remote/test/puppeteer/packages/puppeteer-core/CHANGELOG.md
@@ -20,6 +20,104 @@ All notable changes to this project will be documented in this file. See [standa
* dependencies
* @puppeteer/browsers bumped from 1.5.1 to 1.6.0
+## [22.6.5](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.6.4...puppeteer-core-v22.6.5) (2024-04-15)
+
+
+### Bug Fixes
+
+* remove NetworkServiceInProcess2 set by default ([#12261](https://github.com/puppeteer/puppeteer/issues/12261)) ([ff4f70f](https://github.com/puppeteer/puppeteer/commit/ff4f70f4ae7ca8deb0becbec2e49b35322dba336)), closes [#12257](https://github.com/puppeteer/puppeteer/issues/12257)
+* use setImmediate to reduce flakiness when processing events ([#12264](https://github.com/puppeteer/puppeteer/issues/12264)) ([73403b3](https://github.com/puppeteer/puppeteer/commit/73403b323ec0dd8a08c164cb2c07751451215788))
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * @puppeteer/browsers bumped from 2.2.1 to 2.2.2
+
+## [22.6.4](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.6.3...puppeteer-core-v22.6.4) (2024-04-11)
+
+
+### Bug Fixes
+
+* **a11y:** query only unignored nodes ([#12224](https://github.com/puppeteer/puppeteer/issues/12224)) ([e20cd64](https://github.com/puppeteer/puppeteer/commit/e20cd64fff374c4113777912c193f4a5d7d04297))
+* retain stale main frame for longer ([#12225](https://github.com/puppeteer/puppeteer/issues/12225)) ([aa5b182](https://github.com/puppeteer/puppeteer/commit/aa5b1824a5c82005fcfc05b002facfbbb9810f8f))
+* roll to Chrome 123.0.6312.122 (r1262506) ([#12248](https://github.com/puppeteer/puppeteer/issues/12248)) ([50b6659](https://github.com/puppeteer/puppeteer/commit/50b66591e70a7b6907d86594d7dacee6e76afc2d))
+* **webdriver:** suppress error for error code errors ([5f7254c](https://github.com/puppeteer/puppeteer/commit/5f7254c41c7c1bda82477488f10254d204373d54))
+
+## [22.6.3](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.6.2...puppeteer-core-v22.6.3) (2024-04-05)
+
+
+### Bug Fixes
+
+* check if executablePath exists ([#12201](https://github.com/puppeteer/puppeteer/issues/12201)) ([4ec0280](https://github.com/puppeteer/puppeteer/commit/4ec02800801d441238d6160a933f88f98c5f7165))
+* roll to Chrome 123.0.6312.105 (r1262506) ([#12209](https://github.com/puppeteer/puppeteer/issues/12209)) ([ee31272](https://github.com/puppeteer/puppeteer/commit/ee312721152cce61a9e9cb2b78b71b40c4fa9e64))
+* wait for fonts before pdf printing ([#12175](https://github.com/puppeteer/puppeteer/issues/12175)) ([59bffce](https://github.com/puppeteer/puppeteer/commit/59bffce9720b4d5e5204b26b335735e0a5ca9cc1))
+* **webdriver:** request redirect chain ([#12168](https://github.com/puppeteer/puppeteer/issues/12168)) ([d345055](https://github.com/puppeteer/puppeteer/commit/d345055af3c63effbdfb2751274b9d7137b8a308))
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * @puppeteer/browsers bumped from 2.2.0 to 2.2.1
+
+## [22.6.2](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.6.1...puppeteer-core-v22.6.2) (2024-03-28)
+
+
+### Bug Fixes
+
+* roll to Chrome 123.0.6312.86 (r1262506) ([#12156](https://github.com/puppeteer/puppeteer/issues/12156)) ([29637f2](https://github.com/puppeteer/puppeteer/commit/29637f2b8f2dc1d684dbbb62d1a75857e016be33))
+
+## [22.6.1](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.6.0...puppeteer-core-v22.6.1) (2024-03-25)
+
+
+### Bug Fixes
+
+* apply timeout to waiting for a response ([#12142](https://github.com/puppeteer/puppeteer/issues/12142)) ([ac1767d](https://github.com/puppeteer/puppeteer/commit/ac1767da0b4214ced548a62dd737e2863f92c715))
+* reload should not resolve early on fragment navigations ([#12119](https://github.com/puppeteer/puppeteer/issues/12119)) ([d476031](https://github.com/puppeteer/puppeteer/commit/d4760317c9bd359c9ecdb5f36231449dae16a8d2))
+* support clip in ElementHandle.screenshot ([#12115](https://github.com/puppeteer/puppeteer/issues/12115)) ([b096ffa](https://github.com/puppeteer/puppeteer/commit/b096ffaa0359078bd5748b53b67e87c9453c7196))
+
+## [22.6.0](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.5.0...puppeteer-core-v22.6.0) (2024-03-20)
+
+
+### Features
+
+* roll to Chrome 123.0.6312.58 (r1262506) ([#12110](https://github.com/puppeteer/puppeteer/issues/12110)) ([6f5b3bc](https://github.com/puppeteer/puppeteer/commit/6f5b3bc9b88c6d3204dda396f8963591ea6eb883))
+
+
+### Bug Fixes
+
+* **webdriver:** emit RequestServedFromCache for requests ([#12104](https://github.com/puppeteer/puppeteer/issues/12104)) ([6ba6bef](https://github.com/puppeteer/puppeteer/commit/6ba6bef1b99742543942cef2f6c840bd543f5dee))
+
+## [22.5.0](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.4.1...puppeteer-core-v22.5.0) (2024-03-15)
+
+
+### Features
+
+* deprecate `Frame.prototype.name` ([#12084](https://github.com/puppeteer/puppeteer/issues/12084)) ([0203b45](https://github.com/puppeteer/puppeteer/commit/0203b4533dfec503f9ce7fcd07c3493021a9cecb))
+
+
+### Bug Fixes
+
+* fix keyboard.sendCharacter ([#12088](https://github.com/puppeteer/puppeteer/issues/12088)) ([2637622](https://github.com/puppeteer/puppeteer/commit/26376224d557ce30c911f670c5e7625dd1a1df72))
+* roll to Chrome 122.0.6261.128 (r1250580) ([#12078](https://github.com/puppeteer/puppeteer/issues/12078)) ([ef7a9ea](https://github.com/puppeteer/puppeteer/commit/ef7a9eac16dcb466b220bcb0bc06a1eac3492354))
+* **webdriver:** emit CDP events ([#12058](https://github.com/puppeteer/puppeteer/issues/12058)) ([9afe424](https://github.com/puppeteer/puppeteer/commit/9afe4246bb58c30a13215a254f9326935b24ece3))
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * @puppeteer/browsers bumped from 2.1.0 to 2.2.0
+
+## [22.4.1](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.4.0...puppeteer-core-v22.4.1) (2024-03-08)
+
+
+### Bug Fixes
+
+* roll to Chrome 122.0.6261.111 (r1250580) ([#12055](https://github.com/puppeteer/puppeteer/issues/12055)) ([9b31bca](https://github.com/puppeteer/puppeteer/commit/9b31bca01adeb2ce04c97d9fcb3c6b6461469f07))
+
## [22.4.0](https://github.com/puppeteer/puppeteer/compare/puppeteer-core-v22.3.0...puppeteer-core-v22.4.0) (2024-03-05)
diff --git a/remote/test/puppeteer/packages/puppeteer-core/Herebyfile.mjs b/remote/test/puppeteer/packages/puppeteer-core/Herebyfile.mjs
index 972a080ba0..426d908c0c 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/Herebyfile.mjs
+++ b/remote/test/puppeteer/packages/puppeteer-core/Herebyfile.mjs
@@ -110,8 +110,10 @@ export const buildTask = task({
bundle: true,
allowOverwrite: true,
format,
- target: 'node16',
- minify: true,
+ target: 'node18',
+ // Do not minify for readability and leave minification to
+ // consumers.
+ minify: false,
legalComments: 'inline',
})
);
diff --git a/remote/test/puppeteer/packages/puppeteer-core/package.json b/remote/test/puppeteer/packages/puppeteer-core/package.json
index 1d4d564c4f..fe0eedbe24 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/package.json
+++ b/remote/test/puppeteer/packages/puppeteer-core/package.json
@@ -1,6 +1,6 @@
{
"name": "puppeteer-core",
- "version": "22.4.0",
+ "version": "22.6.5",
"description": "A high-level API to control headless Chrome over the DevTools Protocol",
"keywords": [
"puppeteer",
@@ -119,11 +119,10 @@
"author": "The Chromium Authors",
"license": "Apache-2.0",
"dependencies": {
- "@puppeteer/browsers": "2.1.0",
- "chromium-bidi": "0.5.12",
- "cross-fetch": "4.0.0",
+ "@puppeteer/browsers": "2.2.2",
+ "chromium-bidi": "0.5.17",
"debug": "4.3.4",
- "devtools-protocol": "0.0.1249869",
+ "devtools-protocol": "0.0.1262051",
"ws": "8.16.0"
},
"devDependencies": {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/Browser.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/Browser.ts
index 6d7ea19d49..67835e4aa2 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/Browser.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/Browser.ts
@@ -197,7 +197,7 @@ export interface DebugInfo {
* - connected to via {@link Puppeteer.connect} or
* - launched by {@link PuppeteerNode.launch}.
*
- * {@link Browser} {@link EventEmitter | emits} various events which are
+ * {@link Browser} {@link EventEmitter.emit | emits} various events which are
* documented in the {@link BrowserEvent} enum.
*
* @example Using a {@link Browser} to create a {@link Page}:
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/BrowserContext.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/BrowserContext.ts
index 5e6a5d5d5c..7cedd5f3a4 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/BrowserContext.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/BrowserContext.ts
@@ -151,7 +151,7 @@ export abstract class BrowserContext extends EventEmitter<BrowserContextEvents>
*
* @deprecated In Chrome, the
* {@link Browser.defaultBrowserContext | default browser context} can also be
- * "icognito" if configured via the arguments and in such cases this getter
+ * "incognito" if configured via the arguments and in such cases this getter
* returns wrong results (see
* https://github.com/puppeteer/puppeteer/issues/8836). Also, the term
* "incognito" is not applicable to other browsers. To migrate, check the
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/CDPSession.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/CDPSession.ts
index 3a1fdf1e24..d80b9d9013 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/CDPSession.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/CDPSession.ts
@@ -74,7 +74,7 @@ export interface CommandOptions {
* @example
*
* ```ts
- * const client = await page.target().createCDPSession();
+ * const client = await page.createCDPSession();
* await client.send('Animation.enable');
* client.on('Animation.animationCreated', () =>
* console.log('Animation created!')
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/ElementHandle.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/ElementHandle.ts
index 9b1326f998..84e61f33c1 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/ElementHandle.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/ElementHandle.ts
@@ -623,7 +623,7 @@ export abstract class ElementHandle<
/**
* This method scrolls element into view if needed, and then
- * uses {@link Page} to hover over the center of the element.
+ * uses {@link Page.mouse} to hover over the center of the element.
* If the element is detached from DOM, the method throws an error.
*/
@throwIfDisposed()
@@ -636,7 +636,7 @@ export abstract class ElementHandle<
/**
* This method scrolls element into view if needed, and then
- * uses {@link Page | Page.mouse} to click in the center of the element.
+ * uses {@link Page.mouse} to click in the center of the element.
* If the element is detached from DOM, the method throws an error.
*/
@throwIfDisposed()
@@ -1236,9 +1236,9 @@ export abstract class ElementHandle<
this: ElementHandle<Element>,
options: Readonly<ElementScreenshotOptions> = {}
): Promise<string | Buffer> {
- const {scrollIntoView = true} = options;
+ const {scrollIntoView = true, clip} = options;
- let clip = await this.#nonEmptyVisibleBoundingBox();
+ let elementClip = await this.#nonEmptyVisibleBoundingBox();
const page = this.frame.page();
@@ -1247,7 +1247,7 @@ export abstract class ElementHandle<
await this.scrollIntoViewIfNeeded();
// We measure again just in case.
- clip = await this.#nonEmptyVisibleBoundingBox();
+ elementClip = await this.#nonEmptyVisibleBoundingBox();
}
const [pageLeft, pageTop] = await this.evaluate(() => {
@@ -1259,10 +1259,16 @@ export abstract class ElementHandle<
window.visualViewport.pageTop,
] as const;
});
- clip.x += pageLeft;
- clip.y += pageTop;
+ elementClip.x += pageLeft;
+ elementClip.y += pageTop;
+ if (clip) {
+ elementClip.x += clip.x;
+ elementClip.y += clip.y;
+ elementClip.height = clip.height;
+ elementClip.width = clip.width;
+ }
- return await page.screenshot({...options, clip});
+ return await page.screenshot({...options, clip: elementClip});
}
async #nonEmptyVisibleBoundingBox() {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/Frame.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/Frame.ts
index 19b5eb7fa0..ff476cd054 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/Frame.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/Frame.ts
@@ -18,7 +18,6 @@ import type {PuppeteerLifeCycleEvent} from '../cdp/LifecycleWatcher.js';
import {EventEmitter, type EventType} from '../common/EventEmitter.js';
import {getQueryHandlerAndSelector} from '../common/GetQueryHandler.js';
import {transposeIterableHandle} from '../common/HandleIterator.js';
-import {LazyArg} from '../common/LazyArg.js';
import type {
Awaitable,
EvaluateFunc,
@@ -63,6 +62,10 @@ export interface WaitForOptions {
* @defaultValue `'load'`
*/
waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[];
+ /**
+ * @internal
+ */
+ ignoreSameDocumentNavigation?: boolean;
}
/**
@@ -405,7 +408,7 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
}
/**
- * @internal
+ * @returns The frame element associated with this frame (if any).
*/
@throwIfDetached
async frameElement(): Promise<HandleFor<HTMLIFrameElement> | null> {
@@ -447,7 +450,7 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
}
/**
- * Behaves identically to {@link Page.evaluate} except it's run within the
+ * Behaves identically to {@link Page.evaluate} except it's run within
* the context of this frame.
*
* @see {@link Page.evaluate} for details.
@@ -760,6 +763,13 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
* @remarks
* This value is calculated once when the frame is created, and will not
* update if the attribute is changed later.
+ *
+ * @deprecated Use
+ *
+ * ```ts
+ * const element = await frame.frameElement();
+ * const nameOrId = await element.evaluate(frame => frame.name ?? frame.id);
+ * ```
*/
name(): string {
return this._name || '';
@@ -830,42 +840,37 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
return await this.mainRealm().transferHandle(
await this.isolatedRealm().evaluateHandle(
- async ({Deferred}, {url, id, type, content}) => {
- const deferred = Deferred.create<void>();
- const script = document.createElement('script');
- script.type = type;
- script.text = content;
- if (url) {
- script.src = url;
- script.addEventListener(
- 'load',
- () => {
- return deferred.resolve();
- },
- {once: true}
- );
+ async ({url, id, type, content}) => {
+ return await new Promise<HTMLScriptElement>((resolve, reject) => {
+ const script = document.createElement('script');
+ script.type = type;
+ script.text = content;
script.addEventListener(
'error',
event => {
- deferred.reject(
- new Error(event.message ?? 'Could not load script')
- );
+ reject(new Error(event.message ?? 'Could not load script'));
},
{once: true}
);
- } else {
- deferred.resolve();
- }
- if (id) {
- script.id = id;
- }
- document.head.appendChild(script);
- await deferred.valueOrThrow();
- return script;
+ if (id) {
+ script.id = id;
+ }
+ if (url) {
+ script.src = url;
+ script.addEventListener(
+ 'load',
+ () => {
+ resolve(script);
+ },
+ {once: true}
+ );
+ document.head.appendChild(script);
+ } else {
+ document.head.appendChild(script);
+ resolve(script);
+ }
+ });
},
- LazyArg.create(context => {
- return context.puppeteerUtil;
- }),
{...options, type, content}
)
);
@@ -915,46 +920,42 @@ export abstract class Frame extends EventEmitter<FrameEvents> {
}
return await this.mainRealm().transferHandle(
- await this.isolatedRealm().evaluateHandle(
- async ({Deferred}, {url, content}) => {
- const deferred = Deferred.create<void>();
- let element: HTMLStyleElement | HTMLLinkElement;
- if (!url) {
- element = document.createElement('style');
- element.appendChild(document.createTextNode(content!));
- } else {
- const link = document.createElement('link');
- link.rel = 'stylesheet';
- link.href = url;
- element = link;
+ await this.isolatedRealm().evaluateHandle(async ({url, content}) => {
+ return await new Promise<HTMLStyleElement | HTMLLinkElement>(
+ (resolve, reject) => {
+ let element: HTMLStyleElement | HTMLLinkElement;
+ if (!url) {
+ element = document.createElement('style');
+ element.appendChild(document.createTextNode(content!));
+ } else {
+ const link = document.createElement('link');
+ link.rel = 'stylesheet';
+ link.href = url;
+ element = link;
+ }
+ element.addEventListener(
+ 'load',
+ () => {
+ resolve(element);
+ },
+ {once: true}
+ );
+ element.addEventListener(
+ 'error',
+ event => {
+ reject(
+ new Error(
+ (event as ErrorEvent).message ?? 'Could not load style'
+ )
+ );
+ },
+ {once: true}
+ );
+ document.head.appendChild(element);
+ return element;
}
- element.addEventListener(
- 'load',
- () => {
- deferred.resolve();
- },
- {once: true}
- );
- element.addEventListener(
- 'error',
- event => {
- deferred.reject(
- new Error(
- (event as ErrorEvent).message ?? 'Could not load style'
- )
- );
- },
- {once: true}
- );
- document.head.appendChild(element);
- await deferred.valueOrThrow();
- return element;
- },
- LazyArg.create(context => {
- return context.puppeteerUtil;
- }),
- options
- )
+ );
+ }, options)
);
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPRequest.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPRequest.ts
index d72f088686..674abc61f2 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPRequest.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPRequest.ts
@@ -5,6 +5,10 @@
*/
import type {Protocol} from 'devtools-protocol';
+import type {ProtocolError} from '../common/Errors.js';
+import {debugError} from '../common/util.js';
+import {assert} from '../util/assert.js';
+
import type {CDPSession} from './CDPSession.js';
import type {Frame} from './Frame.js';
import type {HTTPResponse} from './HTTPResponse.js';
@@ -118,6 +122,29 @@ export abstract class HTTPRequest {
_redirectChain: HTTPRequest[] = [];
/**
+ * @internal
+ */
+ protected interception: {
+ enabled: boolean;
+ handled: boolean;
+ handlers: Array<() => void | PromiseLike<any>>;
+ resolutionState: InterceptResolutionState;
+ requestOverrides: ContinueRequestOverrides;
+ response: Partial<ResponseForRequest> | null;
+ abortReason: Protocol.Network.ErrorReason | null;
+ } = {
+ enabled: false,
+ handled: false,
+ handlers: [],
+ resolutionState: {
+ action: InterceptResolutionAction.None,
+ },
+ requestOverrides: {},
+ response: null,
+ abortReason: null,
+ };
+
+ /**
* Warning! Using this client can break Puppeteer. Use with caution.
*
* @experimental
@@ -139,18 +166,27 @@ export abstract class HTTPRequest {
* if the interception is allowed to continue (ie, `abort()` and
* `respond()` aren't called).
*/
- abstract continueRequestOverrides(): ContinueRequestOverrides;
+ continueRequestOverrides(): ContinueRequestOverrides {
+ assert(this.interception.enabled, 'Request Interception is not enabled!');
+ return this.interception.requestOverrides;
+ }
/**
* The `ResponseForRequest` that gets used if the
* interception is allowed to respond (ie, `abort()` is not called).
*/
- abstract responseForRequest(): Partial<ResponseForRequest> | null;
+ responseForRequest(): Partial<ResponseForRequest> | null {
+ assert(this.interception.enabled, 'Request Interception is not enabled!');
+ return this.interception.response;
+ }
/**
* The most recent reason for aborting the request
*/
- abstract abortErrorReason(): Protocol.Network.ErrorReason | null;
+ abortErrorReason(): Protocol.Network.ErrorReason | null {
+ assert(this.interception.enabled, 'Request Interception is not enabled!');
+ return this.interception.abortReason;
+ }
/**
* An InterceptResolutionState object describing the current resolution
@@ -163,13 +199,23 @@ export abstract class HTTPRequest {
* InterceptResolutionAction is one of: `abort`, `respond`, `continue`,
* `disabled`, `none`, or `already-handled`.
*/
- abstract interceptResolutionState(): InterceptResolutionState;
+ interceptResolutionState(): InterceptResolutionState {
+ if (!this.interception.enabled) {
+ return {action: InterceptResolutionAction.Disabled};
+ }
+ if (this.interception.handled) {
+ return {action: InterceptResolutionAction.AlreadyHandled};
+ }
+ return {...this.interception.resolutionState};
+ }
/**
* Is `true` if the intercept resolution has already been handled,
* `false` otherwise.
*/
- abstract isInterceptResolutionHandled(): boolean;
+ isInterceptResolutionHandled(): boolean {
+ return this.interception.handled;
+ }
/**
* Adds an async request handler to the processing queue.
@@ -177,15 +223,51 @@ export abstract class HTTPRequest {
* but they are guaranteed to resolve before the request interception
* is finalized.
*/
- abstract enqueueInterceptAction(
+ enqueueInterceptAction(
pendingHandler: () => void | PromiseLike<unknown>
- ): void;
+ ): void {
+ this.interception.handlers.push(pendingHandler);
+ }
+
+ /**
+ * @internal
+ */
+ abstract _abort(
+ errorReason: Protocol.Network.ErrorReason | null
+ ): Promise<void>;
+
+ /**
+ * @internal
+ */
+ abstract _respond(response: Partial<ResponseForRequest>): Promise<void>;
+
+ /**
+ * @internal
+ */
+ abstract _continue(overrides: ContinueRequestOverrides): Promise<void>;
/**
* Awaits pending interception handlers and then decides how to fulfill
* the request interception.
*/
- abstract finalizeInterceptions(): Promise<void>;
+ async finalizeInterceptions(): Promise<void> {
+ await this.interception.handlers.reduce((promiseChain, interceptAction) => {
+ return promiseChain.then(interceptAction);
+ }, Promise.resolve());
+ this.interception.handlers = []; // TODO: verify this is correct top let gc run
+ const {action} = this.interceptResolutionState();
+ switch (action) {
+ case 'abort':
+ return await this._abort(this.interception.abortReason);
+ case 'respond':
+ if (this.interception.response === null) {
+ throw new Error('Response is missing for the interception');
+ }
+ return await this._respond(this.interception.response);
+ case 'continue':
+ return await this._continue(this.interception.requestOverrides);
+ }
+ }
/**
* Contains the request's resource type as it was perceived by the rendering
@@ -323,10 +405,42 @@ export abstract class HTTPRequest {
*
* Exception is immediately thrown if the request interception is not enabled.
*/
- abstract continue(
- overrides?: ContinueRequestOverrides,
+ async continue(
+ overrides: ContinueRequestOverrides = {},
priority?: number
- ): Promise<void>;
+ ): Promise<void> {
+ // Request interception is not supported for data: urls.
+ if (this.url().startsWith('data:')) {
+ return;
+ }
+ assert(this.interception.enabled, 'Request Interception is not enabled!');
+ assert(!this.interception.handled, 'Request is already handled!');
+ if (priority === undefined) {
+ return await this._continue(overrides);
+ }
+ this.interception.requestOverrides = overrides;
+ if (
+ this.interception.resolutionState.priority === undefined ||
+ priority > this.interception.resolutionState.priority
+ ) {
+ this.interception.resolutionState = {
+ action: InterceptResolutionAction.Continue,
+ priority,
+ };
+ return;
+ }
+ if (priority === this.interception.resolutionState.priority) {
+ if (
+ this.interception.resolutionState.action === 'abort' ||
+ this.interception.resolutionState.action === 'respond'
+ ) {
+ return;
+ }
+ this.interception.resolutionState.action =
+ InterceptResolutionAction.Continue;
+ }
+ return;
+ }
/**
* Fulfills a request with the given response.
@@ -360,10 +474,38 @@ export abstract class HTTPRequest {
*
* Exception is immediately thrown if the request interception is not enabled.
*/
- abstract respond(
+ async respond(
response: Partial<ResponseForRequest>,
priority?: number
- ): Promise<void>;
+ ): Promise<void> {
+ // Mocking responses for dataURL requests is not currently supported.
+ if (this.url().startsWith('data:')) {
+ return;
+ }
+ assert(this.interception.enabled, 'Request Interception is not enabled!');
+ assert(!this.interception.handled, 'Request is already handled!');
+ if (priority === undefined) {
+ return await this._respond(response);
+ }
+ this.interception.response = response;
+ if (
+ this.interception.resolutionState.priority === undefined ||
+ priority > this.interception.resolutionState.priority
+ ) {
+ this.interception.resolutionState = {
+ action: InterceptResolutionAction.Respond,
+ priority,
+ };
+ return;
+ }
+ if (priority === this.interception.resolutionState.priority) {
+ if (this.interception.resolutionState.action === 'abort') {
+ return;
+ }
+ this.interception.resolutionState.action =
+ InterceptResolutionAction.Respond;
+ }
+ }
/**
* Aborts a request.
@@ -379,7 +521,33 @@ export abstract class HTTPRequest {
* {@link Page.setRequestInterception}. If it is not enabled, this method will
* throw an exception immediately.
*/
- abstract abort(errorCode?: ErrorCode, priority?: number): Promise<void>;
+ async abort(
+ errorCode: ErrorCode = 'failed',
+ priority?: number
+ ): Promise<void> {
+ // Request interception is not supported for data: urls.
+ if (this.url().startsWith('data:')) {
+ return;
+ }
+ const errorReason = errorReasons[errorCode];
+ assert(errorReason, 'Unknown error code: ' + errorCode);
+ assert(this.interception.enabled, 'Request Interception is not enabled!');
+ assert(!this.interception.handled, 'Request is already handled!');
+ if (priority === undefined) {
+ return await this._abort(errorReason);
+ }
+ this.interception.abortReason = errorReason;
+ if (
+ this.interception.resolutionState.priority === undefined ||
+ priority >= this.interception.resolutionState.priority
+ ) {
+ this.interception.resolutionState = {
+ action: InterceptResolutionAction.Abort,
+ priority,
+ };
+ return;
+ }
+ }
}
/**
@@ -513,3 +681,33 @@ export const STATUS_TEXTS: Record<string, string> = {
'510': 'Not Extended',
'511': 'Network Authentication Required',
} as const;
+
+const errorReasons: Record<ErrorCode, Protocol.Network.ErrorReason> = {
+ aborted: 'Aborted',
+ accessdenied: 'AccessDenied',
+ addressunreachable: 'AddressUnreachable',
+ blockedbyclient: 'BlockedByClient',
+ blockedbyresponse: 'BlockedByResponse',
+ connectionaborted: 'ConnectionAborted',
+ connectionclosed: 'ConnectionClosed',
+ connectionfailed: 'ConnectionFailed',
+ connectionrefused: 'ConnectionRefused',
+ connectionreset: 'ConnectionReset',
+ internetdisconnected: 'InternetDisconnected',
+ namenotresolved: 'NameNotResolved',
+ timedout: 'TimedOut',
+ failed: 'Failed',
+} as const;
+
+/**
+ * @internal
+ */
+export function handleError(error: ProtocolError): void {
+ if (error.originalMessage.includes('Invalid header')) {
+ throw error;
+ }
+ // In certain cases, protocol will return error if the request was
+ // already canceled or the page was closed. We should tolerate these
+ // errors.
+ debugError(error);
+}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPResponse.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPResponse.ts
index 906479eb43..f5ea35722e 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPResponse.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/HTTPResponse.ts
@@ -81,11 +81,18 @@ export abstract class HTTPResponse {
/**
* Promise which resolves to a buffer with response body.
+ *
+ * @remarks
+ *
+ * The buffer might be re-encoded by the browser
+ * based on HTTP-headers or other heuristics. If the browser
+ * failed to detect the correct encoding, the buffer might
+ * be encoded incorrectly. See https://github.com/puppeteer/puppeteer/issues/6478.
*/
abstract buffer(): Promise<Buffer>;
/**
- * Promise which resolves to a text representation of response body.
+ * Promise which resolves to a text (utf8) representation of response body.
*/
async text(): Promise<string> {
const content = await this.buffer();
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/Page.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/Page.ts
index b094d14b2f..1c1874a856 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/Page.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/Page.ts
@@ -32,7 +32,7 @@ import type {HTTPResponse} from '../api/HTTPResponse.js';
import type {Accessibility} from '../cdp/Accessibility.js';
import type {Coverage} from '../cdp/Coverage.js';
import type {DeviceRequestPrompt} from '../cdp/DeviceRequestPrompt.js';
-import type {Credentials, NetworkConditions} from '../cdp/NetworkManager.js';
+import type {NetworkConditions} from '../cdp/NetworkManager.js';
import type {Tracing} from '../cdp/Tracing.js';
import type {ConsoleMessage} from '../common/ConsoleMessage.js';
import type {
@@ -134,6 +134,14 @@ export interface Metrics {
/**
* @public
*/
+export interface Credentials {
+ username: string;
+ password: string;
+}
+
+/**
+ * @public
+ */
export interface WaitForNetworkIdleOptions extends WaitTimeoutOptions {
/**
* Time (in milliseconds) the network should be idle.
@@ -274,7 +282,7 @@ export interface ScreenshotOptions {
*/
path?: string;
/**
- * Specifies the region of the page to clip.
+ * Specifies the region of the page/element to clip.
*/
clip?: ScreenshotClip;
/**
@@ -644,7 +652,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
*
* @deprecated We no longer support intercepting drag payloads. Use the new
* drag APIs found on {@link ElementHandle} to drag (or just use the
- * {@link Page | Page.mouse}).
+ * {@link Page.mouse}).
*/
abstract isDragInterceptionEnabled(): boolean;
@@ -875,7 +883,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
*
* @deprecated We no longer support intercepting drag payloads. Use the new
* drag APIs found on {@link ElementHandle} to drag (or just use the
- * {@link Page | Page.mouse}).
+ * {@link Page.mouse}).
*/
abstract setDragInterception(enabled: boolean): Promise<void>;
@@ -1342,7 +1350,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
*
* Functions installed via `page.exposeFunction` survive navigations.
*
- * :::note
+ * :::
*
* @example
* An example of adding an `md5` function into the page:
@@ -2116,7 +2124,8 @@ export abstract class Page extends EventEmitter<PageEvents> {
*
* This is either the viewport set with the previous {@link Page.setViewport}
* call or the default viewport set via
- * {@link BrowserConnectOptions | BrowserConnectOptions.defaultViewport}.
+ * {@link BrowserConnectOptions.defaultViewport |
+ * BrowserConnectOptions.defaultViewport}.
*/
abstract viewport(): Viewport | null;
@@ -2458,7 +2467,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
};
if (options.type === undefined && options.path !== undefined) {
const filePath = options.path;
- // Note we cannot use Node.js here due to browser compatability.
+ // Note we cannot use Node.js here due to browser compatibility.
const extension = filePath
.slice(filePath.lastIndexOf('.') + 1)
.toLowerCase();
@@ -2609,7 +2618,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
/**
* This method fetches an element with `selector`, scrolls it into view if
- * needed, and then uses {@link Page | Page.mouse} to click in the center of the
+ * needed, and then uses {@link Page.mouse} to click in the center of the
* element. If there's no element matching `selector`, the method throws an
* error.
*
@@ -2660,7 +2669,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
/**
* This method fetches an element with `selector`, scrolls it into view if
- * needed, and then uses {@link Page | Page.mouse}
+ * needed, and then uses {@link Page.mouse}
* to hover over the center of the element.
* If there's no element matching `selector`, the method throws an error.
* @param selector - A
@@ -2709,7 +2718,7 @@ export abstract class Page extends EventEmitter<PageEvents> {
/**
* This method fetches an element with `selector`, scrolls it into view if
- * needed, and then uses {@link Page | Page.touchscreen}
+ * needed, and then uses {@link Page.touchscreen}
* to tap in the center of the element.
* If there's no element matching `selector`, the method throws an error.
* @param selector - A
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/api/locators/locators.ts b/remote/test/puppeteer/packages/puppeteer-core/src/api/locators/locators.ts
index d88cc0a17d..ea77dc94a1 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/api/locators/locators.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/api/locators/locators.ts
@@ -172,19 +172,23 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
});
},
retryAndRaceWithSignalAndTimer: <T>(
- signal?: AbortSignal
+ signal?: AbortSignal,
+ cause?: Error
): OperatorFunction<T, T> => {
const candidates = [];
if (signal) {
candidates.push(
fromEvent(signal, 'abort').pipe(
map(() => {
+ if (signal.reason instanceof Error) {
+ signal.reason.cause = cause;
+ }
throw signal.reason;
})
)
);
}
- candidates.push(timeout(this._timeout));
+ candidates.push(timeout(this._timeout, cause));
return pipe(
retry({delay: RETRY_DELAY}),
raceWith<T, never[]>(...candidates)
@@ -368,6 +372,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<LocatorClickOptions>
): Observable<void> {
const signal = options?.signal;
+ const cause = new Error('Locator.click');
return this._wait(options).pipe(
this.operators.conditions(
[
@@ -388,7 +393,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
})
);
}),
- this.operators.retryAndRaceWithSignalAndTimer(signal)
+ this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
);
}
@@ -398,6 +403,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<ActionOptions>
): Observable<void> {
const signal = options?.signal;
+ const cause = new Error('Locator.fill');
return this._wait(options).pipe(
this.operators.conditions(
[
@@ -521,7 +527,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
})
);
}),
- this.operators.retryAndRaceWithSignalAndTimer(signal)
+ this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
);
}
@@ -530,6 +536,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<ActionOptions>
): Observable<void> {
const signal = options?.signal;
+ const cause = new Error('Locator.hover');
return this._wait(options).pipe(
this.operators.conditions(
[
@@ -549,7 +556,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
})
);
}),
- this.operators.retryAndRaceWithSignalAndTimer(signal)
+ this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
);
}
@@ -558,6 +565,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
options?: Readonly<LocatorScrollOptions>
): Observable<void> {
const signal = options?.signal;
+ const cause = new Error('Locator.scroll');
return this._wait(options).pipe(
this.operators.conditions(
[
@@ -590,7 +598,7 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
})
);
}),
- this.operators.retryAndRaceWithSignalAndTimer(signal)
+ this.operators.retryAndRaceWithSignalAndTimer(signal, cause)
);
}
@@ -617,9 +625,10 @@ export abstract class Locator<T> extends EventEmitter<LocatorEvents> {
* @public
*/
async waitHandle(options?: Readonly<ActionOptions>): Promise<HandleFor<T>> {
+ const cause = new Error('Locator.waitHandle');
return await firstValueFrom(
this._wait(options).pipe(
- this.operators.retryAndRaceWithSignalAndTimer(options?.signal)
+ this.operators.retryAndRaceWithSignalAndTimer(options?.signal, cause)
)
);
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/BidiOverCdp.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/BidiOverCdp.ts
index ace35a52b0..6f58d3e6a9 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/BidiOverCdp.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/BidiOverCdp.ts
@@ -25,9 +25,7 @@ const bidiServerLogger = (prefix: string, ...args: unknown[]): void => {
*/
export async function connectBidiOverCdp(
cdp: CdpConnection,
- // TODO: replace with `BidiMapper.MapperOptions`, once it's exported in
- // https://github.com/puppeteer/puppeteer/pull/11415.
- options: {acceptInsecureCerts: boolean}
+ options: BidiMapper.MapperOptions
): Promise<BidiConnection> {
const transportBiDi = new NoOpTransport();
const cdpConnectionAdapter = new CdpConnectionAdapter(cdp);
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Browser.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Browser.ts
index 8798d8325d..2e6b80459b 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Browser.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Browser.ts
@@ -19,7 +19,6 @@ import {
import {BrowserContextEvent} from '../api/BrowserContext.js';
import type {Page} from '../api/Page.js';
import type {Target} from '../api/Target.js';
-import {UnsupportedOperation} from '../common/Errors.js';
import {EventEmitter} from '../common/EventEmitter.js';
import {debugError} from '../common/util.js';
import type {Viewport} from '../common/Viewport.js';
@@ -50,7 +49,7 @@ export class BidiBrowser extends Browser {
readonly protocol = 'webDriverBiDi';
// TODO: Update generator to include fully module
- static readonly subscribeModules: string[] = [
+ static readonly subscribeModules: [string, ...string[]] = [
'browsingContext',
'network',
'log',
@@ -133,8 +132,8 @@ export class BidiBrowser extends Browser {
return !this.#browserName.toLocaleLowerCase().includes('firefox');
}
- override userAgent(): never {
- throw new UnsupportedOperation();
+ override async userAgent(): Promise<string> {
+ return this.#browserCore.session.capabilities.userAgent;
}
#createBrowserContext(userContext: UserContext) {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/CDPSession.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/CDPSession.ts
index 1e0c503498..5782056259 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/CDPSession.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/CDPSession.ts
@@ -5,6 +5,7 @@
*/
import type ProtocolMapping from 'devtools-protocol/types/protocol-mapping.js';
+import type {CommandOptions} from '../api/CDPSession.js';
import {CDPSession} from '../api/CDPSession.js';
import type {Connection as CdpConnection} from '../cdp/Connection.js';
import {TargetCloseError, UnsupportedOperation} from '../common/Errors.js';
@@ -61,7 +62,8 @@ export class BidiCdpSession extends CDPSession {
override async send<T extends keyof ProtocolMapping.Commands>(
method: T,
- params?: ProtocolMapping.Commands[T]['paramsType'][0]
+ params?: ProtocolMapping.Commands[T]['paramsType'][0],
+ options?: CommandOptions
): Promise<ProtocolMapping.Commands[T]['returnType']> {
if (this.#connection === undefined) {
throw new UnsupportedOperation(
@@ -74,11 +76,15 @@ export class BidiCdpSession extends CDPSession {
);
}
const session = await this.#sessionId.valueOrThrow();
- const {result} = await this.#connection.send('cdp.sendCommand', {
- method: method,
- params: params,
- session,
- });
+ const {result} = await this.#connection.send(
+ 'cdp.sendCommand',
+ {
+ method: method,
+ params: params,
+ session,
+ },
+ options?.timeout
+ );
return result.result;
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Connection.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Connection.ts
index dd688c309a..5e19390371 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Connection.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Connection.ts
@@ -97,11 +97,12 @@ export class BidiConnection
send<T extends keyof Commands>(
method: T,
- params: Commands[T]['params']
+ params: Commands[T]['params'],
+ timeout?: number
): Promise<{result: Commands[T]['returnType']}> {
assert(!this.#closed, 'Protocol error: Connection closed.');
- return this.#callbacks.create(method, this.#timeout, id => {
+ return this.#callbacks.create(method, timeout ?? this.#timeout, id => {
const stringifiedMessage = JSON.stringify({
id,
method,
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Frame.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Frame.ts
index f2bfd5f64e..ce44c0637d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Frame.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Frame.ts
@@ -37,6 +37,7 @@ import {TargetCloseError, UnsupportedOperation} from '../common/Errors.js';
import type {TimeoutSettings} from '../common/TimeoutSettings.js';
import type {Awaitable, NodeFor} from '../common/types.js';
import {debugError, fromEmitterEvent, timeout} from '../common/util.js';
+import {isErrorLike} from '../util/ErrorLike.js';
import {BidiCdpSession} from './CDPSession.js';
import type {BrowsingContext} from './core/BrowsingContext.js';
@@ -114,13 +115,13 @@ export class BidiFrame extends Frame {
this.browsingContext.on('request', ({request}) => {
const httpRequest = BidiHTTPRequest.from(request, this);
request.once('success', () => {
- // SAFETY: BidiHTTPRequest will create this before here.
this.page().trustedEmitter.emit(PageEvent.RequestFinished, httpRequest);
});
request.once('error', () => {
this.page().trustedEmitter.emit(PageEvent.RequestFailed, httpRequest);
});
+ void httpRequest.finalizeInterceptions();
});
this.browsingContext.on('navigation', ({navigation}) => {
@@ -300,10 +301,18 @@ export class BidiFrame extends Frame {
// readiness=interactive.
//
// Related: https://bugzilla.mozilla.org/show_bug.cgi?id=1846601
- this.browsingContext.navigate(
- url,
- Bidi.BrowsingContext.ReadinessState.Interactive
- ),
+ this.browsingContext
+ .navigate(url, Bidi.BrowsingContext.ReadinessState.Interactive)
+ .catch(error => {
+ if (
+ isErrorLike(error) &&
+ error.message.includes('net::ERR_HTTP_RESPONSE_CODE_FAILURE')
+ ) {
+ return;
+ }
+
+ throw error;
+ }),
]).catch(
rewriteNavigationError(
url,
@@ -351,11 +360,7 @@ export class BidiFrame extends Frame {
}),
raceWith(
fromEmitterEvent(navigation, 'fragment'),
- fromEmitterEvent(navigation, 'failed').pipe(
- map(({url}) => {
- throw new Error(`Navigation failed: ${url}`);
- })
- ),
+ fromEmitterEvent(navigation, 'failed'),
fromEmitterEvent(navigation, 'aborted').pipe(
map(({url}) => {
throw new Error(`Navigation aborted: ${url}`);
@@ -401,11 +406,9 @@ export class BidiFrame extends Frame {
if (!request) {
return null;
}
- const httpRequest = requests.get(request)!;
- const lastRedirect = httpRequest.redirectChain().at(-1);
- return (
- lastRedirect !== undefined ? lastRedirect : httpRequest
- ).response();
+ const lastRequest = request.lastRedirect ?? request;
+ const httpRequest = requests.get(lastRequest)!;
+ return httpRequest.response();
}),
raceWith(
timeout(ms),
@@ -471,6 +474,7 @@ export class BidiFrame extends Frame {
targetId: this._id,
flatten: true,
});
+ await this.browsingContext.subscribe([Bidi.ChromiumBidi.BiDiModule.Cdp]);
return new BidiCdpSession(this, sessionId);
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPRequest.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPRequest.ts
index e75bb0cf3c..39ce4fec4b 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPRequest.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPRequest.ts
@@ -10,7 +10,12 @@ import type {
ContinueRequestOverrides,
ResponseForRequest,
} from '../api/HTTPRequest.js';
-import {HTTPRequest, type ResourceType} from '../api/HTTPRequest.js';
+import {
+ HTTPRequest,
+ STATUS_TEXTS,
+ type ResourceType,
+ handleError,
+} from '../api/HTTPRequest.js';
import {PageEvent} from '../api/Page.js';
import {UnsupportedOperation} from '../common/Errors.js';
@@ -26,41 +31,61 @@ export const requests = new WeakMap<Request, BidiHTTPRequest>();
export class BidiHTTPRequest extends HTTPRequest {
static from(
bidiRequest: Request,
- frame: BidiFrame | undefined
+ frame: BidiFrame,
+ redirect?: BidiHTTPRequest
): BidiHTTPRequest {
- const request = new BidiHTTPRequest(bidiRequest, frame);
+ const request = new BidiHTTPRequest(bidiRequest, frame, redirect);
request.#initialize();
return request;
}
-
- #redirect: BidiHTTPRequest | undefined;
+ #redirectBy: BidiHTTPRequest | undefined;
#response: BidiHTTPResponse | null = null;
override readonly id: string;
- readonly #frame: BidiFrame | undefined;
+ readonly #frame: BidiFrame;
readonly #request: Request;
- private constructor(request: Request, frame: BidiFrame | undefined) {
+ private constructor(
+ request: Request,
+ frame: BidiFrame,
+ redirectBy?: BidiHTTPRequest
+ ) {
super();
requests.set(request, this);
+ this.interception.enabled = request.isBlocked;
+
this.#request = request;
this.#frame = frame;
+ this.#redirectBy = redirectBy;
this.id = request.id;
}
override get client(): CDPSession {
- throw new UnsupportedOperation();
+ return this.#frame.client;
}
#initialize() {
this.#request.on('redirect', request => {
- this.#redirect = BidiHTTPRequest.from(request, this.#frame);
+ const httpRequest = BidiHTTPRequest.from(request, this.#frame, this);
+ void httpRequest.finalizeInterceptions();
});
this.#request.once('success', data => {
this.#response = BidiHTTPResponse.from(data, this);
});
-
- this.#frame?.page().trustedEmitter.emit(PageEvent.Request, this);
+ this.#request.on('authenticate', this.#handleAuthentication);
+
+ this.#frame.page().trustedEmitter.emit(PageEvent.Request, this);
+
+ if (Object.keys(this.#extraHTTPHeaders).length) {
+ this.interception.handlers.push(async () => {
+ await this.continue(
+ {
+ headers: this.headers(),
+ },
+ 0
+ );
+ });
+ }
}
override url(): string {
@@ -68,7 +93,7 @@ export class BidiHTTPRequest extends HTTPRequest {
}
override resourceType(): ResourceType {
- return this.initiator().type.toLowerCase() as ResourceType;
+ throw new UnsupportedOperation();
}
override method(): string {
@@ -87,12 +112,19 @@ export class BidiHTTPRequest extends HTTPRequest {
throw new UnsupportedOperation();
}
+ get #extraHTTPHeaders(): Record<string, string> {
+ return this.#frame?.page()._extraHTTPHeaders ?? {};
+ }
+
override headers(): Record<string, string> {
const headers: Record<string, string> = {};
for (const header of this.#request.headers) {
headers[header.name.toLowerCase()] = header.value.value;
}
- return headers;
+ return {
+ ...headers,
+ ...this.#extraHTTPHeaders,
+ };
}
override response(): BidiHTTPResponse | null {
@@ -115,65 +147,167 @@ export class BidiHTTPRequest extends HTTPRequest {
}
override redirectChain(): BidiHTTPRequest[] {
- if (this.#redirect === undefined) {
+ if (this.#redirectBy === undefined) {
return [];
}
- const redirects = [this.#redirect];
+ const redirects = [this.#redirectBy];
for (const redirect of redirects) {
- if (redirect.#redirect !== undefined) {
- redirects.push(redirect.#redirect);
+ if (redirect.#redirectBy !== undefined) {
+ redirects.push(redirect.#redirectBy);
}
}
return redirects;
}
- override enqueueInterceptAction(
- pendingHandler: () => void | PromiseLike<unknown>
- ): void {
- // Execute the handler when interception is not supported
- void pendingHandler();
+ override frame(): BidiFrame {
+ return this.#frame;
}
- override frame(): BidiFrame | null {
- return this.#frame ?? null;
+ override async continue(
+ overrides?: ContinueRequestOverrides,
+ priority?: number | undefined
+ ): Promise<void> {
+ return await super.continue(
+ {
+ headers: Object.keys(this.#extraHTTPHeaders).length
+ ? this.headers()
+ : undefined,
+ ...overrides,
+ },
+ priority
+ );
}
- override continueRequestOverrides(): never {
- throw new UnsupportedOperation();
+ override async _continue(
+ overrides: ContinueRequestOverrides = {}
+ ): Promise<void> {
+ const headers: Bidi.Network.Header[] = getBidiHeaders(overrides.headers);
+ this.interception.handled = true;
+
+ return await this.#request
+ .continueRequest({
+ url: overrides.url,
+ method: overrides.method,
+ body: overrides.postData
+ ? {
+ type: 'base64',
+ value: btoa(overrides.postData),
+ }
+ : undefined,
+ headers: headers.length > 0 ? headers : undefined,
+ })
+ .catch(error => {
+ this.interception.handled = false;
+ return handleError(error);
+ });
}
- override continue(_overrides: ContinueRequestOverrides = {}): never {
- throw new UnsupportedOperation();
- }
-
- override responseForRequest(): never {
- throw new UnsupportedOperation();
+ override async _abort(): Promise<void> {
+ this.interception.handled = true;
+ return await this.#request.failRequest().catch(error => {
+ this.interception.handled = false;
+ throw error;
+ });
}
- override abortErrorReason(): never {
- throw new UnsupportedOperation();
- }
+ override async _respond(
+ response: Partial<ResponseForRequest>,
+ _priority?: number
+ ): Promise<void> {
+ this.interception.handled = true;
+ const responseBody: string | undefined =
+ response.body && response.body instanceof Uint8Array
+ ? response.body.toString('base64')
+ : response.body
+ ? btoa(response.body)
+ : undefined;
+
+ const headers: Bidi.Network.Header[] = getBidiHeaders(response.headers);
+ const hasContentLength = headers.some(header => {
+ return header.name === 'content-length';
+ });
- override interceptResolutionState(): never {
- throw new UnsupportedOperation();
- }
+ if (response.contentType) {
+ headers.push({
+ name: 'content-type',
+ value: {
+ type: 'string',
+ value: response.contentType,
+ },
+ });
+ }
- override isInterceptResolutionHandled(): never {
- throw new UnsupportedOperation();
+ if (responseBody && !hasContentLength) {
+ const encoder = new TextEncoder();
+ headers.push({
+ name: 'content-length',
+ value: {
+ type: 'string',
+ value: String(encoder.encode(responseBody).byteLength),
+ },
+ });
+ }
+ const status = response.status || 200;
+
+ return await this.#request
+ .provideResponse({
+ statusCode: status,
+ headers: headers.length > 0 ? headers : undefined,
+ reasonPhrase: STATUS_TEXTS[status],
+ body: responseBody
+ ? {
+ type: 'base64',
+ value: responseBody,
+ }
+ : undefined,
+ })
+ .catch(error => {
+ this.interception.handled = false;
+ throw error;
+ });
}
- override finalizeInterceptions(): never {
- throw new UnsupportedOperation();
- }
+ #authenticationHandled = false;
+ #handleAuthentication = async () => {
+ if (!this.#frame) {
+ return;
+ }
+ const credentials = this.#frame.page()._credentials;
+ if (credentials && !this.#authenticationHandled) {
+ this.#authenticationHandled = true;
+ void this.#request.continueWithAuth({
+ action: 'provideCredentials',
+ credentials: {
+ type: 'password',
+ username: credentials.username,
+ password: credentials.password,
+ },
+ });
+ } else {
+ void this.#request.continueWithAuth({
+ action: 'cancel',
+ });
+ }
+ };
+}
- override abort(): never {
- throw new UnsupportedOperation();
+function getBidiHeaders(rawHeaders?: Record<string, unknown>) {
+ const headers: Bidi.Network.Header[] = [];
+ for (const [name, value] of Object.entries(rawHeaders ?? [])) {
+ if (!Object.is(value, undefined)) {
+ const values = Array.isArray(value) ? value : [value];
+
+ for (const value of values) {
+ headers.push({
+ name: name.toLowerCase(),
+ value: {
+ type: 'string',
+ value: String(value),
+ },
+ });
+ }
+ }
}
- override respond(
- _response: Partial<ResponseForRequest>,
- _priority?: number
- ): never {
- throw new UnsupportedOperation();
- }
+ return headers;
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPResponse.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPResponse.ts
index bad44ff089..ffb2ac298a 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPResponse.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/HTTPResponse.ts
@@ -40,6 +40,12 @@ export class BidiHTTPResponse extends HTTPResponse {
}
#initialize() {
+ if (this.#data.fromCache) {
+ this.#request
+ .frame()
+ ?.page()
+ .trustedEmitter.emit(PageEvent.RequestServedFromCache, this.#request);
+ }
this.#request.frame()?.page().trustedEmitter.emit(PageEvent.Response, this);
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Page.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Page.ts
index c662496a18..55a2e79310 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Page.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/Page.ts
@@ -13,8 +13,9 @@ import type {BoundingBox} from '../api/ElementHandle.js';
import type {WaitForOptions} from '../api/Frame.js';
import type {HTTPResponse} from '../api/HTTPResponse.js';
import type {
- MediaFeature,
+ Credentials,
GeolocationOptions,
+ MediaFeature,
PageEvents,
} from '../api/Page.js';
import {
@@ -27,13 +28,22 @@ import {Accessibility} from '../cdp/Accessibility.js';
import {Coverage} from '../cdp/Coverage.js';
import {EmulationManager} from '../cdp/EmulationManager.js';
import {Tracing} from '../cdp/Tracing.js';
-import type {Cookie, CookieParam, CookieSameSite} from '../common/Cookie.js';
-import type {DeleteCookiesRequest} from '../common/Cookie.js';
+import type {
+ Cookie,
+ CookieParam,
+ CookieSameSite,
+ DeleteCookiesRequest,
+} from '../common/Cookie.js';
import {UnsupportedOperation} from '../common/Errors.js';
import {EventEmitter} from '../common/EventEmitter.js';
import type {PDFOptions} from '../common/PDFOptions.js';
import type {Awaitable} from '../common/types.js';
-import {evaluationString, parsePDFOptions, timeout} from '../common/util.js';
+import {
+ evaluationString,
+ isString,
+ parsePDFOptions,
+ timeout,
+} from '../common/util.js';
import type {Viewport} from '../common/Viewport.js';
import {assert} from '../util/assert.js';
import {bubble} from '../util/decorators.js';
@@ -43,7 +53,6 @@ import type {BidiBrowser} from './Browser.js';
import type {BidiBrowserContext} from './BrowserContext.js';
import type {BidiCdpSession} from './CDPSession.js';
import type {BrowsingContext} from './core/BrowsingContext.js';
-import {BidiElementHandle} from './ElementHandle.js';
import {BidiFrame} from './Frame.js';
import type {BidiHTTPResponse} from './HTTPResponse.js';
import {BidiKeyboard, BidiMouse, BidiTouchscreen} from './Input.js';
@@ -161,21 +170,28 @@ export class BidiPage extends Page {
}
async focusedFrame(): Promise<BidiFrame> {
- using frame = await this.mainFrame()
+ using handle = (await this.mainFrame()
.isolatedRealm()
.evaluateHandle(() => {
- let frame: HTMLIFrameElement | undefined;
- let win: Window | null = window;
- while (win?.document.activeElement instanceof HTMLIFrameElement) {
- frame = win.document.activeElement;
- win = frame.contentWindow;
+ let win = window;
+ while (
+ win.document.activeElement instanceof win.HTMLIFrameElement ||
+ win.document.activeElement instanceof win.HTMLFrameElement
+ ) {
+ if (win.document.activeElement.contentWindow === null) {
+ break;
+ }
+ win = win.document.activeElement.contentWindow as typeof win;
}
- return frame;
- });
- if (!(frame instanceof BidiElementHandle)) {
- return this.mainFrame();
- }
- return await frame.contentFrame();
+ return win;
+ })) as BidiJSHandle<Window & typeof globalThis>;
+ const value = handle.remoteValue();
+ assert(value.type === 'window');
+ const frame = this.frames().find(frame => {
+ return frame._id === value.value.context;
+ });
+ assert(frame);
+ return frame;
}
override frames(): BidiFrame[] {
@@ -311,6 +327,17 @@ export class BidiPage extends Page {
preferCSSPageSize,
} = parsePDFOptions(options, 'cm');
const pageRanges = ranges ? ranges.split(', ') : [];
+
+ await firstValueFrom(
+ from(
+ this.mainFrame()
+ .isolatedRealm()
+ .evaluate(() => {
+ return document.fonts.ready;
+ })
+ ).pipe(raceWith(timeout(ms)))
+ );
+
const data = await firstValueFrom(
from(
this.#frame.browsingContext.print({
@@ -489,8 +516,71 @@ export class BidiPage extends Page {
return [...this.#workers];
}
- override setRequestInterception(): never {
- throw new UnsupportedOperation();
+ #userInterception?: string;
+ override async setRequestInterception(enable: boolean): Promise<void> {
+ this.#userInterception = await this.#toggleInterception(
+ [Bidi.Network.InterceptPhase.BeforeRequestSent],
+ this.#userInterception,
+ enable
+ );
+ }
+
+ /**
+ * @internal
+ */
+ _extraHTTPHeaders: Record<string, string> = {};
+ #extraHeadersInterception?: string;
+ override async setExtraHTTPHeaders(
+ headers: Record<string, string>
+ ): Promise<void> {
+ const extraHTTPHeaders: Record<string, string> = {};
+ for (const [key, value] of Object.entries(headers)) {
+ assert(
+ isString(value),
+ `Expected value of header "${key}" to be String, but "${typeof value}" is found.`
+ );
+ extraHTTPHeaders[key.toLowerCase()] = value;
+ }
+ this._extraHTTPHeaders = extraHTTPHeaders;
+
+ this.#extraHeadersInterception = await this.#toggleInterception(
+ [Bidi.Network.InterceptPhase.BeforeRequestSent],
+ this.#extraHeadersInterception,
+ Boolean(Object.keys(this._extraHTTPHeaders).length)
+ );
+ }
+
+ /**
+ * @internal
+ */
+ _credentials: Credentials | null = null;
+ #authInterception?: string;
+ override async authenticate(credentials: Credentials | null): Promise<void> {
+ this.#authInterception = await this.#toggleInterception(
+ [Bidi.Network.InterceptPhase.AuthRequired],
+ this.#authInterception,
+ Boolean(credentials)
+ );
+
+ this._credentials = credentials;
+ }
+
+ async #toggleInterception(
+ phases: [Bidi.Network.InterceptPhase, ...Bidi.Network.InterceptPhase[]],
+ interception: string | undefined,
+ expected: boolean
+ ): Promise<string | undefined> {
+ if (expected && !interception) {
+ return await this.#frame.browsingContext.addIntercept({
+ phases,
+ });
+ } else if (!expected && interception) {
+ await this.#frame.browsingContext.userContext.browser.removeIntercept(
+ interception
+ );
+ return;
+ }
+ return interception;
}
override setDragInterception(): never {
@@ -603,14 +693,6 @@ export class BidiPage extends Page {
await this.#frame.removeExposedFunction(name);
}
- override authenticate(): never {
- throw new UnsupportedOperation();
- }
-
- override setExtraHTTPHeaders(): never {
- throw new UnsupportedOperation();
- }
-
override metrics(): never {
throw new UnsupportedOperation();
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Browser.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Browser.ts
index efeabc3a59..5f51895585 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Browser.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Browser.ts
@@ -51,20 +51,17 @@ export class Browser extends EventEmitter<{
return browser;
}
- // keep-sorted start
#closed = false;
#reason: string | undefined;
readonly #disposables = new DisposableStack();
readonly #userContexts = new Map<string, UserContext>();
readonly session: Session;
readonly #sharedWorkers = new Map<string, SharedWorkerRealm>();
- // keep-sorted end
private constructor(session: Session) {
super();
- // keep-sorted start
+
this.session = session;
- // keep-sorted end
}
async #initialize() {
@@ -141,7 +138,6 @@ export class Browser extends EventEmitter<{
return userContext;
}
- // keep-sorted start block=yes
get closed(): boolean {
return this.#closed;
}
@@ -158,7 +154,6 @@ export class Browser extends EventEmitter<{
get userContexts(): Iterable<UserContext> {
return this.#userContexts.values();
}
- // keep-sorted end
@inertIfDisposed
dispose(reason?: string, closed = false): void {
@@ -203,6 +198,16 @@ export class Browser extends EventEmitter<{
// SAFETY: By definition of `disposed`, `#reason` is defined.
return browser.#reason!;
})
+ async removeIntercept(intercept: Bidi.Network.Intercept): Promise<void> {
+ await this.session.send('network.removeIntercept', {
+ intercept,
+ });
+ }
+
+ @throwIfDisposed<Browser>(browser => {
+ // SAFETY: By definition of `disposed`, `#reason` is defined.
+ return browser.#reason!;
+ })
async removePreloadScript(script: string): Promise<void> {
await this.session.send('script.removePreloadScript', {
script,
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/BrowsingContext.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/BrowsingContext.ts
index 07309576a3..ed3a235f5d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/BrowsingContext.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/BrowsingContext.ts
@@ -21,6 +21,14 @@ import {UserPrompt} from './UserPrompt.js';
/**
* @internal
*/
+export type AddInterceptOptions = Omit<
+ Bidi.Network.AddInterceptParameters,
+ 'contexts'
+>;
+
+/**
+ * @internal
+ */
export type CaptureScreenshotOptions = Omit<
Bidi.BrowsingContext.CaptureScreenshotParameters,
'context'
@@ -121,7 +129,6 @@ export class BrowsingContext extends EventEmitter<{
return browsingContext;
}
- // keep-sorted start
#navigation: Navigation | undefined;
#reason?: string;
#url: string;
@@ -133,7 +140,6 @@ export class BrowsingContext extends EventEmitter<{
readonly id: string;
readonly parent: BrowsingContext | undefined;
readonly userContext: UserContext;
- // keep-sorted end
private constructor(
context: UserContext,
@@ -142,12 +148,11 @@ export class BrowsingContext extends EventEmitter<{
url: string
) {
super();
- // keep-sorted start
+
this.#url = url;
this.id = id;
this.parent = parent;
this.userContext = context;
- // keep-sorted end
this.defaultRealm = this.#createWindowRealm();
}
@@ -275,7 +280,6 @@ export class BrowsingContext extends EventEmitter<{
});
}
- // keep-sorted start block=yes
get #session() {
return this.userContext.browser.session;
}
@@ -306,7 +310,6 @@ export class BrowsingContext extends EventEmitter<{
get url(): string {
return this.#url;
}
- // keep-sorted end
#createWindowRealm(sandbox?: string) {
const realm = WindowRealm.from(this, sandbox);
@@ -478,7 +481,7 @@ export class BrowsingContext extends EventEmitter<{
functionDeclaration,
{
...options,
- contexts: [this, ...(options.contexts ?? [])],
+ contexts: [this],
}
);
}
@@ -487,6 +490,21 @@ export class BrowsingContext extends EventEmitter<{
// SAFETY: Disposal implies this exists.
return context.#reason!;
})
+ async addIntercept(options: AddInterceptOptions): Promise<string> {
+ const {
+ result: {intercept},
+ } = await this.userContext.browser.session.send('network.addIntercept', {
+ ...options,
+ contexts: [this.id],
+ });
+
+ return intercept;
+ }
+
+ @throwIfDisposed<BrowsingContext>(context => {
+ // SAFETY: Disposal implies this exists.
+ return context.#reason!;
+ })
async removePreloadScript(script: string): Promise<void> {
await this.userContext.browser.removePreloadScript(script);
}
@@ -539,6 +557,22 @@ export class BrowsingContext extends EventEmitter<{
});
}
+ @throwIfDisposed<BrowsingContext>(context => {
+ // SAFETY: Disposal implies this exists.
+ return context.#reason!;
+ })
+ async subscribe(events: [string, ...string[]]): Promise<void> {
+ await this.#session.subscribe(events, [this.id]);
+ }
+
+ @throwIfDisposed<BrowsingContext>(context => {
+ // SAFETY: Disposal implies this exists.
+ return context.#reason!;
+ })
+ async addInterception(events: [string, ...string[]]): Promise<void> {
+ await this.#session.subscribe(events, [this.id]);
+ }
+
[disposeSymbol](): void {
this.#reason ??=
'Browsing context already closed, probably because the user context closed.';
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Connection.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Connection.ts
index 9c26a03503..7e5da052bb 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Connection.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Connection.ts
@@ -149,6 +149,31 @@ export interface Commands {
params: Bidi.Storage.SetCookieParameters;
returnType: Bidi.Storage.SetCookieParameters;
};
+
+ 'network.addIntercept': {
+ params: Bidi.Network.AddInterceptParameters;
+ returnType: Bidi.Network.AddInterceptResult;
+ };
+ 'network.removeIntercept': {
+ params: Bidi.Network.RemoveInterceptParameters;
+ returnType: Bidi.EmptyResult;
+ };
+ 'network.continueRequest': {
+ params: Bidi.Network.ContinueRequestParameters;
+ returnType: Bidi.EmptyResult;
+ };
+ 'network.continueWithAuth': {
+ params: Bidi.Network.ContinueWithAuthParameters;
+ returnType: Bidi.EmptyResult;
+ };
+ 'network.failRequest': {
+ params: Bidi.Network.FailRequestParameters;
+ returnType: Bidi.EmptyResult;
+ };
+ 'network.provideResponse': {
+ params: Bidi.Network.ProvideResponseParameters;
+ returnType: Bidi.EmptyResult;
+ };
}
/**
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Navigation.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Navigation.ts
index 50040164a5..d50cf091f9 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Navigation.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Navigation.ts
@@ -6,7 +6,6 @@
import {EventEmitter} from '../../common/EventEmitter.js';
import {inertIfDisposed} from '../../util/decorators.js';
-import {Deferred} from '../../util/Deferred.js';
import {DisposableStack, disposeSymbol} from '../../util/disposable.js';
import type {BrowsingContext} from './BrowsingContext.js';
@@ -39,19 +38,16 @@ export class Navigation extends EventEmitter<{
return navigation;
}
- // keep-sorted start
#request: Request | undefined;
#navigation: Navigation | undefined;
readonly #browsingContext: BrowsingContext;
readonly #disposables = new DisposableStack();
- readonly #id = new Deferred<string | null>();
- // keep-sorted end
+ #id?: string | null;
private constructor(context: BrowsingContext) {
super();
- // keep-sorted start
+
this.#browsingContext = context;
- // keep-sorted end
}
#initialize() {
@@ -69,7 +65,6 @@ export class Navigation extends EventEmitter<{
browsingContextEmitter.on('request', ({request}) => {
if (
request.navigation === undefined ||
- this.#request !== undefined ||
// If a request with a navigation ID comes in, then the navigation ID is
// for this navigation.
!this.#matches(request.navigation)
@@ -79,6 +74,13 @@ export class Navigation extends EventEmitter<{
this.#request = request;
this.emit('request', request);
+ const requestEmitter = this.#disposables.use(
+ new EventEmitter(this.#request)
+ );
+
+ requestEmitter.on('redirect', request => {
+ this.#request = request;
+ });
});
const sessionEmitter = this.#disposables.use(
@@ -139,14 +141,13 @@ export class Navigation extends EventEmitter<{
if (this.#navigation !== undefined && !this.#navigation.disposed) {
return false;
}
- if (!this.#id.resolved()) {
- this.#id.resolve(navigation);
+ if (this.#id === undefined) {
+ this.#id = navigation;
return true;
}
- return this.#id.value() === navigation;
+ return this.#id === navigation;
}
- // keep-sorted start block=yes
get #session() {
return this.#browsingContext.userContext.browser.session;
}
@@ -159,7 +160,6 @@ export class Navigation extends EventEmitter<{
get navigation(): Navigation | undefined {
return this.#navigation;
}
- // keep-sorted end
@inertIfDisposed
private dispose(): void {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Realm.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Realm.ts
index 392194cec8..87298f8730 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Realm.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Realm.ts
@@ -44,22 +44,19 @@ export abstract class Realm extends EventEmitter<{
/** Emitted when a shared worker is created in the realm. */
sharedworker: SharedWorkerRealm;
}> {
- // keep-sorted start
#reason?: string;
protected readonly disposables = new DisposableStack();
readonly id: string;
readonly origin: string;
- // keep-sorted end
+ protected executionContextId?: number;
protected constructor(id: string, origin: string) {
super();
- // keep-sorted start
+
this.id = id;
this.origin = origin;
- // keep-sorted end
}
- // keep-sorted start block=yes
get disposed(): boolean {
return this.#reason !== undefined;
}
@@ -67,7 +64,6 @@ export abstract class Realm extends EventEmitter<{
get target(): Bidi.Script.Target {
return {realm: this.id};
}
- // keep-sorted end
@inertIfDisposed
protected dispose(reason?: string): void {
@@ -127,11 +123,15 @@ export abstract class Realm extends EventEmitter<{
return realm.#reason!;
})
async resolveExecutionContextId(): Promise<number> {
- const {result} = await (this.session.connection as BidiConnection).send(
- 'cdp.resolveRealm',
- {realm: this.id}
- );
- return result.executionContextId;
+ if (!this.executionContextId) {
+ const {result} = await (this.session.connection as BidiConnection).send(
+ 'cdp.resolveRealm',
+ {realm: this.id}
+ );
+ this.executionContextId = result.executionContextId;
+ }
+
+ return this.executionContextId;
}
[disposeSymbol](): void {
@@ -154,19 +154,16 @@ export class WindowRealm extends Realm {
return realm;
}
- // keep-sorted start
readonly browsingContext: BrowsingContext;
readonly sandbox?: string;
- // keep-sorted end
readonly #workers = new Map<string, DedicatedWorkerRealm>();
private constructor(context: BrowsingContext, sandbox?: string) {
super('', '');
- // keep-sorted start
+
this.browsingContext = context;
this.sandbox = sandbox;
- // keep-sorted end
}
#initialize(): void {
@@ -188,6 +185,7 @@ export class WindowRealm extends Realm {
}
(this as any).id = info.realm;
(this as any).origin = info.origin;
+ this.executionContextId = undefined;
this.emit('updated', this);
});
sessionEmitter.on('script.realmCreated', info => {
@@ -242,10 +240,8 @@ export class DedicatedWorkerRealm extends Realm {
return realm;
}
- // keep-sorted start
readonly #workers = new Map<string, DedicatedWorkerRealm>();
readonly owners: Set<DedicatedWorkerOwnerRealm>;
- // keep-sorted end
private constructor(
owner: DedicatedWorkerOwnerRealm,
@@ -300,10 +296,8 @@ export class SharedWorkerRealm extends Realm {
return realm;
}
- // keep-sorted start
readonly #workers = new Map<string, DedicatedWorkerRealm>();
readonly browser: Browser;
- // keep-sorted end
private constructor(browser: Browser, id: string, origin: string) {
super(id, origin);
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Request.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Request.ts
index fd616b668d..241bebf3f9 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Request.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Request.ts
@@ -19,6 +19,8 @@ export class Request extends EventEmitter<{
/** Emitted when the request is redirected. */
redirect: Request;
/** Emitted when the request succeeds. */
+ authenticate: void;
+ /** Emitted when the request succeeds. */
success: Bidi.Network.ResponseData;
/** Emitted when the request fails. */
error: string;
@@ -32,24 +34,21 @@ export class Request extends EventEmitter<{
return request;
}
- // keep-sorted start
#error?: string;
#redirect?: Request;
#response?: Bidi.Network.ResponseData;
readonly #browsingContext: BrowsingContext;
readonly #disposables = new DisposableStack();
readonly #event: Bidi.Network.BeforeRequestSentParameters;
- // keep-sorted end
private constructor(
browsingContext: BrowsingContext,
event: Bidi.Network.BeforeRequestSentParameters
) {
super();
- // keep-sorted start
+
this.#browsingContext = browsingContext;
this.#event = event;
- // keep-sorted end
}
#initialize() {
@@ -77,6 +76,17 @@ export class Request extends EventEmitter<{
this.emit('redirect', this.#redirect);
this.dispose();
});
+ sessionEmitter.on('network.authRequired', event => {
+ if (
+ event.context !== this.#browsingContext.id ||
+ event.request.request !== this.id ||
+ // Don't try to authenticate for events that are not blocked
+ !event.isBlocked
+ ) {
+ return;
+ }
+ this.emit('authenticate', undefined);
+ });
sessionEmitter.on('network.fetchError', event => {
if (
event.context !== this.#browsingContext.id ||
@@ -107,7 +117,6 @@ export class Request extends EventEmitter<{
});
}
- // keep-sorted start block=yes
get #session() {
return this.#browsingContext.userContext.browser.session;
}
@@ -135,13 +144,82 @@ export class Request extends EventEmitter<{
get redirect(): Request | undefined {
return this.#redirect;
}
+ get lastRedirect(): Request | undefined {
+ let redirect = this.#redirect;
+ while (redirect) {
+ if (redirect && !redirect.#redirect) {
+ return redirect;
+ }
+ redirect = redirect.#redirect;
+ }
+ return redirect;
+ }
get response(): Bidi.Network.ResponseData | undefined {
return this.#response;
}
get url(): string {
return this.#event.request.url;
}
- // keep-sorted end
+ get isBlocked(): boolean {
+ return this.#event.isBlocked;
+ }
+
+ async continueRequest({
+ url,
+ method,
+ headers,
+ cookies,
+ body,
+ }: Omit<Bidi.Network.ContinueRequestParameters, 'request'>): Promise<void> {
+ await this.#session.send('network.continueRequest', {
+ request: this.id,
+ url,
+ method,
+ headers,
+ body,
+ cookies,
+ });
+ }
+
+ async failRequest(): Promise<void> {
+ await this.#session.send('network.failRequest', {
+ request: this.id,
+ });
+ }
+
+ async provideResponse({
+ statusCode,
+ reasonPhrase,
+ headers,
+ body,
+ }: Omit<Bidi.Network.ProvideResponseParameters, 'request'>): Promise<void> {
+ await this.#session.send('network.provideResponse', {
+ request: this.id,
+ statusCode,
+ reasonPhrase,
+ headers,
+ body,
+ });
+ }
+
+ async continueWithAuth(
+ parameters:
+ | Bidi.Network.ContinueWithAuthCredentials
+ | Bidi.Network.ContinueWithAuthNoCredentials
+ ): Promise<void> {
+ if (parameters.action === 'provideCredentials') {
+ await this.#session.send('network.continueWithAuth', {
+ request: this.id,
+ action: parameters.action,
+ credentials: parameters.credentials,
+ });
+ } else {
+ await this.#session.send('network.continueWithAuth', {
+ request: this.id,
+ action: parameters.action,
+ });
+ }
+ }
@inertIfDisposed
private dispose(): void {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Session.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Session.ts
index ffd39769e7..3957556c69 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Session.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/Session.ts
@@ -71,8 +71,9 @@ export class Session
platformName: '',
setWindowRect: false,
webSocketUrl: '',
+ userAgent: '',
},
- };
+ } satisfies Bidi.Session.NewResult;
}
const session = new Session(connection, result);
@@ -80,21 +81,18 @@ export class Session
return session;
}
- // keep-sorted start
#reason: string | undefined;
readonly #disposables = new DisposableStack();
readonly #info: Bidi.Session.NewResult;
readonly browser!: Browser;
@bubble()
accessor connection: Connection;
- // keep-sorted end
private constructor(connection: Connection, info: Bidi.Session.NewResult) {
super();
- // keep-sorted start
+
this.#info = info;
this.connection = connection;
- // keep-sorted end
}
async #initialize(): Promise<void> {
@@ -120,7 +118,6 @@ export class Session
});
}
- // keep-sorted start block=yes
get capabilities(): Bidi.Session.NewResult['capabilities'] {
return this.#info.capabilities;
}
@@ -133,7 +130,6 @@ export class Session
get id(): string {
return this.#info.sessionId;
}
- // keep-sorted end
@inertIfDisposed
private dispose(reason?: string): void {
@@ -163,9 +159,27 @@ export class Session
// SAFETY: By definition of `disposed`, `#reason` is defined.
return session.#reason!;
})
- async subscribe(events: string[]): Promise<void> {
+ async subscribe(
+ events: [string, ...string[]],
+ contexts?: [string, ...string[]]
+ ): Promise<void> {
+ await this.send('session.subscribe', {
+ events,
+ contexts,
+ });
+ }
+
+ @throwIfDisposed<Session>(session => {
+ // SAFETY: By definition of `disposed`, `#reason` is defined.
+ return session.#reason!;
+ })
+ async addIntercepts(
+ events: [string, ...string[]],
+ contexts?: [string, ...string[]]
+ ): Promise<void> {
await this.send('session.subscribe', {
events,
+ contexts,
});
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserContext.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserContext.ts
index 72859c6a53..a6af520522 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserContext.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserContext.ts
@@ -52,21 +52,18 @@ export class UserContext extends EventEmitter<{
return context;
}
- // keep-sorted start
#reason?: string;
// Note these are only top-level contexts.
readonly #browsingContexts = new Map<string, BrowsingContext>();
readonly #disposables = new DisposableStack();
readonly #id: string;
readonly browser: Browser;
- // keep-sorted end
private constructor(browser: Browser, id: string) {
super();
- // keep-sorted start
+
this.#id = id;
this.browser = browser;
- // keep-sorted end
}
#initialize() {
@@ -110,7 +107,6 @@ export class UserContext extends EventEmitter<{
});
}
- // keep-sorted start block=yes
get #session() {
return this.browser.session;
}
@@ -126,7 +122,6 @@ export class UserContext extends EventEmitter<{
get id(): string {
return this.#id;
}
- // keep-sorted end
@inertIfDisposed
private dispose(reason?: string): void {
@@ -227,8 +222,7 @@ export class UserContext extends EventEmitter<{
origin,
descriptor,
state,
- // @ts-expect-error not standard implementation.
- 'goog:userContext': this.#id,
+ userContext: this.#id,
});
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserPrompt.ts b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserPrompt.ts
index 073233bed0..13a455e4ac 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserPrompt.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/bidi/core/UserPrompt.ts
@@ -49,23 +49,20 @@ export class UserPrompt extends EventEmitter<{
return userPrompt;
}
- // keep-sorted start
#reason?: string;
#result?: UserPromptResult;
readonly #disposables = new DisposableStack();
readonly browsingContext: BrowsingContext;
readonly info: Bidi.BrowsingContext.UserPromptOpenedParameters;
- // keep-sorted end
private constructor(
context: BrowsingContext,
info: Bidi.BrowsingContext.UserPromptOpenedParameters
) {
super();
- // keep-sorted start
+
this.browsingContext = context;
this.info = info;
- // keep-sorted end
}
#initialize() {
@@ -89,7 +86,6 @@ export class UserPrompt extends EventEmitter<{
});
}
- // keep-sorted start block=yes
get #session() {
return this.browsingContext.userContext.browser.session;
}
@@ -105,7 +101,6 @@ export class UserPrompt extends EventEmitter<{
get result(): UserPromptResult | undefined {
return this.#result;
}
- // keep-sorted end
@inertIfDisposed
private dispose(reason?: string): void {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/AriaQueryHandler.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/AriaQueryHandler.ts
index 2286723758..2b9b14fdc7 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/AriaQueryHandler.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/AriaQueryHandler.ts
@@ -27,7 +27,16 @@ const queryAXTree = async (
role,
});
return nodes.filter((node: Protocol.Accessibility.AXNode) => {
- return !node.role || !NON_ELEMENT_NODE_ROLES.has(node.role.value);
+ if (node.ignored) {
+ return false;
+ }
+ if (!node.role) {
+ return false;
+ }
+ if (NON_ELEMENT_NODE_ROLES.has(node.role.value)) {
+ return false;
+ }
+ return true;
});
};
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts
index 5c8a4c24da..9ae2cbfff1 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Browser.ts
@@ -12,20 +12,18 @@ import type {DebugInfo} from '../api/Browser.js';
import {
Browser as BrowserBase,
BrowserEvent,
- WEB_PERMISSION_TO_PROTOCOL_PERMISSION,
type BrowserCloseCallback,
type BrowserContextOptions,
type IsPageTargetCallback,
- type Permission,
type TargetFilterCallback,
} from '../api/Browser.js';
-import {BrowserContext, BrowserContextEvent} from '../api/BrowserContext.js';
+import {BrowserContextEvent} from '../api/BrowserContext.js';
import {CDPSessionEvent, type CDPSession} from '../api/CDPSession.js';
import type {Page} from '../api/Page.js';
import type {Target} from '../api/Target.js';
import type {Viewport} from '../common/Viewport.js';
-import {assert} from '../util/assert.js';
+import {CdpBrowserContext} from './BrowserContext.js';
import {ChromeTargetManager} from './ChromeTargetManager.js';
import type {Connection} from './Connection.js';
import {FirefoxTargetManager} from './FirefoxTargetManager.js';
@@ -424,90 +422,3 @@ export class CdpBrowser extends BrowserBase {
};
}
}
-
-/**
- * @internal
- */
-export class CdpBrowserContext extends BrowserContext {
- #connection: Connection;
- #browser: CdpBrowser;
- #id?: string;
-
- constructor(connection: Connection, browser: CdpBrowser, contextId?: string) {
- super();
- this.#connection = connection;
- this.#browser = browser;
- this.#id = contextId;
- }
-
- override get id(): string | undefined {
- return this.#id;
- }
-
- override targets(): CdpTarget[] {
- return this.#browser.targets().filter(target => {
- return target.browserContext() === this;
- });
- }
-
- override async pages(): Promise<Page[]> {
- const pages = await Promise.all(
- this.targets()
- .filter(target => {
- return (
- target.type() === 'page' ||
- (target.type() === 'other' &&
- this.#browser._getIsPageTargetCallback()?.(target))
- );
- })
- .map(target => {
- return target.page();
- })
- );
- return pages.filter((page): page is Page => {
- return !!page;
- });
- }
-
- override isIncognito(): boolean {
- return !!this.#id;
- }
-
- override async overridePermissions(
- origin: string,
- permissions: Permission[]
- ): Promise<void> {
- const protocolPermissions = permissions.map(permission => {
- const protocolPermission =
- WEB_PERMISSION_TO_PROTOCOL_PERMISSION.get(permission);
- if (!protocolPermission) {
- throw new Error('Unknown permission: ' + permission);
- }
- return protocolPermission;
- });
- await this.#connection.send('Browser.grantPermissions', {
- origin,
- browserContextId: this.#id || undefined,
- permissions: protocolPermissions,
- });
- }
-
- override async clearPermissionOverrides(): Promise<void> {
- await this.#connection.send('Browser.resetPermissions', {
- browserContextId: this.#id || undefined,
- });
- }
-
- override newPage(): Promise<Page> {
- return this.#browser._createPageInContext(this.#id);
- }
-
- override browser(): CdpBrowser {
- return this.#browser;
- }
-
- override async close(): Promise<void> {
- assert(this.#id, 'Non-incognito profiles cannot be closed!');
- await this.#browser._disposeContext(this.#id);
- }
-}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/BrowserContext.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/BrowserContext.ts
new file mode 100644
index 0000000000..f2279617f1
--- /dev/null
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/BrowserContext.ts
@@ -0,0 +1,104 @@
+/**
+ * @license
+ * Copyright 2024 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ WEB_PERMISSION_TO_PROTOCOL_PERMISSION,
+ type Permission,
+} from '../api/Browser.js';
+import {BrowserContext} from '../api/BrowserContext.js';
+import type {Page} from '../api/Page.js';
+import {assert} from '../util/assert.js';
+
+import type {CdpBrowser} from './Browser.js';
+import type {Connection} from './Connection.js';
+import type {CdpTarget} from './Target.js';
+
+/**
+ * @internal
+ */
+export class CdpBrowserContext extends BrowserContext {
+ #connection: Connection;
+ #browser: CdpBrowser;
+ #id?: string;
+
+ constructor(connection: Connection, browser: CdpBrowser, contextId?: string) {
+ super();
+ this.#connection = connection;
+ this.#browser = browser;
+ this.#id = contextId;
+ }
+
+ override get id(): string | undefined {
+ return this.#id;
+ }
+
+ override targets(): CdpTarget[] {
+ return this.#browser.targets().filter(target => {
+ return target.browserContext() === this;
+ });
+ }
+
+ override async pages(): Promise<Page[]> {
+ const pages = await Promise.all(
+ this.targets()
+ .filter(target => {
+ return (
+ target.type() === 'page' ||
+ (target.type() === 'other' &&
+ this.#browser._getIsPageTargetCallback()?.(target))
+ );
+ })
+ .map(target => {
+ return target.page();
+ })
+ );
+ return pages.filter((page): page is Page => {
+ return !!page;
+ });
+ }
+
+ override isIncognito(): boolean {
+ return !!this.#id;
+ }
+
+ override async overridePermissions(
+ origin: string,
+ permissions: Permission[]
+ ): Promise<void> {
+ const protocolPermissions = permissions.map(permission => {
+ const protocolPermission =
+ WEB_PERMISSION_TO_PROTOCOL_PERMISSION.get(permission);
+ if (!protocolPermission) {
+ throw new Error('Unknown permission: ' + permission);
+ }
+ return protocolPermission;
+ });
+ await this.#connection.send('Browser.grantPermissions', {
+ origin,
+ browserContextId: this.#id || undefined,
+ permissions: protocolPermissions,
+ });
+ }
+
+ override async clearPermissionOverrides(): Promise<void> {
+ await this.#connection.send('Browser.resetPermissions', {
+ browserContextId: this.#id || undefined,
+ });
+ }
+
+ override newPage(): Promise<Page> {
+ return this.#browser._createPageInContext(this.#id);
+ }
+
+ override browser(): CdpBrowser {
+ return this.#browser;
+ }
+
+ override async close(): Promise<void> {
+ assert(this.#id, 'Non-incognito profiles cannot be closed!');
+ await this.#browser._disposeContext(this.#id);
+ }
+}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts
index edc7009b11..c7c2885a65 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Frame.ts
@@ -206,6 +206,7 @@ export class CdpFrame extends Frame {
options: {
timeout?: number;
waitUntil?: PuppeteerLifeCycleEvent | PuppeteerLifeCycleEvent[];
+ ignoreSameDocumentNavigation?: boolean;
} = {}
): Promise<HTTPResponse | null> {
const {
@@ -220,14 +221,22 @@ export class CdpFrame extends Frame {
);
const error = await Deferred.race([
watcher.terminationPromise(),
- watcher.sameDocumentNavigationPromise(),
+ ...(options.ignoreSameDocumentNavigation
+ ? []
+ : [watcher.sameDocumentNavigationPromise()]),
watcher.newDocumentNavigationPromise(),
]);
try {
if (error) {
throw error;
}
- return await watcher.navigationResponse();
+ const result = await Deferred.race<
+ Error | HTTPResponse | null | undefined
+ >([watcher.terminationPromise(), watcher.navigationResponse()]);
+ if (result instanceof Error) {
+ throw error;
+ }
+ return result || null;
} finally {
watcher.dispose();
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/FrameTree.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/FrameTree.ts
index 7ee1b86b5f..dcd341c9e3 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/FrameTree.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/FrameTree.ts
@@ -21,6 +21,7 @@ export class FrameTree<FrameType extends Frame> {
// frameID -> childFrameIDs
#childIds = new Map<string, Set<string>>();
#mainFrame?: FrameType;
+ #isMainFrameStale = false;
#waitRequests = new Map<string, Set<Deferred<FrameType>>>();
getMainFrame(): FrameType | undefined {
@@ -59,8 +60,9 @@ export class FrameTree<FrameType extends Frame> {
this.#childIds.set(frame._parentId, new Set());
}
this.#childIds.get(frame._parentId)!.add(frame._id);
- } else if (!this.#mainFrame) {
+ } else if (!this.#mainFrame || this.#isMainFrameStale) {
this.#mainFrame = frame;
+ this.#isMainFrameStale = false;
}
this.#waitRequests.get(frame._id)?.forEach(request => {
return request.resolve(frame);
@@ -73,7 +75,7 @@ export class FrameTree<FrameType extends Frame> {
if (frame._parentId) {
this.#childIds.get(frame._parentId)?.delete(frame._id);
} else {
- this.#mainFrame = undefined;
+ this.#isMainFrameStale = true;
}
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts
index 1331513e19..59fc0c940a 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/HTTPRequest.ts
@@ -9,18 +9,14 @@ import type {CDPSession} from '../api/CDPSession.js';
import type {Frame} from '../api/Frame.js';
import {
type ContinueRequestOverrides,
- type ErrorCode,
headersArray,
HTTPRequest,
- InterceptResolutionAction,
- type InterceptResolutionState,
type ResourceType,
type ResponseForRequest,
STATUS_TEXTS,
+ handleError,
} from '../api/HTTPRequest.js';
-import type {ProtocolError} from '../common/Errors.js';
import {debugError, isString} from '../common/util.js';
-import {assert} from '../util/assert.js';
import type {CdpHTTPResponse} from './HTTPResponse.js';
@@ -34,8 +30,7 @@ export class CdpHTTPRequest extends HTTPRequest {
#client: CDPSession;
#isNavigationRequest: boolean;
- #allowInterception: boolean;
- #interceptionHandled = false;
+
#url: string;
#resourceType: ResourceType;
@@ -44,13 +39,6 @@ export class CdpHTTPRequest extends HTTPRequest {
#postData?: string;
#headers: Record<string, string> = {};
#frame: Frame | null;
- #continueRequestOverrides: ContinueRequestOverrides;
- #responseForRequest: Partial<ResponseForRequest> | null = null;
- #abortErrorReason: Protocol.Network.ErrorReason | null = null;
- #interceptResolutionState: InterceptResolutionState = {
- action: InterceptResolutionAction.None,
- };
- #interceptHandlers: Array<() => void | PromiseLike<any>>;
#initiator?: Protocol.Network.Initiator;
override get client(): CDPSession {
@@ -96,7 +84,6 @@ export class CdpHTTPRequest extends HTTPRequest {
this.#isNavigationRequest =
data.requestId === data.loaderId && data.type === 'Document';
this._interceptionId = interceptionId;
- this.#allowInterception = allowInterception;
this.#url = data.request.url;
this.#resourceType = (data.type || 'other').toLowerCase() as ResourceType;
this.#method = data.request.method;
@@ -104,10 +91,10 @@ export class CdpHTTPRequest extends HTTPRequest {
this.#hasPostData = data.request.hasPostData ?? false;
this.#frame = frame;
this._redirectChain = redirectChain;
- this.#continueRequestOverrides = {};
- this.#interceptHandlers = [];
this.#initiator = data.initiator;
+ this.interception.enabled = allowInterception;
+
for (const [key, value] of Object.entries(data.request.headers)) {
this.#headers[key.toLowerCase()] = value;
}
@@ -117,59 +104,6 @@ export class CdpHTTPRequest extends HTTPRequest {
return this.#url;
}
- override continueRequestOverrides(): ContinueRequestOverrides {
- assert(this.#allowInterception, 'Request Interception is not enabled!');
- return this.#continueRequestOverrides;
- }
-
- override responseForRequest(): Partial<ResponseForRequest> | null {
- assert(this.#allowInterception, 'Request Interception is not enabled!');
- return this.#responseForRequest;
- }
-
- override abortErrorReason(): Protocol.Network.ErrorReason | null {
- assert(this.#allowInterception, 'Request Interception is not enabled!');
- return this.#abortErrorReason;
- }
-
- override interceptResolutionState(): InterceptResolutionState {
- if (!this.#allowInterception) {
- return {action: InterceptResolutionAction.Disabled};
- }
- if (this.#interceptionHandled) {
- return {action: InterceptResolutionAction.AlreadyHandled};
- }
- return {...this.#interceptResolutionState};
- }
-
- override isInterceptResolutionHandled(): boolean {
- return this.#interceptionHandled;
- }
-
- enqueueInterceptAction(
- pendingHandler: () => void | PromiseLike<unknown>
- ): void {
- this.#interceptHandlers.push(pendingHandler);
- }
-
- override async finalizeInterceptions(): Promise<void> {
- await this.#interceptHandlers.reduce((promiseChain, interceptAction) => {
- return promiseChain.then(interceptAction);
- }, Promise.resolve());
- const {action} = this.interceptResolutionState();
- switch (action) {
- case 'abort':
- return await this.#abort(this.#abortErrorReason);
- case 'respond':
- if (this.#responseForRequest === null) {
- throw new Error('Response is missing for the interception');
- }
- return await this.#respond(this.#responseForRequest);
- case 'continue':
- return await this.#continue(this.#continueRequestOverrides);
- }
- }
-
override resourceType(): ResourceType {
return this.#resourceType;
}
@@ -231,46 +165,12 @@ export class CdpHTTPRequest extends HTTPRequest {
};
}
- override async continue(
- overrides: ContinueRequestOverrides = {},
- priority?: number
- ): Promise<void> {
- // Request interception is not supported for data: urls.
- if (this.#url.startsWith('data:')) {
- return;
- }
- assert(this.#allowInterception, 'Request Interception is not enabled!');
- assert(!this.#interceptionHandled, 'Request is already handled!');
- if (priority === undefined) {
- return await this.#continue(overrides);
- }
- this.#continueRequestOverrides = overrides;
- if (
- this.#interceptResolutionState.priority === undefined ||
- priority > this.#interceptResolutionState.priority
- ) {
- this.#interceptResolutionState = {
- action: InterceptResolutionAction.Continue,
- priority,
- };
- return;
- }
- if (priority === this.#interceptResolutionState.priority) {
- if (
- this.#interceptResolutionState.action === 'abort' ||
- this.#interceptResolutionState.action === 'respond'
- ) {
- return;
- }
- this.#interceptResolutionState.action =
- InterceptResolutionAction.Continue;
- }
- return;
- }
-
- async #continue(overrides: ContinueRequestOverrides = {}): Promise<void> {
+ /**
+ * @internal
+ */
+ async _continue(overrides: ContinueRequestOverrides = {}): Promise<void> {
const {url, method, postData, headers} = overrides;
- this.#interceptionHandled = true;
+ this.interception.handled = true;
const postDataBinaryBase64 = postData
? Buffer.from(postData).toString('base64')
@@ -290,45 +190,13 @@ export class CdpHTTPRequest extends HTTPRequest {
headers: headers ? headersArray(headers) : undefined,
})
.catch(error => {
- this.#interceptionHandled = false;
+ this.interception.handled = false;
return handleError(error);
});
}
- override async respond(
- response: Partial<ResponseForRequest>,
- priority?: number
- ): Promise<void> {
- // Mocking responses for dataURL requests is not currently supported.
- if (this.#url.startsWith('data:')) {
- return;
- }
- assert(this.#allowInterception, 'Request Interception is not enabled!');
- assert(!this.#interceptionHandled, 'Request is already handled!');
- if (priority === undefined) {
- return await this.#respond(response);
- }
- this.#responseForRequest = response;
- if (
- this.#interceptResolutionState.priority === undefined ||
- priority > this.#interceptResolutionState.priority
- ) {
- this.#interceptResolutionState = {
- action: InterceptResolutionAction.Respond,
- priority,
- };
- return;
- }
- if (priority === this.#interceptResolutionState.priority) {
- if (this.#interceptResolutionState.action === 'abort') {
- return;
- }
- this.#interceptResolutionState.action = InterceptResolutionAction.Respond;
- }
- }
-
- async #respond(response: Partial<ResponseForRequest>): Promise<void> {
- this.#interceptionHandled = true;
+ async _respond(response: Partial<ResponseForRequest>): Promise<void> {
+ this.interception.handled = true;
const responseBody: Buffer | null =
response.body && isString(response.body)
@@ -371,43 +239,15 @@ export class CdpHTTPRequest extends HTTPRequest {
body: responseBody ? responseBody.toString('base64') : undefined,
})
.catch(error => {
- this.#interceptionHandled = false;
+ this.interception.handled = false;
return handleError(error);
});
}
- override async abort(
- errorCode: ErrorCode = 'failed',
- priority?: number
- ): Promise<void> {
- // Request interception is not supported for data: urls.
- if (this.#url.startsWith('data:')) {
- return;
- }
- const errorReason = errorReasons[errorCode];
- assert(errorReason, 'Unknown error code: ' + errorCode);
- assert(this.#allowInterception, 'Request Interception is not enabled!');
- assert(!this.#interceptionHandled, 'Request is already handled!');
- if (priority === undefined) {
- return await this.#abort(errorReason);
- }
- this.#abortErrorReason = errorReason;
- if (
- this.#interceptResolutionState.priority === undefined ||
- priority >= this.#interceptResolutionState.priority
- ) {
- this.#interceptResolutionState = {
- action: InterceptResolutionAction.Abort,
- priority,
- };
- return;
- }
- }
-
- async #abort(
+ async _abort(
errorReason: Protocol.Network.ErrorReason | null
): Promise<void> {
- this.#interceptionHandled = true;
+ this.interception.handled = true;
if (this._interceptionId === undefined) {
throw new Error(
'HTTPRequest is missing _interceptionId needed for Fetch.failRequest'
@@ -421,30 +261,3 @@ export class CdpHTTPRequest extends HTTPRequest {
.catch(handleError);
}
}
-
-const errorReasons: Record<ErrorCode, Protocol.Network.ErrorReason> = {
- aborted: 'Aborted',
- accessdenied: 'AccessDenied',
- addressunreachable: 'AddressUnreachable',
- blockedbyclient: 'BlockedByClient',
- blockedbyresponse: 'BlockedByResponse',
- connectionaborted: 'ConnectionAborted',
- connectionclosed: 'ConnectionClosed',
- connectionfailed: 'ConnectionFailed',
- connectionrefused: 'ConnectionRefused',
- connectionreset: 'ConnectionReset',
- internetdisconnected: 'InternetDisconnected',
- namenotresolved: 'NameNotResolved',
- timedout: 'TimedOut',
- failed: 'Failed',
-} as const;
-
-async function handleError(error: ProtocolError) {
- if (['Invalid header'].includes(error.originalMessage)) {
- throw error;
- }
- // In certain cases, protocol will return error if the request was
- // already canceled or the page was closed. We should tolerate these
- // errors.
- debugError(error);
-}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts
index 4fd61116d2..70f7370f2c 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/NetworkManager.ts
@@ -8,6 +8,7 @@ import type {Protocol} from 'devtools-protocol';
import {CDPSessionEvent, type CDPSession} from '../api/CDPSession.js';
import type {Frame} from '../api/Frame.js';
+import type {Credentials} from '../api/Page.js';
import {EventEmitter, EventSubscription} from '../common/EventEmitter.js';
import {
NetworkManagerEvent,
@@ -27,14 +28,6 @@ import {
/**
* @public
*/
-export interface Credentials {
- username: string;
- password: string;
-}
-
-/**
- * @public
- */
export interface NetworkConditions {
/**
* Download speed (bytes/s)
@@ -147,18 +140,16 @@ export class NetworkManager extends EventEmitter<NetworkManagerEvents> {
);
}
- async setExtraHTTPHeaders(
- extraHTTPHeaders: Record<string, string>
- ): Promise<void> {
- this.#extraHTTPHeaders = {};
- for (const key of Object.keys(extraHTTPHeaders)) {
- const value = extraHTTPHeaders[key];
+ async setExtraHTTPHeaders(headers: Record<string, string>): Promise<void> {
+ const extraHTTPHeaders: Record<string, string> = {};
+ for (const [key, value] of Object.entries(headers)) {
assert(
isString(value),
`Expected value of header "${key}" to be String, but "${typeof value}" is found.`
);
- this.#extraHTTPHeaders[key.toLowerCase()] = value;
+ extraHTTPHeaders[key.toLowerCase()] = value;
}
+ this.#extraHTTPHeaders = extraHTTPHeaders;
await this.#applyToAllClients(this.#applyExtraHTTPHeaders.bind(this));
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts
index d5341cf3bb..32ded73b42 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/cdp/Page.ts
@@ -15,6 +15,7 @@ import type {Frame, WaitForOptions} from '../api/Frame.js';
import type {HTTPRequest} from '../api/HTTPRequest.js';
import type {HTTPResponse} from '../api/HTTPResponse.js';
import type {JSHandle} from '../api/JSHandle.js';
+import type {Credentials} from '../api/Page.js';
import {
Page,
PageEvent,
@@ -71,7 +72,7 @@ import {FrameManagerEvent} from './FrameManagerEvents.js';
import {CdpKeyboard, CdpMouse, CdpTouchscreen} from './Input.js';
import {MAIN_WORLD} from './IsolatedWorlds.js';
import {releaseObject} from './JSHandle.js';
-import type {Credentials, NetworkConditions} from './NetworkManager.js';
+import type {NetworkConditions} from './NetworkManager.js';
import type {CdpTarget} from './Target.js';
import type {TargetManager} from './TargetManager.js';
import {TargetManagerEvent} from './TargetManager.js';
@@ -916,7 +917,10 @@ export class CdpPage extends Page {
options?: WaitForOptions
): Promise<HTTPResponse | null> {
const [result] = await Promise.all([
- this.waitForNavigation(options),
+ this.waitForNavigation({
+ ...options,
+ ignoreSameDocumentNavigation: true,
+ }),
this.#primaryTargetClient.send('Page.reload'),
]);
@@ -1130,6 +1134,16 @@ export class CdpPage extends Page {
await this.#emulationManager.setTransparentBackgroundColor();
}
+ await firstValueFrom(
+ from(
+ this.mainFrame()
+ .isolatedRealm()
+ .evaluate(() => {
+ return document.fonts.ready;
+ })
+ ).pipe(raceWith(timeout(ms)))
+ );
+
const printCommandPromise = this.#primaryTargetClient.send(
'Page.printToPDF',
{
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/CallbackRegistry.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/CallbackRegistry.ts
index ea9f3d5abb..6b8379177b 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/common/CallbackRegistry.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/CallbackRegistry.ts
@@ -31,17 +31,14 @@ export class CallbackRegistry {
} catch (error) {
// We still throw sync errors synchronously and clean up the scheduled
// callback.
- callback.promise
- .valueOrThrow()
- .catch(debugError)
- .finally(() => {
- this.#callbacks.delete(callback.id);
- });
+ callback.promise.catch(debugError).finally(() => {
+ this.#callbacks.delete(callback.id);
+ });
callback.reject(error as Error);
throw error;
}
// Must only have sync code up until here.
- return callback.promise.valueOrThrow().finally(() => {
+ return callback.promise.finally(() => {
this.#callbacks.delete(callback.id);
});
}
@@ -148,8 +145,8 @@ export class Callback {
return this.#id;
}
- get promise(): Deferred<unknown> {
- return this.#deferred;
+ get promise(): Promise<unknown> {
+ return this.#deferred.valueOrThrow();
}
get error(): ProtocolError {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/Configuration.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/Configuration.ts
index fe71e57587..9d26cecfbb 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/common/Configuration.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/Configuration.ts
@@ -102,7 +102,7 @@ export interface Configuration {
/**
* Tells Puppeteer to not chrome-headless-shell download during installation.
*
- * Can be overridden by `PUPPETEER_SKIP_CHROME_HEADLESSS_HELL_DOWNLOAD`.
+ * Can be overridden by `PUPPETEER_SKIP_CHROME_HEADLESS_SHELL_DOWNLOAD`.
*/
skipChromeHeadlessShellDownload?: boolean;
/**
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/Errors.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/Errors.ts
index 4d0a43ea33..46a3548cf3 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/common/Errors.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/Errors.ts
@@ -13,8 +13,8 @@ export class PuppeteerError extends Error {
/**
* @internal
*/
- constructor(message?: string) {
- super(message);
+ constructor(message?: string, options?: ErrorOptions) {
+ super(message, options);
this.name = this.constructor.name;
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/PDFOptions.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/PDFOptions.ts
index f87ec6817b..e88a94380d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/common/PDFOptions.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/PDFOptions.ts
@@ -98,7 +98,7 @@ export interface PDFOptions {
headerTemplate?: string;
/**
* HTML template for the print footer. Has the same constraints and support
- * for special classes as {@link PDFOptions | PDFOptions.headerTemplate}.
+ * for special classes as {@link PDFOptions.headerTemplate}.
*/
footerTemplate?: string;
/**
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/common/util.ts b/remote/test/puppeteer/packages/puppeteer-core/src/common/util.ts
index f84453c612..44d22ae01d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/common/util.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/common/util.ts
@@ -312,12 +312,12 @@ export function validateDialogType(
/**
* @internal
*/
-export function timeout(ms: number): Observable<never> {
+export function timeout(ms: number, cause?: Error): Observable<never> {
return ms === 0
? NEVER
: timer(ms).pipe(
map(() => {
- throw new TimeoutError(`Timed out after waiting ${ms}ms`);
+ throw new TimeoutError(`Timed out after waiting ${ms}ms`, {cause});
})
);
}
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/node/ChromeLauncher.ts b/remote/test/puppeteer/packages/puppeteer-core/src/node/ChromeLauncher.ts
index 0cec3de9ae..9b71952a2e 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/node/ChromeLauncher.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/node/ChromeLauncher.ts
@@ -166,6 +166,9 @@ export class ChromeLauncher extends ProductLauncher {
removeMatchingFlags(options.args, '--disable-features');
}
+ const turnOnExperimentalFeaturesForTesting =
+ process.env['PUPPETEER_TEST_EXPERIMENTAL_CHROME_FEATURES'] === 'true';
+
// Merge default disabled features with user-provided ones, if any.
const disabledFeatures = [
'Translate',
@@ -174,9 +177,13 @@ export class ChromeLauncher extends ProductLauncher {
'MediaRouter',
'OptimizationHints',
// https://crbug.com/1492053
- 'ProcessPerSiteUpToMainFrameThreshold',
+ turnOnExperimentalFeaturesForTesting
+ ? ''
+ : 'ProcessPerSiteUpToMainFrameThreshold',
...userDisabledFeatures,
- ];
+ ].filter(feature => {
+ return feature !== '';
+ });
const userEnabledFeatures = getFeatures('--enable-features', options.args);
if (options.args && userEnabledFeatures.length > 0) {
@@ -185,9 +192,11 @@ export class ChromeLauncher extends ProductLauncher {
// Merge default enabled features with user-provided ones, if any.
const enabledFeatures = [
- 'NetworkServiceInProcess2',
+ // Add features to enable by default here.
...userEnabledFeatures,
- ];
+ ].filter(feature => {
+ return feature !== '';
+ });
const chromeArguments = [
'--allow-pre-commit-input',
@@ -201,7 +210,9 @@ export class ChromeLauncher extends ProductLauncher {
'--disable-default-apps',
'--disable-dev-shm-usage',
'--disable-extensions',
- '--disable-field-trial-config', // https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
+ turnOnExperimentalFeaturesForTesting
+ ? ''
+ : '--disable-field-trial-config', // https://source.chromium.org/chromium/chromium/src/+/main:testing/variations/README.md
'--disable-hang-monitor',
'--disable-infobars',
'--disable-ipc-flooding-protection',
@@ -220,7 +231,9 @@ export class ChromeLauncher extends ProductLauncher {
'--use-mock-keychain',
`--disable-features=${disabledFeatures.join(',')}`,
`--enable-features=${enabledFeatures.join(',')}`,
- ];
+ ].filter(arg => {
+ return arg !== '';
+ });
const {
devtools = false,
headless = !devtools,
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/node/NodeWebSocketTransport.ts b/remote/test/puppeteer/packages/puppeteer-core/src/node/NodeWebSocketTransport.ts
index f4ac592e4f..13f1e8349c 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/node/NodeWebSocketTransport.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/node/NodeWebSocketTransport.ts
@@ -41,14 +41,18 @@ export class NodeWebSocketTransport implements ConnectionTransport {
constructor(ws: NodeWebSocket) {
this.#ws = ws;
this.#ws.addEventListener('message', event => {
- if (this.onmessage) {
- this.onmessage.call(null, event.data);
- }
+ setImmediate(() => {
+ if (this.onmessage) {
+ this.onmessage.call(null, event.data);
+ }
+ });
});
this.#ws.addEventListener('close', () => {
- if (this.onclose) {
- this.onclose.call(null);
- }
+ setImmediate(() => {
+ if (this.onclose) {
+ this.onclose.call(null);
+ }
+ });
});
// Silently ignore all errors - we don't know what to do with them.
this.#ws.addEventListener('error', () => {});
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/node/ProductLauncher.ts b/remote/test/puppeteer/packages/puppeteer-core/src/node/ProductLauncher.ts
index 2da07e8f7c..6f4008f23d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/node/ProductLauncher.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/node/ProductLauncher.ts
@@ -98,6 +98,12 @@ export abstract class ProductLauncher {
const launchArgs = await this.computeLaunchArguments(options);
+ if (!existsSync(launchArgs.executablePath)) {
+ throw new Error(
+ `Browser was not found at the configured executablePath (${launchArgs.executablePath})`
+ );
+ }
+
const usePipe = launchArgs.args.includes('--remote-debugging-pipe');
const onProcessExit = async () => {
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/node/PuppeteerNode.ts b/remote/test/puppeteer/packages/puppeteer-core/src/node/PuppeteerNode.ts
index 726ee24cbb..5a5d43bf3c 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/node/PuppeteerNode.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/node/PuppeteerNode.ts
@@ -136,11 +136,11 @@ export class PuppeteerNode extends Puppeteer {
* specified.
*
* When using with `puppeteer-core`,
- * {@link LaunchOptions | options.executablePath} or
- * {@link LaunchOptions | options.channel} must be provided.
+ * {@link LaunchOptions.executablePath | options.executablePath} or
+ * {@link LaunchOptions.channel | options.channel} must be provided.
*
* @example
- * You can use {@link LaunchOptions | options.ignoreDefaultArgs}
+ * You can use {@link LaunchOptions.ignoreDefaultArgs | options.ignoreDefaultArgs}
* to filter out `--mute-audio` from default arguments:
*
* ```ts
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/revisions.ts b/remote/test/puppeteer/packages/puppeteer-core/src/revisions.ts
index c543cd9517..b75257ab50 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/revisions.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/revisions.ts
@@ -8,7 +8,7 @@
* @internal
*/
export const PUPPETEER_REVISIONS = Object.freeze({
- chrome: '122.0.6261.94',
- 'chrome-headless-shell': '122.0.6261.94',
+ chrome: '123.0.6312.122',
+ 'chrome-headless-shell': '123.0.6312.122',
firefox: 'latest',
});
diff --git a/remote/test/puppeteer/packages/puppeteer-core/src/util/Function.ts b/remote/test/puppeteer/packages/puppeteer-core/src/util/Function.ts
index 41db98830b..497a31501d 100644
--- a/remote/test/puppeteer/packages/puppeteer-core/src/util/Function.ts
+++ b/remote/test/puppeteer/packages/puppeteer-core/src/util/Function.ts
@@ -72,7 +72,7 @@ export const interpolateFunction = <T extends (...args: never[]) => unknown>(
for (const [name, jsValue] of Object.entries(replacements)) {
value = value.replace(
new RegExp(`PLACEHOLDER\\(\\s*(?:'${name}'|"${name}")\\s*\\)`, 'g'),
- // Wrapping this ensures tersers that accidently inline PLACEHOLDER calls
+ // Wrapping this ensures tersers that accidentally inline PLACEHOLDER calls
// are still valid. Without, we may get calls like ()=>{...}() which is
// not valid.
`(${jsValue})`
diff --git a/remote/test/puppeteer/packages/puppeteer/CHANGELOG.md b/remote/test/puppeteer/packages/puppeteer/CHANGELOG.md
index 8f98608527..e8fa0d38b8 100644
--- a/remote/test/puppeteer/packages/puppeteer/CHANGELOG.md
+++ b/remote/test/puppeteer/packages/puppeteer/CHANGELOG.md
@@ -29,6 +29,121 @@ All notable changes to this project will be documented in this file. See [standa
* puppeteer-core bumped from 21.0.2 to 21.0.3
* @puppeteer/browsers bumped from 1.5.1 to 1.6.0
+## [22.6.5](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.6.4...puppeteer-v22.6.5) (2024-04-15)
+
+
+### Miscellaneous Chores
+
+* **puppeteer:** Synchronize puppeteer versions
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.6.4 to 22.6.5
+ * @puppeteer/browsers bumped from 2.2.1 to 2.2.2
+
+## [22.6.4](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.6.3...puppeteer-v22.6.4) (2024-04-11)
+
+
+### Miscellaneous Chores
+
+* **puppeteer:** Synchronize puppeteer versions
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.6.3 to 22.6.4
+
+## [22.6.3](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.6.2...puppeteer-v22.6.3) (2024-04-05)
+
+
+### Bug Fixes
+
+* deprecate configuration via package.json ([#12176](https://github.com/puppeteer/puppeteer/issues/12176)) ([c96c762](https://github.com/puppeteer/puppeteer/commit/c96c7623bc2258ba7419812333ec42cdf83bf432))
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.6.2 to 22.6.3
+ * @puppeteer/browsers bumped from 2.2.0 to 2.2.1
+
+## [22.6.2](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.6.1...puppeteer-v22.6.2) (2024-03-28)
+
+
+### Miscellaneous Chores
+
+* **puppeteer:** Synchronize puppeteer versions
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.6.1 to 22.6.2
+
+## [22.6.1](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.6.0...puppeteer-v22.6.1) (2024-03-25)
+
+
+### Miscellaneous Chores
+
+* **puppeteer:** Synchronize puppeteer versions
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.6.0 to 22.6.1
+
+## [22.6.0](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.5.0...puppeteer-v22.6.0) (2024-03-20)
+
+
+### Features
+
+* roll to Chrome 123.0.6312.58 (r1262506) ([#12110](https://github.com/puppeteer/puppeteer/issues/12110)) ([6f5b3bc](https://github.com/puppeteer/puppeteer/commit/6f5b3bc9b88c6d3204dda396f8963591ea6eb883))
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.5.0 to 22.6.0
+
+## [22.5.0](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.4.1...puppeteer-v22.5.0) (2024-03-15)
+
+
+### Miscellaneous Chores
+
+* **puppeteer:** Synchronize puppeteer versions
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.4.1 to 22.5.0
+ * @puppeteer/browsers bumped from 2.1.0 to 2.2.0
+
+## [22.4.1](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.4.0...puppeteer-v22.4.1) (2024-03-08)
+
+
+### Miscellaneous Chores
+
+* **puppeteer:** Synchronize puppeteer versions
+
+
+### Dependencies
+
+* The following workspace dependencies were updated
+ * dependencies
+ * puppeteer-core bumped from 22.4.0 to 22.4.1
+
## [22.4.0](https://github.com/puppeteer/puppeteer/compare/puppeteer-v22.3.0...puppeteer-v22.4.0) (2024-03-05)
diff --git a/remote/test/puppeteer/packages/puppeteer/package.json b/remote/test/puppeteer/packages/puppeteer/package.json
index 88637f3add..6d3b385640 100644
--- a/remote/test/puppeteer/packages/puppeteer/package.json
+++ b/remote/test/puppeteer/packages/puppeteer/package.json
@@ -1,6 +1,6 @@
{
"name": "puppeteer",
- "version": "22.4.0",
+ "version": "22.6.5",
"description": "A high-level API to control headless Chrome over the DevTools Protocol",
"keywords": [
"puppeteer",
@@ -124,8 +124,9 @@
"license": "Apache-2.0",
"dependencies": {
"cosmiconfig": "9.0.0",
- "puppeteer-core": "22.4.0",
- "@puppeteer/browsers": "2.1.0"
+ "puppeteer-core": "22.6.5",
+ "@puppeteer/browsers": "2.2.2",
+ "devtools-protocol": "0.0.1262051"
},
"devDependencies": {
"@types/node": "18.17.15"
diff --git a/remote/test/puppeteer/packages/puppeteer/src/getConfiguration.ts b/remote/test/puppeteer/packages/puppeteer/src/getConfiguration.ts
index 6fd88678a4..ddd3386a70 100644
--- a/remote/test/puppeteer/packages/puppeteer/src/getConfiguration.ts
+++ b/remote/test/puppeteer/packages/puppeteer/src/getConfiguration.ts
@@ -127,6 +127,17 @@ export const getConfiguration = (): Configuration => {
downloadHost;
}
+ if (
+ Object.keys(process.env).some(key => {
+ return key.startsWith('npm_package_config_puppeteer_');
+ }) &&
+ configuration.logLevel === 'warn'
+ ) {
+ console.warn(
+ `Configuring Puppeteer via npm/package.json is deprecated. Use https://pptr.dev/guides/configuration instead.`
+ );
+ }
+
configuration.cacheDirectory =
process.env['PUPPETEER_CACHE_DIR'] ??
process.env['npm_config_puppeteer_cache_dir'] ??
diff --git a/remote/test/puppeteer/test/.eslintrc.js b/remote/test/puppeteer/test/.eslintrc.js
index 5f7746a76b..ea697b0a47 100644
--- a/remote/test/puppeteer/test/.eslintrc.js
+++ b/remote/test/puppeteer/test/.eslintrc.js
@@ -36,6 +36,12 @@ module.exports = {
selector:
'CallExpression[callee.object.name="it"] > MemberExpression > Identifier[name="deflake"], CallExpression[callee.object.name="it"] > MemberExpression > Identifier[name="deflakeOnly"]',
},
+ {
+ message:
+ 'No `expect` in EventHandler. They will never throw errors',
+ selector:
+ 'CallExpression[callee.property.name="on"] BlockStatement > :not(TryStatement) > ExpressionStatement > CallExpression[callee.object.callee.name="expect"]',
+ },
],
},
},
diff --git a/remote/test/puppeteer/test/TestExpectations.json b/remote/test/puppeteer/test/TestExpectations.json
index e55f223441..9f021882f5 100644
--- a/remote/test/puppeteer/test/TestExpectations.json
+++ b/remote/test/puppeteer/test/TestExpectations.json
@@ -18,7 +18,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "Chrome-only feature blocked on https://github.com/GoogleChromeLabs/chromium-bidi/issues/2082"
},
{
"testIdPattern": "[device-request-prompt.spec] *",
@@ -58,9 +58,9 @@
{
"testIdPattern": "[headful.spec] *",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["headless", "firefox"],
+ "parameters": ["headless"],
"expectations": ["SKIP"],
- "comment": "Cannot be run in headless mode"
+ "comment": "Spawns headful browser, needs display or `xvfb` like which is not required for other headless tests"
},
{
"testIdPattern": "[idle_override.spec] *",
@@ -84,20 +84,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[network.spec] network Page.authenticate *",
- "platforms": ["darwin", "linux"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[network.spec] network Page.authenticate *",
- "platforms": ["win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[network.spec] network Page.setBypassServiceWorker *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
@@ -112,13 +98,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[network.spec] network Page.setExtraHTTPHeaders *",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[network.spec] network Request.isNavigationRequest *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
@@ -175,25 +154,18 @@
"comment": "Chrome-specific test"
},
{
- "testIdPattern": "[requestinterception-experimental.spec] *",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[requestinterception.spec] *",
+ "testIdPattern": "[screencast.spec] *",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
+ "parameters": ["chrome"],
"expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "Currently no reliable ffmpeg downloads for testing https://github.com/puppeteer/puppeteer/issues/12121"
},
{
"testIdPattern": "[screencast.spec] *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
"expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "CDP-specific feature"
},
{
"testIdPattern": "[screenshot.spec] Screenshots Cdp *",
@@ -224,20 +196,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"button\"",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"heading\"",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[autofill.spec] *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "chrome-headless-shell"],
@@ -363,14 +321,14 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[devtools.spec] DevTools target.page() should return a DevTools page if asPage is used",
+ "testIdPattern": "[devtools.spec] DevTools target.page() should return a DevTools page if custom isPageTarget is provided",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
"expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[devtools.spec] DevTools target.page() should return a DevTools page if custom isPageTarget is provided",
+ "testIdPattern": "[devtools.spec] DevTools target.page() should return Page when calling asPage on DevTools target",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
"expectations": ["SKIP"],
@@ -391,13 +349,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[elementhandle.spec] ElementHandle specs ElementHandle.clickablePoint should not work if the click box is not visible due to the iframe",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluate should replace symbols with undefined",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp"],
@@ -440,13 +391,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[frame.spec] Frame specs Frame Management should handle nested frames",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[frame.spec] Frame specs Frame Management should report frame.name()",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
@@ -482,17 +426,17 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[jshandle.spec] JSHandle Page.evaluateHandle should return the RemoteObject",
+ "testIdPattern": "[jshandle.spec] JSHandle JSHandle.toString should work with window subtypes",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
+ "parameters": ["cdp"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "CDP does not have special type for window"
},
{
- "testIdPattern": "[keyboard.spec] Keyboard should send a character with sendCharacter in iframe",
+ "testIdPattern": "[jshandle.spec] JSHandle Page.evaluateHandle should return the RemoteObject",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
- "expectations": ["SKIP"],
+ "expectations": ["FAIL"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
@@ -580,6 +524,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[navigation.spec] navigation Page.goto should navigate to URL with hash and fire requests without hash",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "BiDi spec expect the request to not trim the hash"
+ },
+ {
"testIdPattern": "[navigation.spec] navigation Page.goto should send referer",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
@@ -599,11 +550,11 @@
"expectations": ["PASS"]
},
{
- "testIdPattern": "[network.spec] network Page.setBypassServiceWorker *",
- "platforms": ["win32"],
+ "testIdPattern": "[network.spec] network Page.setExtraHTTPHeaders *",
+ "platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "Firefox does not support headers override"
},
{
"testIdPattern": "[network.spec] network Request.initiator should return the initiator",
@@ -625,6 +576,12 @@
"expectations": ["PASS"]
},
{
+ "testIdPattern": "[network.spec] network Request.isNavigationRequest should work with request interception",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["PASS"]
+ },
+ {
"testIdPattern": "[network.spec] network Request.postData should be |undefined| when there is no post data",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
@@ -671,7 +628,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "See https://github.com/puppeteer/puppeteer/issues/4840"
},
{
"testIdPattern": "[page.spec] Page Page.addStyleTag should throw when added with content to the CSP page",
@@ -681,13 +638,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[page.spec] Page Page.bringToFront should work",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[page.spec] Page Page.close should *not* run beforeunload by default",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -713,7 +663,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "BiDi does not support getting a Handle for log args"
},
{
"testIdPattern": "[page.spec] Page Page.Events.Console should return remote objects",
@@ -744,18 +694,11 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[page.spec] Page Page.exposeFunction should work with loading frames",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "Missing request interception"
- },
- {
"testIdPattern": "[page.spec] Page Page.pdf should respect timeout",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
"expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "https://github.com/puppeteer/puppeteer/issues/12152"
},
{
"testIdPattern": "[page.spec] Page Page.setBypassCSP *",
@@ -765,13 +708,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[page.spec] Page Page.setCacheEnabled should stay disabled when toggling request interception on/off",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[page.spec] Page Page.setOfflineMode should emulate navigator.onLine",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["webDriverBiDi"],
@@ -802,6 +738,13 @@
{
"testIdPattern": "[prerender.spec] Prerender can screencast",
"platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome"],
+ "expectations": ["SKIP"],
+ "comment": "Currently no reliable ffmpeg downloads for testing https://github.com/puppeteer/puppeteer/issues/12121"
+ },
+ {
+ "testIdPattern": "[prerender.spec] Prerender can screencast",
+ "platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
"expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
@@ -849,6 +792,27 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should navigate to URL with hash and fire requests without hash",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "BiDi spec expect the request to not trim the hash"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Request.continue *",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs full support for continueRequest in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1850680"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Request.respond *",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs full support for continueResponse in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1853887"
+ },
+ {
"testIdPattern": "[requestinterception.spec] *",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -856,6 +820,55 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should be abortable with custom error codes",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`HTTPRequest.resourceType()` has no eqivalent in BiDi spec"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should intercept",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`request.postData()` has no eqivalent in BiDi spec"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should navigate to URL with hash and fire requests without hash",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "BiDi spec and WPT require expect the Hash"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`HTTPRequest.resourceType()` has no eqivalent in BiDi spec"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects for subresources",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`HTTPRequest.resourceType()` has no eqivalent in BiDi spec"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Request.continue *",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs full support for continueRequest in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1850680"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Request.respond *",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs full support for continueResponse in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1853887"
+ },
+ {
"testIdPattern": "[screencast.spec] Screencasts Page.screencast should validate options",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox"],
@@ -953,53 +966,74 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[bfcache.spec] BFCache can navigate to a BFCached page containing an OOPIF and a worker",
+ "testIdPattern": "[accessibility.spec] Accessibility should work",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "firefox"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "parameters": ["chrome", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Change in A11Y tree on Canary"
},
{
- "testIdPattern": "[browser.spec] Browser specs Browser.isConnected should set the browser connected state",
+ "testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryAllArray $$eval should handle many elements",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome", "webDriverBiDi"],
+ "expectations": ["PASS", "TIMEOUT"],
+ "comment": "times out flakily"
+ },
+ {
+ "testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"button\"",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Querying by a11y attributes is not standard behavior"
+ },
+ {
+ "testIdPattern": "[ariaqueryhandler.spec] AriaQueryHandler queryOne (Chromium web test) should find by role \"heading\"",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Querying by a11y attributes is not standard behavior"
+ },
+ {
+ "testIdPattern": "[bfcache.spec] BFCache can navigate to a BFCached page containing an OOPIF and a worker",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["cdp", "firefox"],
"expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[browser.spec] Browser specs Browser.process should not return child_process for remote browser",
+ "testIdPattern": "[browser.spec] Browser specs Browser.isConnected should set the browser connected state",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[browser.spec] Browser specs Browser.userAgent should include Browser engine",
+ "testIdPattern": "[browser.spec] Browser specs Browser.process should keep connected after the last page is closed",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "The new headless does not allow opening a tab after the browser was closed"
},
{
- "testIdPattern": "[browser.spec] Browser specs Browser.userAgent should include Browser engine",
+ "testIdPattern": "[browser.spec] Browser specs Browser.process should not return child_process for remote browser",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
+ "expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[browser.spec] Browser specs Browser.version should return version",
+ "testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should deny permission when not listed",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
+ "parameters": ["cdp", "firefox"],
"expectations": ["FAIL"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should deny permission when not listed",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "firefox"],
+ "parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1894217"
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should fail when bad permission is given",
@@ -1015,6 +1049,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should grant permission when listed",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1894217"
+ },
+ {
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should grant persistent-storage",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1022,6 +1063,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should grant persistent-storage",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1894217"
+ },
+ {
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should isolate permissions between browser contexts",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1029,6 +1077,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should isolate permissions between browser contexts",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1894217"
+ },
+ {
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should reset permissions",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1036,6 +1091,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should reset permissions",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1894217"
+ },
+ {
"testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should trigger permission onchange",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1043,10 +1105,11 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[browsercontext.spec] BrowserContext should create new incognito context",
+ "testIdPattern": "[browsercontext.spec] BrowserContext BrowserContext.overridePermissions should trigger permission onchange",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["PASS"]
+ "expectations": ["FAIL"],
+ "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1894217"
},
{
"testIdPattern": "[browsercontext.spec] BrowserContext should fire target events",
@@ -1063,12 +1126,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[browsercontext.spec] BrowserContext should have default context",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["PASS"]
- },
- {
"testIdPattern": "[browsercontext.spec] BrowserContext should wait for a target",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1106,13 +1163,6 @@
{
"testIdPattern": "[CDPSession.spec] Target.createCDPSession should respect custom timeout",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[CDPSession.spec] Target.createCDPSession should respect custom timeout",
- "platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
@@ -1139,13 +1189,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[chromiumonly.spec] Chromium-Specific Page Tests Page.setRequestInterception should work with intervention headers",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[click.spec] Page.click should click on checkbox label and toggle",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1160,20 +1203,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[click.spec] Page.click should click the button with deviceScaleFactor set",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[click.spec] Page.click should click the button with fixed position inside an iframe",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[click.spec] Page.click should click the button with fixed position inside an iframe",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1248,7 +1277,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "Firefox default partition key is inconsistent: #12004"
},
{
"testIdPattern": "[cookies.spec] Cookie specs Page.deleteCookie should delete cookie",
@@ -1269,7 +1298,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "Firefox default partition key is inconsistent: #12004"
},
{
"testIdPattern": "[cookies.spec] Cookie specs Page.deleteCookie should not delete cookie for different domain",
@@ -1311,7 +1340,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[cookies.spec] Cookie specs Page.setCookie should set cookie with reasonable defaults",
@@ -1332,7 +1361,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[cookies.spec] Cookie specs Page.setCookie should set multiple cookies",
@@ -1346,7 +1375,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[cookies.spec] Cookie specs Page.setCookie should set secure same-site cookies from a frame",
@@ -1367,7 +1396,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[debugInfo.spec] DebugInfo Browser.debugInfo should work",
@@ -1381,7 +1410,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL", "PASS"],
- "comment": "https://github.com/puppeteer/puppeteer/issues/12010"
+ "comment": "Firefox CDP does not support isolation so this test might fail if other tests set cookies"
},
{
"testIdPattern": "[defaultbrowsercontext.spec] DefaultBrowserContext page.deleteCookie() should work",
@@ -1395,7 +1424,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[defaultbrowsercontext.spec] DefaultBrowserContext page.setCookie() should work",
@@ -1409,7 +1438,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=1884648"
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[device-request-prompt.spec] device request prompt does not crash",
@@ -1594,13 +1623,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[emulation.spec] Emulation Page.viewport should load correct pictures when emulation dpr",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[emulation.spec] Emulation Page.viewport should support landscape emulation",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1622,13 +1644,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[emulation.spec] Emulation Page.viewport should update media queries when resoltion changes",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[evaluation.spec] Evaluation specs Page.evaluate should simulate a user gesture",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -1755,6 +1770,12 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[idle_override.spec] Emulate idle state changing idle state emulation causes change of the IdleDetector state",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome", "webDriverBiDi"],
+ "expectations": ["PASS"]
+ },
+ {
"testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors Response.securityDetails Network redirects should report SecurityDetails",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
@@ -1813,25 +1834,11 @@
{
"testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors should work with request interception",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors should work with request interception",
- "platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[ignorehttpserrors.spec] ignoreHTTPSErrors should work with request interception",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[input.spec] input tests FileChooser.accept should accept single file",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
@@ -2212,13 +2219,6 @@
{
"testIdPattern": "[launcher.spec] Launcher specs Puppeteer Browser.disconnect should reject navigation when browser closes",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "https://github.com/puppeteer/puppeteer/issues/11849"
- },
- {
- "testIdPattern": "[launcher.spec] Launcher specs Puppeteer Browser.disconnect should reject navigation when browser closes",
- "platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL", "PASS"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
@@ -2228,7 +2228,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "https://github.com/puppeteer/puppeteer/issues/11849"
},
{
"testIdPattern": "[launcher.spec] Launcher specs Puppeteer Puppeteer.connect should be able to close remote browser",
@@ -2350,20 +2350,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[launcher.spec] Launcher specs Puppeteer Puppeteer.launch can launch and close the browser",
- "platforms": ["win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[launcher.spec] Launcher specs Puppeteer Puppeteer.launch should be able to launch Chrome",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[launcher.spec] Launcher specs Puppeteer Puppeteer.launch should be able to launch Firefox",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
@@ -2546,20 +2532,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[navigation.spec] navigation Page.goto should navigate to URL with hash and fire requests without hash",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[navigation.spec] navigation Page.goto should not leak listeners during navigation",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[navigation.spec] navigation Page.goto should send referer",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -2696,8 +2668,7 @@
"testIdPattern": "[network.spec] network Network Events Page.Events.RequestServedFromCache",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "expectations": ["PASS"]
},
{
"testIdPattern": "[network.spec] network Network Events Page.Events.Response",
@@ -2742,6 +2713,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[network.spec] network Page.authenticate should allow disable authentication",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL", "PASS"],
+ "comment": "FAIL: The Puppeteer implementation does not expect 2 responseCompleted events (that AuthRequired triggered). PASS: Only one event on late beta (Bug 1893664)."
+ },
+ {
"testIdPattern": "[network.spec] network Page.authenticate should fail if wrong credentials",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -2756,6 +2734,13 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[network.spec] network Page.authenticate should not disable caching",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Firefox returns `fromCache: false`"
+ },
+ {
"testIdPattern": "[network.spec] network Page.authenticate should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -2763,6 +2748,20 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[network.spec] network Page.authenticate should work",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome", "webDriverBiDi"],
+ "expectations": ["FAIL", "PASS"],
+ "comment": "Flaky see https://github.com/puppeteer/puppeteer/issues/12253"
+ },
+ {
+ "testIdPattern": "[network.spec] network Page.authenticate should work",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["TIMEOUT"],
+ "comment": "When navigating to page with authentication the command response (error) never comes without interception"
+ },
+ {
"testIdPattern": "[network.spec] network Page.setExtraHTTPHeaders should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -2847,13 +2846,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[network.spec] network Response.buffer should throw if the response does not have a body",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[network.spec] network Response.buffer should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -2890,13 +2882,6 @@
},
{
"testIdPattern": "[network.spec] network Response.fromServiceWorker Response.fromServiceWorker",
- "platforms": ["win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[network.spec] network Response.fromServiceWorker Response.fromServiceWorker",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["SKIP"],
@@ -2931,13 +2916,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[network.spec] network Response.text should wait until response completes",
- "platforms": ["win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[network.spec] network Response.text should work",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -2980,38 +2958,17 @@
"comment": "Failed previously and currently times out"
},
{
- "testIdPattern": "[oopif.spec] OOPIF should load oopif iframes with subresources and request interception",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[oopif.spec] OOPIF should load oopif iframes with subresources and request interception",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
- "testIdPattern": "[oopif.spec] OOPIF should report google.com frame",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["chrome", "webDriverBiDi"],
- "expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[oopif.spec] OOPIF should report google.com frame",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
+ "expectations": ["FAIL", "TIMEOUT"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
"testIdPattern": "[oopif.spec] OOPIF should support lazy OOP frames",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["firefox", "webDriverBiDi"],
- "expectations": ["FAIL"],
+ "expectations": ["FAIL", "TIMEOUT"],
"comment": "https://bugzilla.mozilla.org/show_bug.cgi?id=187816"
},
{
@@ -3082,7 +3039,7 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "chrome"],
"expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "See https://github.com/puppeteer/puppeteer/issues/4840"
},
{
"testIdPattern": "[page.spec] Page Page.addScriptTag should throw when added with content to the CSP page",
@@ -3311,6 +3268,13 @@
{
"testIdPattern": "[page.spec] Page Page.setCacheEnabled should stay disabled when toggling request interception on/off",
"platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ },
+ {
+ "testIdPattern": "[page.spec] Page Page.setCacheEnabled should stay disabled when toggling request interception on/off",
+ "platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
"expectations": ["FAIL"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
@@ -3369,14 +3333,14 @@
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "headful"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "only works in the old headless code"
},
{
"testIdPattern": "[pdf.spec] Page.pdf can print to PDF with outline",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["chrome", "headless"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "only works in the old headless code"
},
{
"testIdPattern": "[proxy.spec] request proxy in incognito browser context should proxy requests when configured at context level",
@@ -3426,6 +3390,158 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should be able to fetch dataURL and fire dataURL requests",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for data URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1805176"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should be able to remove headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs investigation, on Firefox the test is passing even if the origin header is not removed"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should be abortable with custom error codes",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Test relies on chrome-only error code (Firefox currently outputs NS_ERROR_ABORT)"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should cache if cache enabled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for enabling cache in BiDi without CDP https://github.com/w3c/webdriver-bidi/issues/582"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should cooperatively continue by priority",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs full support for continueRequest in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1850680"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should cooperatively respond by priority",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs full support for continueRequest in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1850680"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should intercept",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs Puppeteer support for BidiHTTPRequest.postData"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should load fonts if cache enabled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for enabling cache in BiDi without CDP https://github.com/w3c/webdriver-bidi/issues/582"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should navigate to dataURL and fire dataURL requests",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for data URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1805176"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should not cache if cache disabled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for enabling cache in BiDi without CDP https://github.com/w3c/webdriver-bidi/issues/582"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should send referer",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should show custom HTTP headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work when header manipulation headers with redirect",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs investigation, on Firefox the test is passing even if headers are not actually modified"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with custom referer headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with encoded server - 2",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for data URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1805176"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with equal requests",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "TODO: Needs investigation, it looks like Firefox lets the request go also to the server"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with file URLs",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for file URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1826210"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with redirects",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for BidiHTTPRequest.resourceType"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with redirects for subresources",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for BidiHTTPRequest.resourceType"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with requests without networkId",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Test requires CDP"
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Request.continue should work",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["PASS"]
+ },
+ {
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Request.respond should indicate already-handled if an intercept has been handled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["PASS"]
+ },
+ {
"testIdPattern": "[requestinterception-experimental.spec] request interception \"after each\" hook in \"request interception\"",
"platforms": ["win32"],
"parameters": ["cdp", "chrome"],
@@ -3454,6 +3570,55 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should be able to fetch dataURL and fire dataURL requests",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for data URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1805176"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should be able to remove headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs investigation, on Firefox the test is passing even if the origin header is not removed"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should be abortable with custom error codes",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Test relies on chrome-only error code (Firefox currently outputs NS_ERROR_ABORT)"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should cache if cache enabled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for enabling cache in BiDi without CDP https://github.com/w3c/webdriver-bidi/issues/582"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should intercept",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs Puppeteer support for BidiHTTPRequest.postData"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should load fonts if cache enabled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for enabling cache in BiDi without CDP https://github.com/w3c/webdriver-bidi/issues/582"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should navigate to dataURL and fire dataURL requests",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for data URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1805176"
+ },
+ {
"testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should navigate to URL with hash and fire requests without hash",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "chrome"],
@@ -3461,6 +3626,117 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should not cache if cache disabled",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for enabling cache in BiDi without CDP https://github.com/w3c/webdriver-bidi/issues/582"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should send referer",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should send referer",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should show custom HTTP headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should show custom HTTP headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work when header manipulation headers with redirect",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs investigation, on Firefox the test is passing even if headers are not actually modified"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with custom referer headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with custom referer headers",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Firefox does not support headers override"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with encoded server - 2",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for data URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1805176"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with equal requests",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "TODO: Needs investigation"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with file URLs",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for file URIs in Firefox https://bugzilla.mozilla.org/show_bug.cgi?id=1826210"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for BidiHTTPRequest.resourceType"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects for subresources",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "TODO: Needs support for BidiHTTPRequest.resourceType"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with requests without networkId",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["SKIP"],
+ "comment": "Test requires CDP"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with requests without networkId",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "CDP specific issue, maybe we can support it from BiDi+"
+ },
+ {
+ "testIdPattern": "[requestinterception.spec] request interception Request.continue should work",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["PASS"]
+ },
+ {
"testIdPattern": "[screenshot.spec] Screenshots Cdp should use scale for clip",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "firefox"],
@@ -3789,6 +4065,12 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
+ "testIdPattern": "[worker.spec] Workers should report errors",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["firefox", "webDriverBiDi"],
+ "expectations": ["PASS"]
+ },
+ {
"testIdPattern": "[CDPSession.spec] Target.createCDPSession should send events",
"platforms": ["win32"],
"parameters": ["cdp", "chrome", "headless"],
@@ -3810,14 +4092,14 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[devtools.spec] DevTools target.page() should return a DevTools page if asPage is used",
+ "testIdPattern": "[devtools.spec] DevTools target.page() should return a DevTools page if custom isPageTarget is provided",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "chrome", "chrome-headless-shell"],
"expectations": ["SKIP"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[devtools.spec] DevTools target.page() should return a DevTools page if custom isPageTarget is provided",
+ "testIdPattern": "[devtools.spec] DevTools target.page() should return Page when calling asPage on DevTools target",
"platforms": ["darwin", "linux", "win32"],
"parameters": ["cdp", "chrome", "chrome-headless-shell"],
"expectations": ["SKIP"],
@@ -3845,13 +4127,6 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[launcher.spec] Launcher specs Puppeteer Puppeteer.launch userDataDir option restores preferences",
- "platforms": ["win32"],
- "parameters": ["firefox", "headless", "webDriverBiDi"],
- "expectations": ["SKIP"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
- },
- {
"testIdPattern": "[network.spec] network Network Events Page.Events.Request",
"platforms": ["linux"],
"parameters": ["cdp", "chrome", "headless"],
@@ -3873,52 +4148,52 @@
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should be abortable",
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should be abortable with custom error codes",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "chrome", "headful"],
- "expectations": ["FAIL", "PASS"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "parameters": ["chrome", "headless", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`HTTPRequest.resourceType()` has no eqivalent in BiDi spec"
},
{
- "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects",
- "platforms": ["win32"],
- "parameters": ["cdp", "chrome", "headless"],
- "expectations": ["FAIL", "PASS"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should intercept",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome", "headless", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`request.postData()` has no eqivalent in BiDi spec"
},
{
- "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects",
- "platforms": ["win32"],
- "parameters": ["cdp", "chrome", "headful"],
- "expectations": ["FAIL", "PASS"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with redirects",
+ "platforms": ["darwin", "linux", "win32"],
+ "parameters": ["chrome", "headless", "webDriverBiDi"],
+ "expectations": ["FAIL"],
+ "comment": "`HTTPRequest.resourceType()` has no eqivalent in BiDi spec"
},
{
- "testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work for an element with an offset",
+ "testIdPattern": "[requestinterception-experimental.spec] cooperative request interception Page.setRequestInterception should work with redirects for subresources",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "firefox", "headful"],
+ "parameters": ["chrome", "headless", "webDriverBiDi"],
"expectations": ["FAIL"],
- "comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
+ "comment": "`HTTPRequest.resourceType()` has no eqivalent in BiDi spec"
},
{
- "testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work for an element with an offset",
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should be abortable",
"platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "firefox", "headless"],
- "expectations": ["FAIL"],
+ "parameters": ["cdp", "chrome", "headful"],
+ "expectations": ["FAIL", "PASS"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work with a rotated element",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "firefox", "headful"],
- "expectations": ["FAIL"],
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects",
+ "platforms": ["win32"],
+ "parameters": ["cdp", "chrome", "headless"],
+ "expectations": ["FAIL", "PASS"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
- "testIdPattern": "[screenshot.spec] Screenshots ElementHandle.screenshot should work with a rotated element",
- "platforms": ["darwin", "linux", "win32"],
- "parameters": ["cdp", "firefox", "headless"],
- "expectations": ["FAIL"],
+ "testIdPattern": "[requestinterception.spec] request interception Page.setRequestInterception should work with redirects",
+ "platforms": ["win32"],
+ "parameters": ["cdp", "chrome", "headful"],
+ "expectations": ["FAIL", "PASS"],
"comment": "TODO: add a comment explaining why this expectation is required (include links to issues)"
},
{
diff --git a/remote/test/puppeteer/test/TestSuites.json b/remote/test/puppeteer/test/TestSuites.json
index 3c36f8d7a4..1b36a3ef4c 100644
--- a/remote/test/puppeteer/test/TestSuites.json
+++ b/remote/test/puppeteer/test/TestSuites.json
@@ -45,7 +45,7 @@
{
"id": "chrome-bidi",
"platforms": ["linux"],
- "parameters": ["chrome", "chrome-headless-shell", "webDriverBiDi"],
+ "parameters": ["chrome", "headless", "webDriverBiDi"],
"expectedLineCoverage": 56
}
],
diff --git a/remote/test/puppeteer/test/golden-chrome/screenshot-element-clip.png b/remote/test/puppeteer/test/golden-chrome/screenshot-element-clip.png
new file mode 100644
index 0000000000..609952cd3d
--- /dev/null
+++ b/remote/test/puppeteer/test/golden-chrome/screenshot-element-clip.png
Binary files differ
diff --git a/remote/test/puppeteer/test/golden-firefox/screenshot-element-clip.png b/remote/test/puppeteer/test/golden-firefox/screenshot-element-clip.png
new file mode 100644
index 0000000000..609952cd3d
--- /dev/null
+++ b/remote/test/puppeteer/test/golden-firefox/screenshot-element-clip.png
Binary files differ
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js b/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js
index 4776d7e261..b0982cdd90 100644
--- a/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js
@@ -13,7 +13,11 @@ import puppeteer from 'puppeteer-core';
executablePath: 'node',
});
} catch (error) {
- if (error.message.includes('Failed to launch the browser process')) {
+ if (
+ error.message.includes(
+ 'Browser was not found at the configured executablePath (node)'
+ )
+ ) {
process.exit(0);
}
console.error(error);
diff --git a/remote/test/puppeteer/test/installation/package.json b/remote/test/puppeteer/test/installation/package.json
index bd21ac4b0a..17ee450391 100644
--- a/remote/test/puppeteer/test/installation/package.json
+++ b/remote/test/puppeteer/test/installation/package.json
@@ -44,7 +44,7 @@
"assets"
],
"dependencies": {
- "glob": "10.3.10",
- "mocha": "10.3.0"
+ "glob": "10.3.12",
+ "mocha": "10.4.0"
}
}
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts
index b599af01dc..addaebbbd0 100644
--- a/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts
@@ -5,6 +5,8 @@
*/
import assert from 'assert';
+import {spawnSync} from 'child_process';
+import {existsSync} from 'fs';
import {readdir} from 'fs/promises';
import {platform} from 'os';
import {join} from 'path';
@@ -49,3 +51,36 @@ import {readAsset} from './util.js';
});
}
);
+
+describe('Firefox download', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ PUPPETEER_SKIP_DOWNLOAD: 'true',
+ };
+ },
+ });
+
+ it('can download Firefox stable', async function () {
+ assert.ok(!existsSync(join(this.sandbox, '.cache', 'puppeteer')));
+ const result = spawnSync(
+ 'npx',
+ ['puppeteer', 'browsers', 'install', 'firefox@stable'],
+ {
+ // npx is not found without the shell flag on Windows.
+ shell: process.platform === 'win32',
+ cwd: this.sandbox,
+ env: {
+ ...process.env,
+ PUPPETEER_CACHE_DIR: join(this.sandbox, '.cache', 'puppeteer'),
+ },
+ }
+ );
+ assert.strictEqual(result.status, 0);
+ const files = await readdir(join(this.sandbox, '.cache', 'puppeteer'));
+ assert.equal(files.length, 1);
+ assert.equal(files[0], 'firefox');
+ });
+});
diff --git a/remote/test/puppeteer/test/src/ariaqueryhandler.spec.ts b/remote/test/puppeteer/test/src/ariaqueryhandler.spec.ts
index 0ffb8ae6a5..4ab1df3a0a 100644
--- a/remote/test/puppeteer/test/src/ariaqueryhandler.spec.ts
+++ b/remote/test/puppeteer/test/src/ariaqueryhandler.spec.ts
@@ -697,20 +697,13 @@ describe('AriaQueryHandler', () => {
ElementHandle<HTMLButtonElement>
>;
const ids = await getIds(found);
- expect(ids).toEqual([
- 'node5',
- 'node6',
- 'node7',
- 'node8',
- 'node10',
- 'node21',
- ]);
+ expect(ids).toEqual(['node5', 'node6', 'node8', 'node10', 'node21']);
});
it('should find by role "heading"', async () => {
const {page} = await setupPage();
const found = await page.$$('aria/[role="heading"]');
const ids = await getIds(found);
- expect(ids).toEqual(['shown', 'hidden', 'node11', 'node13']);
+ expect(ids).toEqual(['shown', 'node11', 'node13']);
});
it('should find both ignored and unignored', async () => {
const {page} = await setupPage();
diff --git a/remote/test/puppeteer/test/src/browser.spec.ts b/remote/test/puppeteer/test/src/browser.spec.ts
index b8e0c8bb07..edfa075c4d 100644
--- a/remote/test/puppeteer/test/src/browser.spec.ts
+++ b/remote/test/puppeteer/test/src/browser.spec.ts
@@ -6,7 +6,7 @@
import expect from 'expect';
-import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
+import {getTestState, launch, setupTestBrowserHooks} from './mocha-utils.js';
describe('Browser specs', function () {
setupTestBrowserHooks();
@@ -64,6 +64,23 @@ describe('Browser specs', function () {
expect(remoteBrowser.process()).toBe(null);
await remoteBrowser.disconnect();
});
+ it('should keep connected after the last page is closed', async () => {
+ const {browser, close} = await launch({}, {createContext: false});
+ try {
+ const pages = await browser.pages();
+ await Promise.all(
+ pages.map(page => {
+ return page.close();
+ })
+ );
+ // Verify the browser is still connected.
+ expect(browser.connected).toBe(true);
+ // Verify the browser can open a new page.
+ await browser.newPage();
+ } finally {
+ await close();
+ }
+ });
});
describe('Browser.isConnected', () => {
diff --git a/remote/test/puppeteer/test/src/cdp/CDPSession.spec.ts b/remote/test/puppeteer/test/src/cdp/CDPSession.spec.ts
index 887152f097..01b0009433 100644
--- a/remote/test/puppeteer/test/src/cdp/CDPSession.spec.ts
+++ b/remote/test/puppeteer/test/src/cdp/CDPSession.spec.ts
@@ -134,7 +134,7 @@ describe('Target.createCDPSession', function () {
}
)
).rejects.toThrowError(
- `Runtime.evaluate timed out. Increase the 'protocolTimeout' setting in launch/connect calls for a higher timeout if needed.`
+ /Increase the 'protocolTimeout' setting in launch\/connect calls for a higher timeout if needed./gi
);
});
diff --git a/remote/test/puppeteer/test/src/cdp/devtools.spec.ts b/remote/test/puppeteer/test/src/cdp/devtools.spec.ts
index c48b4c353b..0f9330d15f 100644
--- a/remote/test/puppeteer/test/src/cdp/devtools.spec.ts
+++ b/remote/test/puppeteer/test/src/cdp/devtools.spec.ts
@@ -67,9 +67,9 @@ describe('DevTools', function () {
return 2 * 3;
})
).toBe(6);
- expect(await browser.pages()).toContainEqual(page);
+ expect(await browser.pages()).toContain(page);
});
- it('target.page() should return a DevTools page if asPage is used', async function () {
+ it('target.page() should return Page when calling asPage on DevTools target', async function () {
const {puppeteer} = await getTestState({skipLaunch: true});
const originalBrowser = await launchBrowser(launchOptions);
@@ -87,7 +87,8 @@ describe('DevTools', function () {
return 2 * 3;
})
).toBe(6);
- expect(await browser.pages()).toContainEqual(page);
+ // The page won't be part of browser.pages() if a custom isPageTarget is not provided
+ expect(await browser.pages()).not.toContain(page);
});
it('should open devtools when "devtools: true" option is given', async () => {
const browser = await launchBrowser(
diff --git a/remote/test/puppeteer/test/src/elementhandle.spec.ts b/remote/test/puppeteer/test/src/elementhandle.spec.ts
index e0f1e41878..434ac9ca40 100644
--- a/remote/test/puppeteer/test/src/elementhandle.spec.ts
+++ b/remote/test/puppeteer/test/src/elementhandle.spec.ts
@@ -385,8 +385,15 @@ describe('ElementHandle specs', function () {
await page.setContent(
`<iframe name='frame' style='position: absolute; left: -100px' srcdoc="<button style='width: 10px; height: 10px;'></button>"></iframe>`
);
- const frame = await page.waitForFrame(frame => {
- return frame.name() === 'frame';
+ const frame = await page.waitForFrame(async frame => {
+ using element = await frame.frameElement();
+ if (!element) {
+ return false;
+ }
+ const name = await element.evaluate(frame => {
+ return frame.name;
+ });
+ return name === 'frame';
});
using handle = await frame.locator('button').waitHandle();
@@ -395,8 +402,15 @@ describe('ElementHandle specs', function () {
await page.setContent(
`<iframe name='frame2' style='position: absolute; top: -100px' srcdoc="<button style='width: 10px; height: 10px;'></button>"></iframe>`
);
- const frame2 = await page.waitForFrame(frame => {
- return frame.name() === 'frame2';
+ const frame2 = await page.waitForFrame(async frame => {
+ using element = await frame.frameElement();
+ if (!element) {
+ return false;
+ }
+ const name = await element.evaluate(frame => {
+ return frame.name;
+ });
+ return name === 'frame2';
});
using handle2 = await frame2.locator('button').waitHandle();
diff --git a/remote/test/puppeteer/test/src/frame.spec.ts b/remote/test/puppeteer/test/src/frame.spec.ts
index a49fb19482..758725f932 100644
--- a/remote/test/puppeteer/test/src/frame.spec.ts
+++ b/remote/test/puppeteer/test/src/frame.spec.ts
@@ -7,6 +7,7 @@
import expect from 'expect';
import {CDPSession} from 'puppeteer-core/internal/api/CDPSession.js';
import type {Frame} from 'puppeteer-core/internal/api/Frame.js';
+import {assert} from 'puppeteer-core/internal/util/assert.js';
import {getTestState, setupTestBrowserHooks} from './mocha-utils.js';
import {
@@ -78,7 +79,7 @@ describe('Frame specs', function () {
const {page, server} = await getTestState();
await page.goto(server.PREFIX + '/frames/nested-frames.html');
- expect(dumpFrames(page.mainFrame())).toEqual([
+ expect(await dumpFrames(page.mainFrame())).toEqual([
'http://localhost:<PORT>/frames/nested-frames.html',
' http://localhost:<PORT>/frames/two-frames.html (2frames)',
' http://localhost:<PORT>/frames/frame.html (uno)',
@@ -232,23 +233,6 @@ describe('Frame specs', function () {
expect(page.frames()).toHaveLength(2);
expect(page.frames()[1]!.url()).toBe(server.EMPTY_PAGE);
});
- it('should report frame.name()', async () => {
- const {page, server} = await getTestState();
-
- await attachFrame(page, 'theFrameId', server.EMPTY_PAGE);
- await page.evaluate((url: string) => {
- const frame = document.createElement('iframe');
- frame.name = 'theFrameName';
- frame.src = url;
- document.body.appendChild(frame);
- return new Promise(x => {
- return (frame.onload = x);
- });
- }, server.EMPTY_PAGE);
- expect(page.frames()[0]!.name()).toBe('');
- expect(page.frames()[1]!.name()).toBe('theFrameId');
- expect(page.frames()[2]!.name()).toBe('theFrameName');
- });
it('should report frame.parent()', async () => {
const {page, server} = await getTestState();
@@ -306,4 +290,35 @@ describe('Frame specs', function () {
expect(page.mainFrame().client).toBeInstanceOf(CDPSession);
});
});
+
+ describe('Frame.prototype.frameElement', function () {
+ it('should work', async () => {
+ const {page, server} = await getTestState();
+
+ await attachFrame(page, 'theFrameId', server.EMPTY_PAGE);
+ await page.evaluate((url: string) => {
+ const frame = document.createElement('iframe');
+ frame.name = 'theFrameName';
+ frame.src = url;
+ document.body.appendChild(frame);
+ return new Promise(x => {
+ return (frame.onload = x);
+ });
+ }, server.EMPTY_PAGE);
+ using frame0 = await page.frames()[0]?.frameElement();
+ assert(!frame0);
+ using frame1 = await page.frames()[1]?.frameElement();
+ assert(frame1);
+ using frame2 = await page.frames()[2]?.frameElement();
+ assert(frame2);
+ const name1 = await frame1.evaluate(frame => {
+ return frame.id;
+ });
+ expect(name1).toBe('theFrameId');
+ const name2 = await frame2.evaluate(frame => {
+ return frame.name;
+ });
+ expect(name2).toBe('theFrameName');
+ });
+ });
});
diff --git a/remote/test/puppeteer/test/src/jshandle.spec.ts b/remote/test/puppeteer/test/src/jshandle.spec.ts
index 28097811e4..0c5de6cde0 100644
--- a/remote/test/puppeteer/test/src/jshandle.spec.ts
+++ b/remote/test/puppeteer/test/src/jshandle.spec.ts
@@ -326,6 +326,16 @@ describe('JSHandle', function () {
'JSHandle@proxy'
);
});
+ it('should work with window subtypes', async () => {
+ const {page} = await getTestState();
+
+ expect((await page.evaluateHandle('window')).toString()).toBe(
+ 'JSHandle@window'
+ );
+ expect((await page.evaluateHandle('globalThis')).toString()).toBe(
+ 'JSHandle@window'
+ );
+ });
});
describe('JSHandle[Symbol.dispose]', () => {
diff --git a/remote/test/puppeteer/test/src/keyboard.spec.ts b/remote/test/puppeteer/test/src/keyboard.spec.ts
index 9157465242..c6cc78c68b 100644
--- a/remote/test/puppeteer/test/src/keyboard.spec.ts
+++ b/remote/test/puppeteer/test/src/keyboard.spec.ts
@@ -186,8 +186,15 @@ describe('Keyboard', function () {
await page.setContent(`
<iframe srcdoc="<iframe name='test' srcdoc='<textarea></textarea>'></iframe>"</iframe>
`);
- const frame = await page.waitForFrame(frame => {
- return frame.name() === 'test';
+ const frame = await page.waitForFrame(async frame => {
+ using element = await frame.frameElement();
+ if (!element) {
+ return false;
+ }
+ const name = await element.evaluate(frame => {
+ return frame.name;
+ });
+ return name === 'test';
});
await frame.focus('textarea');
diff --git a/remote/test/puppeteer/test/src/launcher.spec.ts b/remote/test/puppeteer/test/src/launcher.spec.ts
index 876f8d1624..e1eefaceb1 100644
--- a/remote/test/puppeteer/test/src/launcher.spec.ts
+++ b/remote/test/puppeteer/test/src/launcher.spec.ts
@@ -116,6 +116,30 @@ describe('Launcher specs', function () {
const {close} = await launch({});
await close();
});
+
+ it('can launch multiple instances without node warnings', async () => {
+ const instances = [];
+ let warning = null;
+ const warningHandler: NodeJS.WarningListener = w => {
+ return (warning = w);
+ };
+ process.on('warning', warningHandler);
+ process.setMaxListeners(1);
+ try {
+ for (let i = 0; i < 2; i++) {
+ instances.push(launch({}));
+ }
+ await Promise.all(
+ (await Promise.all(instances)).map(instance => {
+ return instance.close();
+ })
+ );
+ } finally {
+ process.setMaxListeners(10);
+ }
+ process.off('warning', warningHandler);
+ expect(warning).toBe(null);
+ });
it('should have default url when launching browser', async function () {
const {browser, close} = await launch({}, {createContext: false});
try {
@@ -166,7 +190,9 @@ describe('Launcher specs', function () {
}).catch(error => {
return (waitError = error);
});
- expect(waitError.message).toContain('Failed to launch');
+ expect(waitError.message).toBe(
+ 'Browser was not found at the configured executablePath (random-invalid-path)'
+ );
});
it('userDataDir option', async () => {
const userDataDir = await mkdtemp(TMP_FOLDER);
@@ -591,6 +617,20 @@ describe('Launcher specs', function () {
});
expect(error.message).toContain('either pipe or debugging port');
});
+
+ it('throws an error if executable path is not valid with pipe=true', async () => {
+ const options = {
+ executablePath: '/tmp/does-not-exist',
+ pipe: true,
+ };
+ let error!: Error;
+ await launch(options).catch(error_ => {
+ return (error = error_);
+ });
+ expect(error.message).toContain(
+ 'Browser was not found at the configured executablePath (/tmp/does-not-exist)'
+ );
+ });
});
describe('Puppeteer.launch', function () {
@@ -793,7 +833,7 @@ describe('Launcher specs', function () {
const restoredPage = pages.find(page => {
return page.url() === server.PREFIX + '/frames/nested-frames.html';
})!;
- expect(dumpFrames(restoredPage.mainFrame())).toEqual([
+ expect(await dumpFrames(restoredPage.mainFrame())).toEqual([
'http://localhost:<PORT>/frames/nested-frames.html',
' http://localhost:<PORT>/frames/two-frames.html (2frames)',
' http://localhost:<PORT>/frames/frame.html (uno)',
diff --git a/remote/test/puppeteer/test/src/navigation.spec.ts b/remote/test/puppeteer/test/src/navigation.spec.ts
index dd59c98349..927dd02cd5 100644
--- a/remote/test/puppeteer/test/src/navigation.spec.ts
+++ b/remote/test/puppeteer/test/src/navigation.spec.ts
@@ -112,6 +112,27 @@ describe('navigation', function () {
const response = await page.goto(server.PREFIX + '/grid.html');
expect(response!.status()).toBe(200);
});
+ it('should work when reload causes history API in beforeunload', async () => {
+ const {page, server} = await getTestState();
+
+ await page.goto(server.EMPTY_PAGE);
+ await page.evaluate(() => {
+ window.addEventListener(
+ 'beforeunload',
+ () => {
+ return history.replaceState(null, 'initial', window.location.href);
+ },
+ false
+ );
+ });
+ await page.reload();
+ // Evaluate still works.
+ expect(
+ await page.evaluate(() => {
+ return 1;
+ })
+ ).toBe(1);
+ });
it('should navigate to empty page with networkidle0', async () => {
const {page, server} = await getTestState();
diff --git a/remote/test/puppeteer/test/src/network.spec.ts b/remote/test/puppeteer/test/src/network.spec.ts
index c6f51a3412..9d5b28d0c3 100644
--- a/remote/test/puppeteer/test/src/network.spec.ts
+++ b/remote/test/puppeteer/test/src/network.spec.ts
@@ -722,7 +722,7 @@ describe('network', function () {
} catch (error) {
// In headful, an error is thrown instead of 401.
if (
- !(error as Error).message.startsWith(
+ !(error as Error).message?.includes(
'net::ERR_INVALID_AUTH_CREDENTIALS'
)
) {
@@ -772,7 +772,7 @@ describe('network', function () {
} catch (error) {
// In headful, an error is thrown instead of 401.
if (
- !(error as Error).message.startsWith(
+ !(error as Error).message?.includes(
'net::ERR_INVALID_AUTH_CREDENTIALS'
)
) {
diff --git a/remote/test/puppeteer/test/src/page.spec.ts b/remote/test/puppeteer/test/src/page.spec.ts
index d83920d3ff..bc07b1d259 100644
--- a/remote/test/puppeteer/test/src/page.spec.ts
+++ b/remote/test/puppeteer/test/src/page.spec.ts
@@ -506,11 +506,14 @@ describe('Page', function () {
console.log(1, 2, 3, globalThis);
});
const log = await logPromise;
- expect(log.text()).toBe('1 2 3 JSHandle@object');
+
+ expect(log.text()).atLeastOneToContain([
+ '1 2 3 JSHandle@object',
+ '1 2 3 JSHandle@window',
+ ]);
expect(log.args()).toHaveLength(4);
- expect(await (await log.args()[3]!.getProperty('test')).jsonValue()).toBe(
- 1
- );
+ using property = await log.args()[3]!.getProperty('test');
+ expect(await property.jsonValue()).toBe(1);
});
it('should trigger correct Log', async () => {
const {page, server, isChrome} = await getTestState();
@@ -1210,13 +1213,15 @@ describe('Page', function () {
expect(result).toBe(36);
await page.removeExposedFunction('compute');
- let error: Error | null = null;
- await page
+ const error = await page
.evaluate(async function () {
return (globalThis as any).compute(9, 4);
})
- .catch(_error => {
- return (error = _error);
+ .then(() => {
+ return null;
+ })
+ .catch(error => {
+ return error;
});
expect(error).toBeTruthy();
});
diff --git a/remote/test/puppeteer/test/src/requestinterception-experimental.spec.ts b/remote/test/puppeteer/test/src/requestinterception-experimental.spec.ts
index 966554fd5d..ce3429f0b7 100644
--- a/remote/test/puppeteer/test/src/requestinterception-experimental.spec.ts
+++ b/remote/test/puppeteer/test/src/requestinterception-experimental.spec.ts
@@ -23,8 +23,7 @@ describe('cooperative request interception', function () {
describe('Page.setRequestInterception', function () {
const expectedActions: ActionResult[] = ['abort', 'continue', 'respond'];
- while (expectedActions.length > 0) {
- const expectedAction = expectedActions.pop();
+ for (const expectedAction of expectedActions) {
it(`should cooperatively ${expectedAction} by priority`, async () => {
const {page, server} = await getTestState();
@@ -94,24 +93,36 @@ describe('cooperative request interception', function () {
const {page, server} = await getTestState();
await page.setRequestInterception(true);
+ let requestError;
page.on('request', request => {
if (isFavicon(request)) {
void request.continue({}, 0);
return;
}
- expect(request.url()).toContain('empty.html');
- expect(request.headers()['user-agent']).toBeTruthy();
- expect(request.method()).toBe('GET');
- expect(request.postData()).toBe(undefined);
- expect(request.isNavigationRequest()).toBe(true);
- expect(request.resourceType()).toBe('document');
- expect(request.frame() === page.mainFrame()).toBe(true);
- expect(request.frame()!.url()).toBe('about:blank');
- void request.continue({}, 0);
+ try {
+ expect(request).toBeTruthy();
+ expect(request.url()).toContain('empty.html');
+ expect(request.headers()['user-agent']).toBeTruthy();
+ expect(request.method()).toBe('GET');
+ expect(request.postData()).toBe(undefined);
+ expect(request.isNavigationRequest()).toBe(true);
+ expect(request.resourceType()).toBe('document');
+ expect(request.frame()!.url()).toBe('about:blank');
+ expect(request.frame() === page.mainFrame()).toBe(true);
+ } catch (error) {
+ requestError = error;
+ } finally {
+ void request.continue({}, 0);
+ }
});
+
const response = (await page.goto(server.EMPTY_PAGE))!;
- expect(response!.ok()).toBe(true);
- expect(response!.remoteAddress().port).toBe(server.PORT);
+ if (requestError) {
+ throw requestError;
+ }
+
+ expect(response.ok()).toBe(true);
+ expect(response.remoteAddress().port).toBe(server.PORT);
});
// @see https://github.com/puppeteer/puppeteer/pull/3105
it('should work when POST is redirected with 302', async () => {
@@ -141,16 +152,24 @@ describe('cooperative request interception', function () {
server.setRedirect('/rrredirect', '/empty.html');
await page.setRequestInterception(true);
+ let requestError;
page.on('request', request => {
const headers = Object.assign({}, request.headers(), {
foo: 'bar',
});
void request.continue({headers}, 0);
-
- expect(request.continueRequestOverrides()).toEqual({headers});
+ try {
+ expect(request.continueRequestOverrides()).toEqual({headers});
+ } catch (error) {
+ requestError = error;
+ }
});
// Make sure that the goto does not time out.
await page.goto(server.PREFIX + '/rrredirect');
+
+ if (requestError) {
+ throw requestError;
+ }
});
// @see https://github.com/puppeteer/puppeteer/issues/4743
it('should be able to remove headers', async () => {
@@ -220,11 +239,20 @@ describe('cooperative request interception', function () {
foo: 'bar',
});
await page.setRequestInterception(true);
+ let requestError;
page.on('request', request => {
- expect(request.headers()['foo']).toBe('bar');
- void request.continue({}, 0);
+ try {
+ expect(request.headers()['foo']).toBe('bar');
+ } catch (error) {
+ requestError = error;
+ } finally {
+ void request.continue({}, 0);
+ }
});
const response = await page.goto(server.EMPTY_PAGE);
+ if (requestError) {
+ throw requestError;
+ }
expect(response!.ok()).toBe(true);
});
// @see https://github.com/puppeteer/puppeteer/issues/4337
@@ -250,11 +278,20 @@ describe('cooperative request interception', function () {
await page.setExtraHTTPHeaders({referer: server.EMPTY_PAGE});
await page.setRequestInterception(true);
+ let requestError;
page.on('request', request => {
- expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);
- void request.continue({}, 0);
+ try {
+ expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);
+ } catch (error) {
+ requestError = error;
+ } finally {
+ void request.continue({}, 0);
+ }
});
const response = await page.goto(server.EMPTY_PAGE);
+ if (requestError) {
+ throw requestError;
+ }
expect(response!.ok()).toBe(true);
});
it('should be abortable', async () => {
@@ -340,7 +377,7 @@ describe('cooperative request interception', function () {
if (isChrome) {
expect(error.message).toContain('net::ERR_FAILED');
} else {
- expect(error.message).toContain('NS_ERROR_FAILURE');
+ expect(error.message).toContain('NS_ERROR_ABORT');
}
});
it('should work with redirects', async () => {
@@ -947,14 +984,26 @@ describe('cooperative request interception', function () {
page.on('request', request => {
void request.continue();
});
+ let requestError;
page.on('request', request => {
- expect(request.isInterceptResolutionHandled()).toBeTruthy();
+ try {
+ expect(request.isInterceptResolutionHandled()).toBeTruthy();
+ } catch (error) {
+ requestError = error;
+ }
});
page.on('request', request => {
const {action} = request.interceptResolutionState();
- expect(action).toBe(InterceptResolutionAction.AlreadyHandled);
+ try {
+ expect(action).toBe(InterceptResolutionAction.AlreadyHandled);
+ } catch (error) {
+ requestError = error;
+ }
});
await page.goto(server.EMPTY_PAGE);
+ if (requestError) {
+ throw requestError;
+ }
});
});
});
diff --git a/remote/test/puppeteer/test/src/requestinterception.spec.ts b/remote/test/puppeteer/test/src/requestinterception.spec.ts
index 4b88d30a3b..2f73ae6974 100644
--- a/remote/test/puppeteer/test/src/requestinterception.spec.ts
+++ b/remote/test/puppeteer/test/src/requestinterception.spec.ts
@@ -22,23 +22,34 @@ describe('request interception', function () {
const {page, server} = await getTestState();
await page.setRequestInterception(true);
+ let requestError;
page.on('request', request => {
if (isFavicon(request)) {
void request.continue();
return;
}
- expect(request.url()).toContain('empty.html');
- expect(request.headers()['user-agent']).toBeTruthy();
- expect(request.headers()['accept']).toBeTruthy();
- expect(request.method()).toBe('GET');
- expect(request.postData()).toBe(undefined);
- expect(request.isNavigationRequest()).toBe(true);
- expect(request.resourceType()).toBe('document');
- expect(request.frame() === page.mainFrame()).toBe(true);
- expect(request.frame()!.url()).toBe('about:blank');
- void request.continue();
+ try {
+ expect(request).toBeTruthy();
+ expect(request.url()).toContain('empty.html');
+ expect(request.headers()['user-agent']).toBeTruthy();
+ expect(request.method()).toBe('GET');
+ expect(request.postData()).toBe(undefined);
+ expect(request.isNavigationRequest()).toBe(true);
+ expect(request.resourceType()).toBe('document');
+ expect(request.frame()!.url()).toBe('about:blank');
+ expect(request.frame() === page.mainFrame()).toBe(true);
+ } catch (error) {
+ requestError = error;
+ } finally {
+ void request.continue();
+ }
});
+
const response = (await page.goto(server.EMPTY_PAGE))!;
+ if (requestError) {
+ throw requestError;
+ }
+
expect(response.ok()).toBe(true);
expect(response.remoteAddress().port).toBe(server.PORT);
});
@@ -76,7 +87,11 @@ describe('request interception', function () {
});
void request.continue({headers});
});
- await page.goto(server.PREFIX + '/rrredirect');
+ const [request] = await Promise.all([
+ server.waitForRequest('/empty.html'),
+ page.goto(server.PREFIX + '/rrredirect'),
+ ]);
+ expect(request.headers['foo']).toBe('bar');
});
// @see https://github.com/puppeteer/puppeteer/issues/4743
it('should be able to remove headers', async () => {
@@ -162,11 +177,21 @@ describe('request interception', function () {
foo: 'bar',
});
await page.setRequestInterception(true);
+ let requestError;
page.on('request', request => {
- expect(request.headers()['foo']).toBe('bar');
- void request.continue();
+ try {
+ expect(request.headers()['foo']).toBe('bar');
+ } catch (error) {
+ requestError = error;
+ } finally {
+ void request.continue();
+ }
});
+
const response = (await page.goto(server.EMPTY_PAGE))!;
+ if (requestError) {
+ throw requestError;
+ }
expect(response.ok()).toBe(true);
});
// @see https://github.com/puppeteer/puppeteer/issues/4337
@@ -192,11 +217,13 @@ describe('request interception', function () {
await page.setExtraHTTPHeaders({referer: server.EMPTY_PAGE});
await page.setRequestInterception(true);
- page.on('request', request => {
- expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);
+ let request!: HTTPRequest;
+ page.on('request', req => {
+ request = req;
void request.continue();
});
const response = (await page.goto(server.EMPTY_PAGE))!;
+ expect(request.headers()['referer']).toBe(server.EMPTY_PAGE);
expect(response.ok()).toBe(true);
});
it('should be abortable', async () => {
@@ -267,7 +294,7 @@ describe('request interception', function () {
if (isChrome) {
expect(error.message).toContain('net::ERR_FAILED');
} else {
- expect(error.message).toContain('NS_ERROR_FAILURE');
+ expect(error.message).toContain('NS_ERROR_ABORT');
}
});
it('should work with redirects', async () => {
@@ -493,7 +520,7 @@ describe('request interception', function () {
))!;
expect(response.status()).toBe(200);
});
- it('should work wit h encoded server - 2', async () => {
+ it('should work with encoded server - 2', async () => {
const {page, server} = await getTestState();
// The requestWillBeSent will report URL as-is, whereas interception will
diff --git a/remote/test/puppeteer/test/src/screenshot.spec.ts b/remote/test/puppeteer/test/src/screenshot.spec.ts
index 9176d0c920..9880581217 100644
--- a/remote/test/puppeteer/test/src/screenshot.spec.ts
+++ b/remote/test/puppeteer/test/src/screenshot.spec.ts
@@ -393,6 +393,33 @@ describe('Screenshots', function () {
await context.close();
});
+
+ it('should use element clip', async () => {
+ const {page} = await getTestState();
+
+ await page.setViewport({width: 500, height: 500});
+ await page.setContent(`
+ something above
+ <style>div {
+ border: 2px solid blue;
+ background: green;
+ width: 50px;
+ height: 50px;
+ }
+ </style>
+ <div></div>
+ `);
+ using elementHandle = (await page.$('div'))!;
+ const screenshot = await elementHandle.screenshot({
+ clip: {
+ x: 10,
+ y: 10,
+ width: 20,
+ height: 20,
+ },
+ });
+ expect(screenshot).toBeGolden('screenshot-element-clip.png');
+ });
});
describe('Cdp', () => {
diff --git a/remote/test/puppeteer/test/src/utils.ts b/remote/test/puppeteer/test/src/utils.ts
index d1bad65a16..d0dc08c33b 100644
--- a/remote/test/puppeteer/test/src/utils.ts
+++ b/remote/test/puppeteer/test/src/utils.ts
@@ -112,15 +112,24 @@ export async function navigateFrame(
}
}
-export const dumpFrames = (frame: Frame, indentation?: string): string[] => {
+export const dumpFrames = async (
+ frame: Frame,
+ indentation?: string
+): Promise<string[]> => {
indentation = indentation || '';
let description = frame.url().replace(/:\d{4,5}\//, ':<PORT>/');
- if (frame.name()) {
- description += ' (' + frame.name() + ')';
+ using element = await frame.frameElement();
+ if (element) {
+ const nameOrId = await element.evaluate(frame => {
+ return frame.name || frame.id;
+ });
+ if (nameOrId) {
+ description += ' (' + nameOrId + ')';
+ }
}
const result = [indentation + description];
for (const child of frame.childFrames()) {
- result.push(...dumpFrames(child, ' ' + indentation));
+ result.push(...(await dumpFrames(child, ' ' + indentation)));
}
return result;
};
diff --git a/remote/test/puppeteer/tools/analyze_issue.mjs b/remote/test/puppeteer/tools/analyze_issue.mjs
index eff6a4122e..359ce93b87 100755
--- a/remote/test/puppeteer/tools/analyze_issue.mjs
+++ b/remote/test/puppeteer/tools/analyze_issue.mjs
@@ -36,9 +36,7 @@ const LAST_PUPPETEER_VERSION = packageJson.version;
if (!LAST_PUPPETEER_VERSION) {
core.setFailed('No maintained version found.');
}
-const LAST_SUPPORTED_NODE_VERSION = removeVersionPrefix(
- packageJson.engines.node.slice(2).trim()
-);
+const LAST_SUPPORTED_NODE_VERSION = packageJson.engines.node;
const SUPPORTED_OSES = ['windows', 'macos', 'linux'];
const SUPPORTED_PACKAGE_MANAGERS = ['yarn', 'npm', 'pnpm'];
@@ -65,7 +63,7 @@ This issue has an invalid package manager version: \`${value}\`. Versions must f
},
unsupportedNodeVersion(value) {
return formatMessage(`
-This issue has an unsupported Node.js version: \`${value}\`. Only versions above \`v${LAST_SUPPORTED_NODE_VERSION}\` are supported. Please verify the issue on a supported version of Node.js and update the form.
+This issue has an unsupported Node.js version: \`${value}\`. Only versions satisfying \`${LAST_SUPPORTED_NODE_VERSION}\` are supported. Please verify the issue on a supported version of Node.js and update the form.
`);
},
invalidNodeVersion(value) {
@@ -109,8 +107,8 @@ This issue has an invalid Puppeteer version: \`${value}\`. Versions must follow
let set = () => {
return void 0;
};
- let j = 1;
- let i = 1;
+ let j = 0;
+ let i = 0;
for (; i < lines.length; ++i) {
if (lines[i].startsWith('### Bug behavior')) {
set(lines.slice(j, i).join('\n').trim());
@@ -211,7 +209,7 @@ This issue has an invalid Puppeteer version: \`${value}\`. Versions must follow
);
core.setFailed('Invalid Node version');
}
- if (semver.lt(nodeVersion, LAST_SUPPORTED_NODE_VERSION)) {
+ if (!semver.satisfies(nodeVersion, LAST_SUPPORTED_NODE_VERSION)) {
core.setOutput(
'errorMessage',
ERROR_MESSAGES.unsupportedNodeVersion(nodeVersion)
diff --git a/remote/test/puppeteer/tools/docgen/package.json b/remote/test/puppeteer/tools/docgen/package.json
index 82f6d4d6c4..a89323e31b 100644
--- a/remote/test/puppeteer/tools/docgen/package.json
+++ b/remote/test/puppeteer/tools/docgen/package.json
@@ -24,10 +24,10 @@
}
},
"devDependencies": {
- "@microsoft/api-extractor": "7.42.2",
- "@microsoft/api-documenter": "7.23.35",
- "@microsoft/api-extractor-model": "7.28.13",
+ "@microsoft/api-extractor": "7.43.1",
+ "@microsoft/api-documenter": "7.24.2",
+ "@microsoft/api-extractor-model": "7.28.14",
"@microsoft/tsdoc": "0.14.2",
- "@rushstack/node-core-library": "4.0.2"
+ "@rushstack/node-core-library": "4.1.0"
}
}
diff --git a/remote/test/puppeteer/tools/docgen/src/custom_markdown_documenter.ts b/remote/test/puppeteer/tools/docgen/src/custom_markdown_documenter.ts
index d63a8b96ef..abf48e200c 100644
--- a/remote/test/puppeteer/tools/docgen/src/custom_markdown_documenter.ts
+++ b/remote/test/puppeteer/tools/docgen/src/custom_markdown_documenter.ts
@@ -69,6 +69,9 @@ import {
DocSection,
StandardTags,
StringBuilder,
+ DocHtmlStartTag,
+ DocHtmlEndTag,
+ DocHtmlAttribute,
type TSDocConfiguration,
} from '@microsoft/tsdoc';
import {
@@ -85,7 +88,7 @@ export interface IMarkdownDocumenterOptions {
export class CustomMarkdownEmitter extends ApiFormatterMarkdownEmitter {
protected override getEscapedText(text: string): string {
- const textWithBackslashes: string = text
+ const textWithBackslashes = text
.replace(/\\/g, '\\\\') // first replace the escape character
.replace(/[*#[\]_|`~]/g, x => {
return '\\' + x;
@@ -98,15 +101,6 @@ export class CustomMarkdownEmitter extends ApiFormatterMarkdownEmitter {
.replace(/\}/g, '&#125;');
return textWithBackslashes;
}
-
- protected override getTableEscapedText(text: string): string {
- return text
- .replace(/&/g, '&amp;')
- .replace(/"/g, '&quot;')
- .replace(/</g, '&lt;')
- .replace(/>/g, '&gt;')
- .replace(/\|/g, '&#124;');
- }
}
/**
@@ -156,12 +150,12 @@ export class MarkdownDocumenter {
}
private _writeApiItemPage(apiItem: ApiItem): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
- const output: DocSection = new DocSection({
- configuration: this._tsdocConfiguration,
+ const configuration = this._tsdocConfiguration;
+ const output = new DocSection({
+ configuration,
});
- const scopedName: string = apiItem.getScopedNameWithinPackage();
+ const scopedName = apiItem.getScopedNameWithinPackage();
switch (apiItem.kind) {
case ApiItemKind.Class:
@@ -259,7 +253,7 @@ export class MarkdownDocumenter {
new DocNoteBox({configuration: this._tsdocConfiguration}, [
new DocParagraph({configuration: this._tsdocConfiguration}, [
new DocPlainText({
- configuration: this._tsdocConfiguration,
+ configuration,
text: 'Warning: This API is now obsolete. ',
}),
]),
@@ -369,11 +363,11 @@ export class MarkdownDocumenter {
this._writeRemarksSection(output, apiItem);
}
- const filename: string = path.join(
+ const filename = path.join(
this._outputFolder,
this._getFilenameForApiItem(apiItem)
);
- const stringBuilder: StringBuilder = new StringBuilder();
+ const stringBuilder = new StringBuilder();
this._markdownEmitter.emit(stringBuilder, output, {
contextApiItem: apiItem,
@@ -382,7 +376,7 @@ export class MarkdownDocumenter {
},
});
- let pageContent: string = stringBuilder.toString();
+ let pageContent = stringBuilder.toString();
if (this._pluginLoader.markdownDocumenterFeature) {
// Allow the plugin to customize the pageContent
@@ -413,18 +407,15 @@ export class MarkdownDocumenter {
output: DocSection,
apiItem: ApiDeclaredItem
): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
if (apiItem instanceof ApiClass) {
if (apiItem.extendsType) {
- const extendsParagraph: DocParagraph = new DocParagraph(
- {configuration},
- [
- new DocEmphasisSpan({configuration, bold: true}, [
- new DocPlainText({configuration, text: 'Extends: '}),
- ]),
- ]
- );
+ const extendsParagraph = new DocParagraph({configuration}, [
+ new DocEmphasisSpan({configuration, bold: true}, [
+ new DocPlainText({configuration, text: 'Extends: '}),
+ ]),
+ ]);
this._appendExcerptWithHyperlinks(
extendsParagraph,
apiItem.extendsType.excerpt
@@ -432,14 +423,11 @@ export class MarkdownDocumenter {
output.appendNode(extendsParagraph);
}
if (apiItem.implementsTypes.length > 0) {
- const extendsParagraph: DocParagraph = new DocParagraph(
- {configuration},
- [
- new DocEmphasisSpan({configuration, bold: true}, [
- new DocPlainText({configuration, text: 'Implements: '}),
- ]),
- ]
- );
+ const extendsParagraph = new DocParagraph({configuration}, [
+ new DocEmphasisSpan({configuration, bold: true}, [
+ new DocPlainText({configuration, text: 'Implements: '}),
+ ]),
+ ]);
let needsComma = false;
for (const implementsType of apiItem.implementsTypes) {
if (needsComma) {
@@ -459,14 +447,11 @@ export class MarkdownDocumenter {
if (apiItem instanceof ApiInterface) {
if (apiItem.extendsTypes.length > 0) {
- const extendsParagraph: DocParagraph = new DocParagraph(
- {configuration},
- [
- new DocEmphasisSpan({configuration, bold: true}, [
- new DocPlainText({configuration, text: 'Extends: '}),
- ]),
- ]
- );
+ const extendsParagraph = new DocParagraph({configuration}, [
+ new DocEmphasisSpan({configuration, bold: true}, [
+ new DocPlainText({configuration, text: 'Extends: '}),
+ ]),
+ ]);
let needsComma = false;
for (const extendsType of apiItem.extendsTypes) {
if (needsComma) {
@@ -496,14 +481,11 @@ export class MarkdownDocumenter {
);
});
if (refs.length > 0) {
- const referencesParagraph: DocParagraph = new DocParagraph(
- {configuration},
- [
- new DocEmphasisSpan({configuration, bold: true}, [
- new DocPlainText({configuration, text: 'References: '}),
- ]),
- ]
- );
+ const referencesParagraph = new DocParagraph({configuration}, [
+ new DocEmphasisSpan({configuration, bold: true}, [
+ new DocPlainText({configuration, text: 'References: '}),
+ ]),
+ ]);
let needsComma = false;
const visited = new Set<string>();
for (const ref of refs) {
@@ -548,6 +530,8 @@ export class MarkdownDocumenter {
}
private _writeRemarksSection(output: DocSection, apiItem: ApiItem): void {
+ const configuration = this._tsdocConfiguration;
+
if (apiItem instanceof ApiDocumentedItem) {
const tsdocComment: DocComment | undefined = apiItem.tsdocComment;
@@ -556,7 +540,7 @@ export class MarkdownDocumenter {
if (tsdocComment.remarksBlock) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Remarks',
})
);
@@ -580,7 +564,7 @@ export class MarkdownDocumenter {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: heading,
})
);
@@ -627,15 +611,15 @@ export class MarkdownDocumenter {
* GENERATE PAGE: MODEL
*/
private _writeModelTable(output: DocSection, apiModel: ApiModel): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const packagesTable: DocTable = new DocTable({
+ const packagesTable = new DocTable({
configuration,
headerTitles: ['Package', 'Description'],
});
for (const apiMember of apiModel.members) {
- const row: DocTableRow = new DocTableRow({configuration}, [
+ const row = new DocTableRow({configuration}, [
this._createTitleCell(apiMember),
this._createDescriptionCell(apiMember),
]);
@@ -651,7 +635,7 @@ export class MarkdownDocumenter {
if (packagesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Packages',
})
);
@@ -666,39 +650,39 @@ export class MarkdownDocumenter {
output: DocSection,
apiContainer: ApiPackage | ApiNamespace
): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const classesTable: DocTable = new DocTable({
+ const classesTable = new DocTable({
configuration,
headerTitles: ['Class', 'Description'],
});
- const enumerationsTable: DocTable = new DocTable({
+ const enumerationsTable = new DocTable({
configuration,
headerTitles: ['Enumeration', 'Description'],
});
- const functionsTable: DocTable = new DocTable({
+ const functionsTable = new DocTable({
configuration,
headerTitles: ['Function', 'Description'],
});
- const interfacesTable: DocTable = new DocTable({
+ const interfacesTable = new DocTable({
configuration,
headerTitles: ['Interface', 'Description'],
});
- const namespacesTable: DocTable = new DocTable({
+ const namespacesTable = new DocTable({
configuration,
headerTitles: ['Namespace', 'Description'],
});
- const variablesTable: DocTable = new DocTable({
+ const variablesTable = new DocTable({
configuration,
headerTitles: ['Variable', 'Description'],
});
- const typeAliasesTable: DocTable = new DocTable({
+ const typeAliasesTable = new DocTable({
configuration,
headerTitles: ['Type Alias', 'Description'],
});
@@ -709,7 +693,7 @@ export class MarkdownDocumenter {
: (apiContainer as ApiNamespace).members;
for (const apiMember of apiMembers) {
- const row: DocTableRow = new DocTableRow({configuration}, [
+ const row = new DocTableRow({configuration}, [
this._createTitleCell(apiMember),
this._createDescriptionCell(apiMember),
]);
@@ -755,7 +739,7 @@ export class MarkdownDocumenter {
if (classesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Classes',
})
);
@@ -765,7 +749,7 @@ export class MarkdownDocumenter {
if (enumerationsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Enumerations',
})
);
@@ -774,7 +758,7 @@ export class MarkdownDocumenter {
if (functionsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Functions',
})
);
@@ -784,7 +768,7 @@ export class MarkdownDocumenter {
if (interfacesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Interfaces',
})
);
@@ -794,7 +778,7 @@ export class MarkdownDocumenter {
if (namespacesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Namespaces',
})
);
@@ -804,7 +788,7 @@ export class MarkdownDocumenter {
if (variablesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Variables',
})
);
@@ -814,7 +798,7 @@ export class MarkdownDocumenter {
if (typeAliasesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Type Aliases',
})
);
@@ -826,24 +810,24 @@ export class MarkdownDocumenter {
* GENERATE PAGE: CLASS
*/
private _writeClassTables(output: DocSection, apiClass: ApiClass): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const eventsTable: DocTable = new DocTable({
+ const eventsTable = new DocTable({
configuration,
headerTitles: ['Property', 'Modifiers', 'Type', 'Description'],
});
- const constructorsTable: DocTable = new DocTable({
+ const constructorsTable = new DocTable({
configuration,
headerTitles: ['Constructor', 'Modifiers', 'Description'],
});
- const propertiesTable: DocTable = new DocTable({
+ const propertiesTable = new DocTable({
configuration,
headerTitles: ['Property', 'Modifiers', 'Type', 'Description'],
});
- const methodsTable: DocTable = new DocTable({
+ const methodsTable = new DocTable({
configuration,
headerTitles: ['Method', 'Modifiers', 'Description'],
});
@@ -902,7 +886,7 @@ export class MarkdownDocumenter {
if (eventsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Events',
})
);
@@ -912,7 +896,7 @@ export class MarkdownDocumenter {
if (constructorsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Constructors',
})
);
@@ -922,7 +906,7 @@ export class MarkdownDocumenter {
if (propertiesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Properties',
})
);
@@ -932,7 +916,7 @@ export class MarkdownDocumenter {
if (methodsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Methods',
})
);
@@ -944,9 +928,9 @@ export class MarkdownDocumenter {
* GENERATE PAGE: ENUM
*/
private _writeEnumTables(output: DocSection, apiEnum: ApiEnum): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const enumMembersTable: DocTable = new DocTable({
+ const enumMembersTable = new DocTable({
configuration,
headerTitles: ['Member', 'Value', 'Description'],
});
@@ -971,7 +955,7 @@ export class MarkdownDocumenter {
if (enumMembersTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Enumeration Members',
})
);
@@ -986,19 +970,19 @@ export class MarkdownDocumenter {
output: DocSection,
apiClass: ApiInterface
): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const eventsTable: DocTable = new DocTable({
+ const eventsTable = new DocTable({
configuration,
headerTitles: ['Property', 'Modifiers', 'Type', 'Description'],
});
- const propertiesTable: DocTable = new DocTable({
+ const propertiesTable = new DocTable({
configuration,
headerTitles: ['Property', 'Modifiers', 'Type', 'Description', 'Default'],
});
- const methodsTable: DocTable = new DocTable({
+ const methodsTable = new DocTable({
configuration,
headerTitles: ['Method', 'Description'],
});
@@ -1046,7 +1030,7 @@ export class MarkdownDocumenter {
if (eventsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Events',
})
);
@@ -1056,7 +1040,7 @@ export class MarkdownDocumenter {
if (propertiesTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Properties',
})
);
@@ -1066,7 +1050,7 @@ export class MarkdownDocumenter {
if (methodsTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Methods',
})
);
@@ -1081,14 +1065,14 @@ export class MarkdownDocumenter {
output: DocSection,
apiParameterListMixin: ApiParameterListMixin
): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const parametersTable: DocTable = new DocTable({
+ const parametersTable = new DocTable({
configuration,
headerTitles: ['Parameter', 'Type', 'Description'],
});
for (const apiParameter of apiParameterListMixin.parameters) {
- const parameterDescription: DocSection = new DocSection({configuration});
+ const parameterDescription = new DocSection({configuration});
if (apiParameter.isOptional) {
parameterDescription.appendNodesInParagraph([
@@ -1126,7 +1110,7 @@ export class MarkdownDocumenter {
if (parametersTable.rows.length > 0) {
output.appendNode(
new DocHeading({
- configuration: this._tsdocConfiguration,
+ configuration,
title: 'Parameters',
})
);
@@ -1161,9 +1145,9 @@ export class MarkdownDocumenter {
}
private _createParagraphForTypeExcerpt(excerpt: Excerpt): DocParagraph {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const paragraph: DocParagraph = new DocParagraph({configuration});
+ const paragraph = new DocParagraph({configuration});
if (!excerpt.text.trim()) {
paragraph.appendNode(
new DocPlainText({configuration, text: '(not declared)'})
@@ -1188,13 +1172,13 @@ export class MarkdownDocumenter {
docNodeContainer: DocNodeContainer,
token: ExcerptToken
): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
// Markdown doesn't provide a standardized syntax for hyperlinks inside code
// spans, so we will render the type expression as DocPlainText. Instead of
// creating multiple DocParagraphs, we can simply discard any newlines and
// let the renderer do normal word-wrapping.
- const unwrappedTokenText: string = token.text.replace(/[\r\n]+/g, ' ');
+ const unwrappedTokenText = token.text.replace(/[\r\n]+/g, ' ');
// If it's hyperlinkable, then append a DocLinkTag
if (token.kind === ExcerptTokenKind.Reference && token.canonicalReference) {
@@ -1226,12 +1210,23 @@ export class MarkdownDocumenter {
}
private _createTitleCell(apiItem: ApiItem, plain = false): DocTableCell {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const text: string = Utilities.getConciseSignature(apiItem);
+ const text = Utilities.getConciseSignature(apiItem);
return new DocTableCell({configuration}, [
new DocParagraph({configuration}, [
+ new DocHtmlStartTag({
+ configuration,
+ name: 'span',
+ htmlAttributes: [
+ new DocHtmlAttribute({
+ configuration,
+ name: 'id',
+ value: `"${Utilities.getSafeFilenameForName(apiItem.displayName)}"`,
+ }),
+ ],
+ }),
plain
? new DocPlainText({configuration, text})
: new DocLinkTag({
@@ -1240,6 +1235,10 @@ export class MarkdownDocumenter {
linkText: text,
urlDestination: this._getLinkFilenameForApiItem(apiItem),
}),
+ new DocHtmlEndTag({
+ configuration,
+ name: 'span',
+ }),
]),
]);
}
@@ -1254,9 +1253,9 @@ export class MarkdownDocumenter {
* cast.
*/
private _createDescriptionCell(apiItem: ApiItem): DocTableCell {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const section: DocSection = new DocSection({configuration});
+ const section = new DocSection({configuration});
if (ApiReleaseTagMixin.isBaseClassOf(apiItem)) {
if (apiItem.releaseTag === ReleaseTag.Beta) {
@@ -1275,6 +1274,20 @@ export class MarkdownDocumenter {
section,
apiItem.tsdocComment.summarySection
);
+
+ if (apiItem.tsdocComment.deprecatedBlock) {
+ section.appendNode(
+ new DocParagraph({configuration}, [
+ new DocEmphasisSpan({configuration, bold: true}, [
+ new DocPlainText({configuration, text: 'Deprecated: '}),
+ ]),
+ ])
+ );
+
+ section.appendNodes(
+ apiItem.tsdocComment.deprecatedBlock.content.getChildNodes()
+ );
+ }
}
}
@@ -1282,7 +1295,7 @@ export class MarkdownDocumenter {
}
private _createDefaultCell(apiItem: ApiItem): DocTableCell {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
if (apiItem instanceof ApiDocumentedItem) {
const block = apiItem.tsdocComment?.customBlocks.find(block => {
@@ -1300,57 +1313,56 @@ export class MarkdownDocumenter {
}
private _createModifiersCell(apiItem: ApiItem): DocTableCell {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
+
+ const section = new DocSection({configuration});
- const section: DocSection = new DocSection({configuration});
+ const codes = [];
if (ApiProtectedMixin.isBaseClassOf(apiItem)) {
if (apiItem.isProtected) {
- section.appendNode(
- new DocParagraph({configuration}, [
- new DocCodeSpan({configuration, code: 'protected'}),
- ])
- );
+ codes.push('protected');
}
}
if (ApiReadonlyMixin.isBaseClassOf(apiItem)) {
if (apiItem.isReadonly) {
- section.appendNode(
- new DocParagraph({configuration}, [
- new DocCodeSpan({configuration, code: 'readonly'}),
- ])
- );
+ codes.push('readonly');
}
}
if (ApiStaticMixin.isBaseClassOf(apiItem)) {
if (apiItem.isStatic) {
- section.appendNode(
- new DocParagraph({configuration}, [
- new DocCodeSpan({configuration, code: 'static'}),
- ])
- );
+ codes.push('static');
}
}
if (ApiOptionalMixin.isBaseClassOf(apiItem)) {
if (apiItem.isOptional) {
- section.appendNode(
- new DocParagraph({configuration}, [
- new DocCodeSpan({configuration, code: 'optional'}),
- ])
- );
+ codes.push('optional');
}
}
+ if (apiItem instanceof ApiDocumentedItem) {
+ if (apiItem.tsdocComment?.deprecatedBlock) {
+ codes.push('deprecated');
+ }
+ }
+ if (codes.length) {
+ section.appendNode(
+ new DocParagraph({configuration}, [
+ new DocCodeSpan({configuration, code: codes.join(', ')}),
+ ])
+ );
+ }
+
return new DocTableCell({configuration}, section.nodes);
}
private _createPropertyTypeCell(apiItem: ApiItem): DocTableCell {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const section: DocSection = new DocSection({configuration});
+ const section = new DocSection({configuration});
if (apiItem instanceof ApiPropertyItem) {
section.appendNode(
@@ -1362,9 +1374,9 @@ export class MarkdownDocumenter {
}
private _createInitializerCell(apiItem: ApiItem): DocTableCell {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
+ const configuration = this._tsdocConfiguration;
- const section: DocSection = new DocSection({configuration});
+ const section = new DocSection({configuration});
if (ApiInitializerMixin.isBaseClassOf(apiItem)) {
if (apiItem.initializerExcerpt) {
@@ -1381,8 +1393,8 @@ export class MarkdownDocumenter {
}
private _writeBetaWarning(output: DocSection): void {
- const configuration: TSDocConfiguration = this._tsdocConfiguration;
- const betaWarning: string =
+ const configuration = this._tsdocConfiguration;
+ const betaWarning =
'This API is provided as a preview for developers and may change' +
' based on feedback that we receive. Do not use this API in a production environment.';
output.appendNode(
@@ -1427,7 +1439,7 @@ export class MarkdownDocumenter {
let baseName = '';
for (const hierarchyItem of apiItem.getHierarchy()) {
// For overloaded methods, add a suffix such as "MyClass.myMethod_2".
- let qualifiedName: string = hierarchyItem.displayName;
+ let qualifiedName = hierarchyItem.displayName;
if (ApiParameterListMixin.isBaseClassOf(hierarchyItem)) {
if (hierarchyItem.overloadIndex > 1) {
// Subtract one for compatibility with earlier releases of API Documenter.
@@ -1448,15 +1460,16 @@ export class MarkdownDocumenter {
return baseName.slice(0, baseName.length - 1);
}
- private _getFilenameForApiItem(apiItem: ApiItem): string {
+ private _getFilenameForApiItem(apiItem: ApiItem, link = false): string {
if (apiItem.kind === ApiItemKind.Package) {
return 'index.md';
}
let baseName = '';
+ let suffix = '';
for (const hierarchyItem of apiItem.getHierarchy()) {
// For overloaded methods, add a suffix such as "MyClass.myMethod_2".
- let qualifiedName: string = Utilities.getSafeFilenameForName(
+ let qualifiedName = Utilities.getSafeFilenameForName(
hierarchyItem.displayName
);
if (ApiParameterListMixin.isBaseClassOf(hierarchyItem)) {
@@ -1471,6 +1484,9 @@ export class MarkdownDocumenter {
case ApiItemKind.Model:
case ApiItemKind.EntryPoint:
case ApiItemKind.EnumMember:
+ // Properties don't have separate pages
+ case ApiItemKind.Property:
+ case ApiItemKind.PropertySignature:
break;
case ApiItemKind.Package:
baseName = Utilities.getSafeFilenameForName(
@@ -1480,12 +1496,26 @@ export class MarkdownDocumenter {
default:
baseName += '.' + qualifiedName;
}
+
+ if (link) {
+ switch (hierarchyItem.kind) {
+ case ApiItemKind.Property:
+ case ApiItemKind.PropertySignature:
+ suffix =
+ '#' +
+ Utilities.getSafeFilenameForName(
+ PackageName.getUnscopedName(hierarchyItem.displayName)
+ );
+ break;
+ }
+ }
}
- return baseName + '.md';
+
+ return `${baseName}.md${suffix}`;
}
private _getLinkFilenameForApiItem(apiItem: ApiItem): string {
- return './' + this._getFilenameForApiItem(apiItem);
+ return './' + this._getFilenameForApiItem(apiItem, true);
}
private _deleteOldOutputFiles(): void {
diff --git a/remote/test/puppeteer/tools/doctest/package.json b/remote/test/puppeteer/tools/doctest/package.json
index 1d0adb633b..ee3be2a6ea 100644
--- a/remote/test/puppeteer/tools/doctest/package.json
+++ b/remote/test/puppeteer/tools/doctest/package.json
@@ -24,13 +24,13 @@
}
},
"devDependencies": {
- "@swc/core": "1.4.2",
+ "@swc/core": "1.4.13",
"@types/doctrine": "0.0.9",
"@types/source-map-support": "0.5.10",
"@types/yargs": "17.0.32",
"acorn": "8.11.3",
"doctrine": "3.0.0",
- "glob": "10.3.10",
+ "glob": "10.3.12",
"pkg-dir": "8.0.0",
"source-map-support": "0.5.21",
"source-map": "0.7.4",
diff --git a/remote/test/puppeteer/tools/eslint/package.json b/remote/test/puppeteer/tools/eslint/package.json
index c7f7f4f38d..97976a37f2 100644
--- a/remote/test/puppeteer/tools/eslint/package.json
+++ b/remote/test/puppeteer/tools/eslint/package.json
@@ -33,6 +33,6 @@
"license": "Apache-2.0",
"devDependencies": {
"@prettier/sync": "0.5.1",
- "@typescript-eslint/utils": "7.1.0"
+ "@typescript-eslint/utils": "7.6.0"
}
}
diff --git a/remote/test/puppeteer/tools/mocha-runner/package.json b/remote/test/puppeteer/tools/mocha-runner/package.json
index a817020d5e..94a31ae2e1 100644
--- a/remote/test/puppeteer/tools/mocha-runner/package.json
+++ b/remote/test/puppeteer/tools/mocha-runner/package.json
@@ -36,7 +36,7 @@
"devDependencies": {
"@types/yargs": "17.0.32",
"c8": "9.1.0",
- "glob": "10.3.10",
+ "glob": "10.3.12",
"yargs": "17.7.2",
"zod": "3.22.4"
}
diff --git a/remote/test/puppeteer/tools/sort-test-expectations.mjs b/remote/test/puppeteer/tools/sort-test-expectations.mjs
index 972d244874..a80f0cfbd2 100644
--- a/remote/test/puppeteer/tools/sort-test-expectations.mjs
+++ b/remote/test/puppeteer/tools/sort-test-expectations.mjs
@@ -78,14 +78,14 @@ const toBeRemoved = new Set();
for (let i = testExpectations.length - 1; i >= 0; i--) {
const expectation = testExpectations[i];
const params = new Set(expectation.parameters);
- const labels = new Set(expectation.expectations);
+ const expectations = new Set(expectation.expectations);
const platforms = new Set(expectation.platforms);
let foundMatch = false;
for (let j = i - 1; j >= 0; j--) {
const candidate = testExpectations[j];
const candidateParams = new Set(candidate.parameters);
- const candidateLabels = new Set(candidate.expectations);
+ const candidateExpectations = new Set(candidate.expectations);
const candidatePlatforms = new Set(candidate.platforms);
if (
@@ -93,11 +93,11 @@ for (let i = testExpectations.length - 1; i >= 0; i--) {
expectation.testIdPattern,
candidate.testIdPattern
) &&
- isSubset(candidateParams, params) &&
- isSubset(candidatePlatforms, platforms)
+ isSubset(candidatePlatforms, platforms) &&
+ (isSubset(params, candidateParams) || isSubset(candidateParams, params))
) {
foundMatch = true;
- if (isSubset(candidateLabels, labels)) {
+ if (isSubset(candidateExpectations, expectations)) {
console.log('removing', expectation, 'already covered by', candidate);
toBeRemoved.add(expectation);
}
@@ -105,7 +105,7 @@ for (let i = testExpectations.length - 1; i >= 0; i--) {
}
}
- if (!foundMatch && isSubset(new Set(['PASS']), labels)) {
+ if (!foundMatch && isSubset(new Set(['PASS']), expectations)) {
console.log(
'removing',
expectation,
diff --git a/remote/test/puppeteer/tools/update_chrome_revision.mjs b/remote/test/puppeteer/tools/update_chrome_revision.mjs
index 64eeef74d5..0083bc0bbb 100644
--- a/remote/test/puppeteer/tools/update_chrome_revision.mjs
+++ b/remote/test/puppeteer/tools/update_chrome_revision.mjs
@@ -99,6 +99,12 @@ async function updateDevToolsProtocolVersion(revision) {
`"devtools-protocol": "${currentProtocol}"`,
`"devtools-protocol": "${bestNewProtocol}"`
);
+
+ await replaceInFile(
+ './packages/puppeteer/package.json',
+ `"devtools-protocol": "${currentProtocol}"`,
+ `"devtools-protocol": "${bestNewProtocol}"`
+ );
}
async function updateVersionFileLastMaintained(oldVersion, newVersion) {
diff --git a/remote/test/puppeteer/versions.js b/remote/test/puppeteer/versions.js
index 05d8429789..ca01e45511 100644
--- a/remote/test/puppeteer/versions.js
+++ b/remote/test/puppeteer/versions.js
@@ -7,6 +7,12 @@
const versionsPerRelease = new Map([
// This is a mapping from Chrome version => Puppeteer version.
// In Chrome roll patches, use `NEXT` for the Puppeteer version.
+ ['123.0.6312.122', 'v22.6.4'],
+ ['123.0.6312.105', 'v22.6.3'],
+ ['123.0.6312.86', 'v22.6.2'],
+ ['123.0.6312.58', 'v22.6.0'],
+ ['122.0.6261.128', 'v22.5.0'],
+ ['122.0.6261.111', 'v22.4.1'],
['122.0.6261.94', 'v22.4.0'],
['122.0.6261.69', 'v22.3.0'],
['122.0.6261.57', 'v22.2.0'],
@@ -65,7 +71,7 @@ const versionsPerRelease = new Map([
]);
// Should not be more than 2 major versions behind Chrome Stable (https://chromestatus.com/roadmap).
-const lastMaintainedChromeVersion = '119.0.6045.105';
+const lastMaintainedChromeVersion = '120.0.6099.109';
if (!versionsPerRelease.has(lastMaintainedChromeVersion)) {
throw new Error(