summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer/test/installation
diff options
context:
space:
mode:
Diffstat (limited to 'remote/test/puppeteer/test/installation')
-rw-r--r--remote/test/puppeteer/test/installation/.mocharc.cjs13
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer-core/imports.js9
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js22
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer-core/requires.cjs9
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/basic.js15
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/basic.ts15
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/bidi.js17
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/configuration/.puppeteerrc.cjs8
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/configuration/puppeteer.config.ts6
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/imports.js10
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/installCanary.js24
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/requires.cjs10
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/trimCache.js11
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/tsconfig.json7
-rw-r--r--remote/test/puppeteer/test/installation/assets/puppeteer/webpack/webpack.config.js16
-rw-r--r--remote/test/puppeteer/test/installation/package.json50
-rw-r--r--remote/test/puppeteer/test/installation/src/browsers.spec.ts30
-rw-r--r--remote/test/puppeteer/test/installation/src/constants.ts25
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-cli.spec.ts58
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-configuration.spec.ts73
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-core.spec.ts34
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts51
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-typescript.spec.ts49
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer-webpack.spec.ts47
-rw-r--r--remote/test/puppeteer/test/installation/src/puppeteer.spec.ts104
-rw-r--r--remote/test/puppeteer/test/installation/src/sandbox.ts131
-rw-r--r--remote/test/puppeteer/test/installation/src/util.ts17
-rw-r--r--remote/test/puppeteer/test/installation/tsconfig.json10
-rw-r--r--remote/test/puppeteer/test/installation/tsdoc.json15
29 files changed, 886 insertions, 0 deletions
diff --git a/remote/test/puppeteer/test/installation/.mocharc.cjs b/remote/test/puppeteer/test/installation/.mocharc.cjs
new file mode 100644
index 0000000000..5a797716e0
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/.mocharc.cjs
@@ -0,0 +1,13 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+/**
+ * @type {import('mocha').MochaOptions}
+ */
+module.exports = {
+ spec: ['build/**/*.spec.js'],
+ timeout: '240000ms',
+};
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer-core/imports.js b/remote/test/puppeteer/test/installation/assets/puppeteer-core/imports.js
new file mode 100644
index 0000000000..8f8fb329e7
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer-core/imports.js
@@ -0,0 +1,9 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import 'puppeteer-core';
+import 'puppeteer-core/internal/revisions.js';
+import 'puppeteer-core/lib/esm/puppeteer/revisions.js';
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js b/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js
new file mode 100644
index 0000000000..4776d7e261
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer-core/launch.js
@@ -0,0 +1,22 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import puppeteer from 'puppeteer-core';
+
+(async () => {
+ try {
+ await puppeteer.launch({
+ product: '${product}',
+ executablePath: 'node',
+ });
+ } catch (error) {
+ if (error.message.includes('Failed to launch the browser process')) {
+ process.exit(0);
+ }
+ console.error(error);
+ process.exit(1);
+ }
+})();
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer-core/requires.cjs b/remote/test/puppeteer/test/installation/assets/puppeteer-core/requires.cjs
new file mode 100644
index 0000000000..f4276f2589
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer-core/requires.cjs
@@ -0,0 +1,9 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+require('puppeteer-core');
+require('puppeteer-core/internal/revisions.js');
+require('puppeteer-core/lib/cjs/puppeteer/revisions.js');
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/basic.js b/remote/test/puppeteer/test/installation/assets/puppeteer/basic.js
new file mode 100644
index 0000000000..9e6ce241b2
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/basic.js
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import puppeteer from 'puppeteer';
+(async () => {
+ const browser = await puppeteer.launch();
+ const page = await browser.newPage();
+ await page.goto('http://example.com');
+ await page.$('aria/example');
+ await page.screenshot({path: 'example.png'});
+ await browser.close();
+})();
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/basic.ts b/remote/test/puppeteer/test/installation/assets/puppeteer/basic.ts
new file mode 100644
index 0000000000..28396d0096
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/basic.ts
@@ -0,0 +1,15 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import puppeteer from 'puppeteer';
+(async () => {
+ const browser = await puppeteer.launch();
+ const page = await browser.newPage();
+ await page.goto('http://example.com');
+ await page.$('aria/example');
+ await page.screenshot({path: 'example.png'});
+ await browser.close();
+})();
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/bidi.js b/remote/test/puppeteer/test/installation/assets/puppeteer/bidi.js
new file mode 100644
index 0000000000..3e1df93654
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/bidi.js
@@ -0,0 +1,17 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import puppeteer from 'puppeteer';
+(async () => {
+ const browser = await puppeteer.launch({
+ protocol: 'webDriverBiDi',
+ });
+ const page = await browser.newPage();
+ await page.goto('http://example.com');
+ await page.$('h1');
+ await page.screenshot({path: 'example.png'});
+ await browser.close();
+})();
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/configuration/.puppeteerrc.cjs b/remote/test/puppeteer/test/installation/assets/puppeteer/configuration/.puppeteerrc.cjs
new file mode 100644
index 0000000000..64a7b96681
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/configuration/.puppeteerrc.cjs
@@ -0,0 +1,8 @@
+const {join} = require('path');
+
+/**
+ * @type {import("puppeteer").Configuration}
+ */
+module.exports = {
+ cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
+};
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/configuration/puppeteer.config.ts b/remote/test/puppeteer/test/installation/assets/puppeteer/configuration/puppeteer.config.ts
new file mode 100644
index 0000000000..5bcb82ffc8
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/configuration/puppeteer.config.ts
@@ -0,0 +1,6 @@
+import {type Configuration} from 'puppeteer';
+import {join} from 'path';
+
+export default {
+ cacheDirectory: join(__dirname, '.cache', 'puppeteer'),
+} satisfies Configuration;
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/imports.js b/remote/test/puppeteer/test/installation/assets/puppeteer/imports.js
new file mode 100644
index 0000000000..cd742bafd5
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/imports.js
@@ -0,0 +1,10 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import 'puppeteer';
+
+// Should still be reachable.
+import 'puppeteer-core/internal/revisions.js';
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/installCanary.js b/remote/test/puppeteer/test/installation/assets/puppeteer/installCanary.js
new file mode 100644
index 0000000000..39a0113de9
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/installCanary.js
@@ -0,0 +1,24 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {
+ Browser,
+ detectBrowserPlatform,
+ install,
+ resolveBuildId,
+} from '@puppeteer/browsers';
+
+(async () => {
+ await install({
+ cacheDir: process.env['PUPPETEER_CACHE_DIR'],
+ browser: Browser.CHROME,
+ buildId: await resolveBuildId(
+ Browser.CHROME,
+ detectBrowserPlatform(),
+ 'canary'
+ ),
+ });
+})();
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/requires.cjs b/remote/test/puppeteer/test/installation/assets/puppeteer/requires.cjs
new file mode 100644
index 0000000000..208eee9021
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/requires.cjs
@@ -0,0 +1,10 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+require('puppeteer');
+
+// Should still be reachable.
+require('puppeteer-core/internal/revisions.js');
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/trimCache.js b/remote/test/puppeteer/test/installation/assets/puppeteer/trimCache.js
new file mode 100644
index 0000000000..a810e2aac2
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/trimCache.js
@@ -0,0 +1,11 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import puppeteer from 'puppeteer';
+
+(async () => {
+ await puppeteer.trimCache();
+})();
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/tsconfig.json b/remote/test/puppeteer/test/installation/assets/puppeteer/tsconfig.json
new file mode 100644
index 0000000000..ce77dbf8d9
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/tsconfig.json
@@ -0,0 +1,7 @@
+{
+ "compilerOptions": {
+ "target": "ES2022",
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ },
+}
diff --git a/remote/test/puppeteer/test/installation/assets/puppeteer/webpack/webpack.config.js b/remote/test/puppeteer/test/installation/assets/puppeteer/webpack/webpack.config.js
new file mode 100644
index 0000000000..30de2a4890
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/assets/puppeteer/webpack/webpack.config.js
@@ -0,0 +1,16 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+export default {
+ mode: 'production',
+ entry: './index.js',
+ target: 'node',
+ externals: 'typescript',
+ output: {
+ path: process.cwd(),
+ filename: 'bundle.js',
+ },
+};
diff --git a/remote/test/puppeteer/test/installation/package.json b/remote/test/puppeteer/test/installation/package.json
new file mode 100644
index 0000000000..f5e804d99c
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/package.json
@@ -0,0 +1,50 @@
+{
+ "name": "@puppeteer-test/installation",
+ "version": "latest",
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "build": "wireit",
+ "clean": "../../tools/clean.js",
+ "test": "mocha"
+ },
+ "wireit": {
+ "build": {
+ "command": "tsc -b",
+ "clean": "if-file-deleted",
+ "dependencies": [
+ "build:packages"
+ ],
+ "files": [
+ "tsconfig.json",
+ "src/**"
+ ],
+ "output": [
+ "build/**",
+ "tsconfig.tsbuildinfo"
+ ]
+ },
+ "build:packages": {
+ "command": "npm pack --quiet --workspace puppeteer --workspace puppeteer-core --workspace @puppeteer/browsers",
+ "dependencies": [
+ "../../packages/puppeteer:build",
+ "../../packages/puppeteer-core:build",
+ "../../packages/browsers:build"
+ ],
+ "files": [],
+ "output": [
+ "puppeteer-*.tgz"
+ ]
+ }
+ },
+ "files": [
+ ".mocharc.cjs",
+ "puppeteer-*.tgz",
+ "build",
+ "assets"
+ ],
+ "dependencies": {
+ "glob": "10.3.10",
+ "mocha": "10.2.0"
+ }
+}
diff --git a/remote/test/puppeteer/test/installation/src/browsers.spec.ts b/remote/test/puppeteer/test/installation/src/browsers.spec.ts
new file mode 100644
index 0000000000..0c91731455
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/browsers.spec.ts
@@ -0,0 +1,30 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import {spawnSync} from 'child_process';
+
+import {configureSandbox} from './sandbox.js';
+
+describe('`@puppeteer/browsers`', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers'],
+ });
+
+ it('can launch CLI', async function () {
+ const result = spawnSync('npx', ['@puppeteer/browsers', '--help'], {
+ // npx is not found without the shell flag on Windows.
+ shell: process.platform === 'win32',
+ cwd: this.sandbox,
+ });
+ assert.strictEqual(result.status, 0);
+ assert.ok(
+ result.stdout
+ .toString('utf-8')
+ .startsWith('@puppeteer/browsers <command>')
+ );
+ });
+});
diff --git a/remote/test/puppeteer/test/installation/src/constants.ts b/remote/test/puppeteer/test/installation/src/constants.ts
new file mode 100644
index 0000000000..2b66b792d5
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/constants.ts
@@ -0,0 +1,25 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {dirname, join, resolve} from 'path';
+import {fileURLToPath} from 'url';
+
+import {globSync} from 'glob';
+
+export const PUPPETEER_CORE_PACKAGE_PATH = resolve(
+ globSync('puppeteer-core-*.tgz')[0]!
+);
+export const PUPPETEER_BROWSERS_PACKAGE_PATH = resolve(
+ globSync('puppeteer-browsers-[0-9]*.tgz')[0]!
+);
+export const PUPPETEER_PACKAGE_PATH = resolve(
+ globSync('puppeteer-[0-9]*.tgz')[0]!
+);
+export const ASSETS_DIR = join(
+ dirname(fileURLToPath(import.meta.url)),
+ '..',
+ 'assets'
+);
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-cli.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-cli.spec.ts
new file mode 100644
index 0000000000..650cbc1832
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-cli.spec.ts
@@ -0,0 +1,58 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import {spawnSync} from 'child_process';
+import {existsSync} from 'fs';
+import {readdir} from 'fs/promises';
+import {join} from 'path';
+
+import {configureSandbox} from './sandbox.js';
+
+describe('Puppeteer CLI', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ PUPPETEER_SKIP_DOWNLOAD: 'true',
+ };
+ },
+ });
+
+ it('can launch', async function () {
+ const result = spawnSync('npx', ['puppeteer', '--help'], {
+ // npx is not found without the shell flag on Windows.
+ shell: process.platform === 'win32',
+ cwd: this.sandbox,
+ });
+ assert.strictEqual(result.status, 0);
+ assert.ok(
+ result.stdout.toString('utf-8').startsWith('puppeteer <command>')
+ );
+ });
+
+ it('can download a browser', async function () {
+ assert.ok(!existsSync(join(this.sandbox, '.cache', 'puppeteer')));
+ const result = spawnSync(
+ 'npx',
+ ['puppeteer', 'browsers', 'install', 'chrome'],
+ {
+ // 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], 'chrome');
+ });
+});
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-configuration.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-configuration.spec.ts
new file mode 100644
index 0000000000..1ed5511f6c
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-configuration.spec.ts
@@ -0,0 +1,73 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import {readdir, writeFile} from 'fs/promises';
+import {join} from 'path';
+
+import {configureSandbox} from './sandbox.js';
+import {readAsset} from './util.js';
+
+describe('`puppeteer` with configuration', () => {
+ describe('cjs', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ before: async cwd => {
+ await writeFile(
+ join(cwd, '.puppeteerrc.cjs'),
+ await readAsset('puppeteer', 'configuration', '.puppeteerrc.cjs')
+ );
+ },
+ });
+
+ it('evaluates', async function () {
+ const files = await readdir(join(this.sandbox, '.cache', 'puppeteer'));
+ assert.equal(files.length, 2);
+ assert(files.includes('chrome'));
+ assert(files.includes('chrome-headless-shell'));
+
+ const script = await readAsset('puppeteer', 'basic.js');
+ await this.runScript(script, 'mjs');
+ });
+ });
+
+ describe('ts', () => {
+ configureSandbox({
+ dependencies: [
+ '@puppeteer/browsers',
+ 'puppeteer-core',
+ 'puppeteer',
+ 'typescript',
+ ],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ before: async cwd => {
+ await writeFile(
+ join(cwd, 'puppeteer.config.ts'),
+ await readAsset('puppeteer', 'configuration', 'puppeteer.config.ts')
+ );
+ },
+ });
+
+ it('evaluates', async function () {
+ const files = await readdir(join(this.sandbox, '.cache', 'puppeteer'));
+ assert.equal(files.length, 2);
+ assert(files.includes('chrome'));
+ assert(files.includes('chrome-headless-shell'));
+
+ const script = await readAsset('puppeteer', 'basic.js');
+ await this.runScript(script, 'mjs');
+ });
+ });
+});
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-core.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-core.spec.ts
new file mode 100644
index 0000000000..9df19e1c85
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-core.spec.ts
@@ -0,0 +1,34 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {configureSandbox} from './sandbox.js';
+import {readAsset} from './util.js';
+
+describe('`puppeteer-core`', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core'],
+ });
+
+ it('evaluates CommonJS', async function () {
+ const script = await readAsset('puppeteer-core', 'requires.cjs');
+ await this.runScript(script, 'cjs');
+ });
+
+ it('evaluates ES modules', async function () {
+ const script = await readAsset('puppeteer-core', 'imports.js');
+ await this.runScript(script, 'mjs');
+ });
+
+ for (const product of ['firefox', 'chrome']) {
+ it(`\`launch\` for \`${product}\` with a bad \`executablePath\``, async function () {
+ const script = (await readAsset('puppeteer-core', 'launch.js')).replace(
+ '${product}',
+ product
+ );
+ await this.runScript(script, 'mjs');
+ });
+ }
+});
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts
new file mode 100644
index 0000000000..b599af01dc
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts
@@ -0,0 +1,51 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import {readdir} from 'fs/promises';
+import {platform} from 'os';
+import {join} from 'path';
+
+import {configureSandbox} from './sandbox.js';
+import {readAsset} from './util.js';
+
+// Skipping this test on Windows as windows runners are much slower.
+(platform() === 'win32' ? describe.skip : describe)(
+ '`puppeteer` with Firefox',
+ () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ PUPPETEER_PRODUCT: 'firefox',
+ };
+ },
+ });
+
+ describe('with CDP', () => {
+ it('evaluates CommonJS', async function () {
+ const files = await readdir(join(this.sandbox, '.cache', 'puppeteer'));
+ assert.equal(files.length, 1);
+ assert.equal(files[0], 'firefox');
+ const script = await readAsset('puppeteer-core', 'requires.cjs');
+ await this.runScript(script, 'cjs');
+ });
+
+ it('evaluates ES modules', async function () {
+ const script = await readAsset('puppeteer-core', 'imports.js');
+ await this.runScript(script, 'mjs');
+ });
+ });
+
+ describe('with WebDriverBiDi', () => {
+ it('evaluates ES modules', async function () {
+ const script = await readAsset('puppeteer', 'bidi.js');
+ await this.runScript(script, 'mjs');
+ });
+ });
+ }
+);
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-typescript.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-typescript.spec.ts
new file mode 100644
index 0000000000..fc8ff133fb
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-typescript.spec.ts
@@ -0,0 +1,49 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {readFile, writeFile} from 'fs/promises';
+import {platform} from 'os';
+import {join} from 'path';
+
+import {configureSandbox} from './sandbox.js';
+import {execFile, readAsset} from './util.js';
+
+// Skipping this test on Windows as windows runners are much slower.
+(platform() === 'win32' ? describe.skip : describe)(
+ '`puppeteer` with TypeScript',
+ () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ devDependencies: ['typescript@4.7.4', '@types/node@16.3.3'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ });
+
+ it('should work', async function () {
+ // Write a Webpack configuration.
+ await writeFile(
+ join(this.sandbox, 'tsconfig.json'),
+ await readAsset('puppeteer', 'tsconfig.json')
+ );
+
+ // Write the source code.
+ await writeFile(
+ join(this.sandbox, 'index.ts'),
+ await readAsset('puppeteer', 'basic.ts')
+ );
+
+ // Compile.
+ await execFile('npx', ['tsc'], {cwd: this.sandbox, shell: true});
+
+ const script = await readFile(join(this.sandbox, 'index.js'), 'utf-8');
+
+ await this.runScript(script, 'cjs');
+ });
+ }
+);
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer-webpack.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-webpack.spec.ts
new file mode 100644
index 0000000000..93902aec32
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer-webpack.spec.ts
@@ -0,0 +1,47 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {readFile, rm, writeFile} from 'fs/promises';
+import {join} from 'path';
+
+import {configureSandbox} from './sandbox.js';
+import {execFile, readAsset} from './util.js';
+
+describe('`puppeteer` with Webpack', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ devDependencies: ['webpack', 'webpack-cli'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ });
+
+ it('evaluates WebPack Bundles', async function () {
+ // Write a Webpack configuration.
+ await writeFile(
+ join(this.sandbox, 'webpack.config.mjs'),
+ await readAsset('puppeteer', 'webpack', 'webpack.config.js')
+ );
+
+ // Write the source code.
+ await writeFile(
+ join(this.sandbox, 'index.js'),
+ await readAsset('puppeteer', 'basic.js')
+ );
+
+ // Bundle.
+ await execFile('npx', ['webpack'], {cwd: this.sandbox, shell: true});
+
+ // Remove `node_modules` to test independence.
+ await rm('node_modules', {recursive: true, force: true});
+
+ const script = await readFile(join(this.sandbox, 'bundle.js'), 'utf-8');
+
+ await this.runScript(script, 'cjs');
+ });
+});
diff --git a/remote/test/puppeteer/test/installation/src/puppeteer.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer.spec.ts
new file mode 100644
index 0000000000..d7b8757284
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/puppeteer.spec.ts
@@ -0,0 +1,104 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import {readdirSync} from 'fs';
+import {readdir} from 'fs/promises';
+import {platform} from 'os';
+import {join} from 'path';
+
+import {configureSandbox} from './sandbox.js';
+import {readAsset} from './util.js';
+
+describe('`puppeteer`', () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ });
+
+ it('evaluates CommonJS', async function () {
+ const files = await readdir(join(this.sandbox, '.cache', 'puppeteer'));
+ assert.equal(files.length, 2);
+ assert(files.includes('chrome'));
+ assert(files.includes('chrome-headless-shell'));
+
+ const script = await readAsset('puppeteer-core', 'requires.cjs');
+ await this.runScript(script, 'cjs');
+ });
+
+ it('evaluates ES modules', async function () {
+ const script = await readAsset('puppeteer-core', 'imports.js');
+ await this.runScript(script, 'mjs');
+ });
+});
+
+// Skipping this test on Windows as windows runners are much slower.
+(platform() === 'win32' ? describe.skip : describe)(
+ '`puppeteer` with PUPPETEER_DOWNLOAD_PATH',
+ () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_DOWNLOAD_PATH: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ });
+
+ it('evaluates', async function () {
+ const files = await readdir(join(this.sandbox, '.cache', 'puppeteer'));
+ assert.equal(files.length, 2);
+ assert(files.includes('chrome'));
+ assert(files.includes('chrome-headless-shell'));
+
+ const script = await readAsset('puppeteer', 'basic.js');
+ await this.runScript(script, 'mjs');
+ });
+ }
+);
+
+// Skipping this test on Windows as windows runners are much slower.
+(platform() === 'win32' ? describe.skip : describe)(
+ '`puppeteer` clears cache',
+ () => {
+ configureSandbox({
+ dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'],
+ env: cwd => {
+ return {
+ PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'),
+ };
+ },
+ });
+
+ it('evaluates', async function () {
+ assert.equal(
+ readdirSync(join(this.sandbox, '.cache', 'puppeteer', 'chrome')).length,
+ 1
+ );
+
+ await this.runScript(
+ await readAsset('puppeteer', 'installCanary.js'),
+ 'mjs'
+ );
+
+ assert.equal(
+ readdirSync(join(this.sandbox, '.cache', 'puppeteer', 'chrome')).length,
+ 2
+ );
+
+ await this.runScript(await readAsset('puppeteer', 'trimCache.js'), 'mjs');
+
+ assert.equal(
+ readdirSync(join(this.sandbox, '.cache', 'puppeteer', 'chrome')).length,
+ 1
+ );
+ });
+ }
+);
diff --git a/remote/test/puppeteer/test/installation/src/sandbox.ts b/remote/test/puppeteer/test/installation/src/sandbox.ts
new file mode 100644
index 0000000000..fde30dfcf9
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/sandbox.ts
@@ -0,0 +1,131 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+import crypto from 'crypto';
+import {mkdtemp, rm, writeFile} from 'fs/promises';
+import {tmpdir} from 'os';
+import {join} from 'path';
+
+import {
+ PUPPETEER_CORE_PACKAGE_PATH,
+ PUPPETEER_PACKAGE_PATH,
+ PUPPETEER_BROWSERS_PACKAGE_PATH,
+} from './constants.js';
+import {execFile} from './util.js';
+
+const PKG_MANAGER = process.env['PKG_MANAGER'] || 'npm';
+
+let ADD_PKG_SUBCOMMAND = 'install';
+if (PKG_MANAGER !== 'npm') {
+ ADD_PKG_SUBCOMMAND = 'add';
+}
+
+export interface ItEvaluatesOptions {
+ commonjs?: boolean;
+}
+
+export interface ItEvaluatesFn {
+ (
+ title: string,
+ options: ItEvaluatesOptions,
+ getScriptContent: (cwd: string) => Promise<string>
+ ): void;
+ (title: string, getScriptContent: (cwd: string) => Promise<string>): void;
+}
+
+export interface SandboxOptions {
+ dependencies?: string[];
+ devDependencies?: string[];
+ /**
+ * This should be idempotent.
+ */
+ env?: ((cwd: string) => NodeJS.ProcessEnv) | NodeJS.ProcessEnv;
+ before?: (cwd: string) => Promise<void>;
+}
+
+declare module 'mocha' {
+ export interface Context {
+ /**
+ * The path to the root of the sandbox folder.
+ */
+ sandbox: string;
+ env: NodeJS.ProcessEnv | undefined;
+ runScript: (content: string, type: 'cjs' | 'mjs') => Promise<void>;
+ }
+}
+
+/**
+ * Configures mocha before/after hooks to create a temp folder and install
+ * specified dependencies.
+ */
+export const configureSandbox = (options: SandboxOptions): void => {
+ before(async function (): Promise<void> {
+ console.time('before');
+ const sandbox = await mkdtemp(join(tmpdir(), 'puppeteer-'));
+ const dependencies = (options.dependencies ?? []).map(module => {
+ switch (module) {
+ case 'puppeteer':
+ return PUPPETEER_PACKAGE_PATH;
+ case 'puppeteer-core':
+ return PUPPETEER_CORE_PACKAGE_PATH;
+ case '@puppeteer/browsers':
+ return PUPPETEER_BROWSERS_PACKAGE_PATH;
+ default:
+ return module;
+ }
+ });
+ const devDependencies = options.devDependencies ?? [];
+
+ let getEnv: (cwd: string) => NodeJS.ProcessEnv | undefined;
+ if (typeof options.env === 'function') {
+ getEnv = options.env;
+ } else {
+ const env = options.env;
+ getEnv = () => {
+ return env;
+ };
+ }
+ const env = {...process.env, ...getEnv(sandbox)};
+
+ await options.before?.(sandbox);
+ if (dependencies.length > 0) {
+ await execFile(PKG_MANAGER, [ADD_PKG_SUBCOMMAND, ...dependencies], {
+ cwd: sandbox,
+ env,
+ shell: true,
+ });
+ }
+ if (devDependencies.length > 0) {
+ await execFile(
+ PKG_MANAGER,
+ [ADD_PKG_SUBCOMMAND, '-D', ...devDependencies],
+ {
+ cwd: sandbox,
+ env,
+ shell: true,
+ }
+ );
+ }
+
+ this.sandbox = sandbox;
+ this.env = env;
+ this.runScript = async (content: string, type: 'cjs' | 'mjs') => {
+ const script = join(sandbox, `script-${crypto.randomUUID()}.${type}`);
+ await writeFile(script, content);
+ await execFile('node', [script], {cwd: sandbox, env});
+ };
+ console.timeEnd('before');
+ });
+
+ after(async function () {
+ console.time('after');
+ if (!process.env['KEEP_SANDBOX']) {
+ await rm(this.sandbox, {recursive: true, force: true, maxRetries: 5});
+ } else {
+ console.log('sandbox saved in', this.sandbox);
+ }
+ console.timeEnd('after');
+ });
+};
diff --git a/remote/test/puppeteer/test/installation/src/util.ts b/remote/test/puppeteer/test/installation/src/util.ts
new file mode 100644
index 0000000000..c975fd61e3
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/src/util.ts
@@ -0,0 +1,17 @@
+/**
+ * @license
+ * Copyright 2022 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import {execFile as execFileAsync} from 'child_process';
+import {readFile} from 'fs/promises';
+import {join} from 'path';
+import {promisify} from 'util';
+
+import {ASSETS_DIR} from './constants.js';
+
+export const execFile = promisify(execFileAsync);
+export const readAsset = (...components: string[]): Promise<string> => {
+ return readFile(join(ASSETS_DIR, ...components), 'utf8');
+};
diff --git a/remote/test/puppeteer/test/installation/tsconfig.json b/remote/test/puppeteer/test/installation/tsconfig.json
new file mode 100644
index 0000000000..146127b470
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/tsconfig.json
@@ -0,0 +1,10 @@
+{
+ "extends": "../../tsconfig.base.json",
+ "compilerOptions": {
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext",
+ "outDir": "build",
+ "rootDir": "src",
+ },
+ "include": ["src"],
+}
diff --git a/remote/test/puppeteer/test/installation/tsdoc.json b/remote/test/puppeteer/test/installation/tsdoc.json
new file mode 100644
index 0000000000..f5b91f4af6
--- /dev/null
+++ b/remote/test/puppeteer/test/installation/tsdoc.json
@@ -0,0 +1,15 @@
+{
+ "$schema": "https://developer.microsoft.com/json-schemas/tsdoc/v0/tsdoc.schema.json",
+
+ "extends": ["@microsoft/api-extractor/extends/tsdoc-base.json"],
+ "tagDefinitions": [
+ {
+ "tagName": "@license",
+ "syntaxKind": "modifier",
+ "allowMultiple": false
+ }
+ ],
+ "supportForTags": {
+ "@license": true
+ }
+}