summaryrefslogtreecommitdiffstats
path: root/remote/test/puppeteer/packages/browsers/test/src/chrome
diff options
context:
space:
mode:
Diffstat (limited to 'remote/test/puppeteer/packages/browsers/test/src/chrome')
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chrome/chrome-data.spec.ts119
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chrome/cli.spec.ts94
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts233
-rw-r--r--remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts122
4 files changed, 568 insertions, 0 deletions
diff --git a/remote/test/puppeteer/packages/browsers/test/src/chrome/chrome-data.spec.ts b/remote/test/puppeteer/packages/browsers/test/src/chrome/chrome-data.spec.ts
new file mode 100644
index 0000000000..510afa8454
--- /dev/null
+++ b/remote/test/puppeteer/packages/browsers/test/src/chrome/chrome-data.spec.ts
@@ -0,0 +1,119 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import path from 'path';
+
+import {
+ BrowserPlatform,
+ ChromeReleaseChannel,
+} from '../../../lib/cjs/browser-data/browser-data.js';
+import {
+ resolveDownloadUrl,
+ relativeExecutablePath,
+ resolveSystemExecutablePath,
+ resolveBuildId,
+} from '../../../lib/cjs/browser-data/chrome.js';
+
+describe('Chrome', () => {
+ it('should resolve download URLs', () => {
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.LINUX, '113.0.5672.0'),
+ 'https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/113.0.5672.0/linux64/chrome-linux64.zip'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC, '113.0.5672.0'),
+ 'https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/113.0.5672.0/mac-x64/chrome-mac-x64.zip'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.MAC_ARM, '113.0.5672.0'),
+ 'https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/113.0.5672.0/mac-arm64/chrome-mac-arm64.zip'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN32, '113.0.5672.0'),
+ 'https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/113.0.5672.0/win32/chrome-win32.zip'
+ );
+ assert.strictEqual(
+ resolveDownloadUrl(BrowserPlatform.WIN64, '113.0.5672.0'),
+ 'https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/113.0.5672.0/win64/chrome-win64.zip'
+ );
+ });
+
+ it('should resolve executable paths', () => {
+ assert.strictEqual(
+ relativeExecutablePath(BrowserPlatform.LINUX, '12372323'),
+ path.join('chrome-linux64', 'chrome')
+ );
+ assert.strictEqual(
+ relativeExecutablePath(BrowserPlatform.MAC, '12372323'),
+ path.join(
+ 'chrome-mac-x64',
+ 'Google Chrome for Testing.app',
+ 'Contents',
+ 'MacOS',
+ 'Google Chrome for Testing'
+ )
+ );
+ assert.strictEqual(
+ relativeExecutablePath(BrowserPlatform.MAC_ARM, '12372323'),
+ path.join(
+ 'chrome-mac-arm64',
+ 'Google Chrome for Testing.app',
+ 'Contents',
+ 'MacOS',
+ 'Google Chrome for Testing'
+ )
+ );
+ assert.strictEqual(
+ relativeExecutablePath(BrowserPlatform.WIN32, '12372323'),
+ path.join('chrome-win32', 'chrome.exe')
+ );
+ assert.strictEqual(
+ relativeExecutablePath(BrowserPlatform.WIN64, '12372323'),
+ path.join('chrome-win64', 'chrome.exe')
+ );
+ });
+
+ it('should resolve system executable path', () => {
+ process.env['PROGRAMFILES'] = 'C:\\ProgramFiles';
+ try {
+ assert.strictEqual(
+ resolveSystemExecutablePath(
+ BrowserPlatform.WIN32,
+ ChromeReleaseChannel.DEV
+ ),
+ 'C:\\ProgramFiles\\Google\\Chrome Dev\\Application\\chrome.exe'
+ );
+ } finally {
+ delete process.env['PROGRAMFILES'];
+ }
+
+ assert.strictEqual(
+ resolveSystemExecutablePath(
+ BrowserPlatform.MAC,
+ ChromeReleaseChannel.BETA
+ ),
+ '/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta'
+ );
+ assert.throws(() => {
+ assert.strictEqual(
+ resolveSystemExecutablePath(
+ BrowserPlatform.LINUX,
+ ChromeReleaseChannel.CANARY
+ ),
+ path.join('chrome-linux', 'chrome')
+ );
+ }, new Error(`Unable to detect browser executable path for 'canary' on linux.`));
+ });
+
+ it('should resolve milestones', async () => {
+ assert.strictEqual(await resolveBuildId('115'), '115.0.5790.170');
+ });
+
+ it('should resolve build prefix', async () => {
+ assert.strictEqual(await resolveBuildId('115.0.5790'), '115.0.5790.170');
+ });
+});
diff --git a/remote/test/puppeteer/packages/browsers/test/src/chrome/cli.spec.ts b/remote/test/puppeteer/packages/browsers/test/src/chrome/cli.spec.ts
new file mode 100644
index 0000000000..bdda9d9aa9
--- /dev/null
+++ b/remote/test/puppeteer/packages/browsers/test/src/chrome/cli.spec.ts
@@ -0,0 +1,94 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import fs from 'fs';
+import os from 'os';
+import path from 'path';
+
+import {CLI} from '../../../lib/cjs/CLI.js';
+import {
+ createMockedReadlineInterface,
+ setupTestServer,
+ getServerUrl,
+} from '../utils.js';
+import {testChromeBuildId} from '../versions.js';
+
+describe('Chrome CLI', function () {
+ this.timeout(90000);
+
+ setupTestServer();
+
+ let tmpDir = '/tmp/puppeteer-browsers-test';
+
+ beforeEach(() => {
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'puppeteer-browsers-test'));
+ });
+
+ afterEach(async () => {
+ await new CLI(tmpDir, createMockedReadlineInterface('yes')).run([
+ 'npx',
+ '@puppeteer/browsers',
+ 'clear',
+ `--path=${tmpDir}`,
+ `--base-url=${getServerUrl()}`,
+ ]);
+ });
+
+ it('should download Chrome binaries', async () => {
+ await new CLI(tmpDir).run([
+ 'npx',
+ '@puppeteer/browsers',
+ 'install',
+ `chrome@${testChromeBuildId}`,
+ `--path=${tmpDir}`,
+ '--platform=linux',
+ `--base-url=${getServerUrl()}`,
+ ]);
+ assert.ok(
+ fs.existsSync(
+ path.join(
+ tmpDir,
+ 'chrome',
+ `linux-${testChromeBuildId}`,
+ 'chrome-linux64',
+ 'chrome'
+ )
+ )
+ );
+
+ await new CLI(tmpDir, createMockedReadlineInterface('no')).run([
+ 'npx',
+ '@puppeteer/browsers',
+ 'clear',
+ `--path=${tmpDir}`,
+ ]);
+ assert.ok(
+ fs.existsSync(
+ path.join(
+ tmpDir,
+ 'chrome',
+ `linux-${testChromeBuildId}`,
+ 'chrome-linux64',
+ 'chrome'
+ )
+ )
+ );
+ });
+
+ // Skipped because the current latest is not published yet.
+ it.skip('should download latest Chrome binaries', async () => {
+ await new CLI(tmpDir).run([
+ 'npx',
+ '@puppeteer/browsers',
+ 'install',
+ `chrome@latest`,
+ `--path=${tmpDir}`,
+ '--platform=linux',
+ `--base-url=${getServerUrl()}`,
+ ]);
+ });
+});
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
new file mode 100644
index 0000000000..8103ff3612
--- /dev/null
+++ b/remote/test/puppeteer/packages/browsers/test/src/chrome/install.spec.ts
@@ -0,0 +1,233 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import fs from 'fs';
+import http from 'http';
+import https from 'https';
+import os from 'os';
+import path from 'path';
+
+import {
+ install,
+ canDownload,
+ Browser,
+ BrowserPlatform,
+ Cache,
+} from '../../../lib/cjs/main.js';
+import {getServerUrl, setupTestServer} from '../utils.js';
+import {testChromeBuildId} from '../versions.js';
+
+/**
+ * Tests in this spec use real download URLs and unpack live browser archives
+ * so it requires the network access.
+ */
+describe('Chrome install', () => {
+ setupTestServer();
+
+ let tmpDir = '/tmp/puppeteer-browsers-test';
+
+ beforeEach(() => {
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'puppeteer-browsers-test'));
+ });
+
+ afterEach(() => {
+ new Cache(tmpDir).clear();
+ });
+
+ it('should check if a buildId can be downloaded', async () => {
+ assert.ok(
+ await canDownload({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: testChromeBuildId,
+ baseUrl: getServerUrl(),
+ })
+ );
+ });
+
+ it('should report if a buildId is not downloadable', async () => {
+ assert.strictEqual(
+ await canDownload({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: 'unknown',
+ baseUrl: getServerUrl(),
+ }),
+ false
+ );
+ });
+
+ it('should download a buildId that is a zip archive', async function () {
+ this.timeout(60000);
+ const expectedOutputPath = path.join(
+ tmpDir,
+ 'chrome',
+ `${BrowserPlatform.LINUX}-${testChromeBuildId}`
+ );
+ assert.strictEqual(fs.existsSync(expectedOutputPath), false);
+ let browser = await install({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: testChromeBuildId,
+ baseUrl: getServerUrl(),
+ });
+ assert.strictEqual(browser.path, expectedOutputPath);
+ assert.ok(fs.existsSync(expectedOutputPath));
+ // Second iteration should be no-op.
+ browser = await install({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: testChromeBuildId,
+ baseUrl: getServerUrl(),
+ });
+ assert.strictEqual(browser.path, expectedOutputPath);
+ assert.ok(fs.existsSync(expectedOutputPath));
+ // Should discover installed browsers.
+ const cache = new Cache(tmpDir);
+ const installed = cache.getInstalledBrowsers();
+ assert.deepStrictEqual(browser, installed[0]);
+ assert.deepStrictEqual(
+ browser!.executablePath,
+ installed[0]?.executablePath
+ );
+ });
+
+ it('throws on invalid URL', async function () {
+ const expectedOutputPath = path.join(
+ tmpDir,
+ 'chrome',
+ `${BrowserPlatform.LINUX}-${testChromeBuildId}`
+ );
+ assert.strictEqual(fs.existsSync(expectedOutputPath), false);
+
+ async function installThatThrows(): Promise<unknown> {
+ try {
+ await install({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: testChromeBuildId,
+ baseUrl: 'https://127.0.0.1',
+ });
+ return undefined;
+ } catch (err) {
+ return err;
+ }
+ }
+ assert.ok(await installThatThrows());
+ assert.strictEqual(fs.existsSync(expectedOutputPath), false);
+ });
+
+ describe('with proxy', () => {
+ const proxyUrl = new URL(`http://localhost:54321`);
+ let proxyServer: http.Server;
+ let proxiedRequestUrls: string[] = [];
+ let proxiedRequestHosts: string[] = [];
+
+ beforeEach(() => {
+ proxiedRequestUrls = [];
+ proxiedRequestHosts = [];
+ proxyServer = http
+ .createServer(
+ (
+ originalRequest: http.IncomingMessage,
+ originalResponse: http.ServerResponse
+ ) => {
+ const url = originalRequest.url as string;
+ const proxyRequest = (
+ url.startsWith('http:') ? http : https
+ ).request(
+ url,
+ {
+ method: originalRequest.method,
+ rejectUnauthorized: false,
+ },
+ proxyResponse => {
+ originalResponse.writeHead(
+ proxyResponse.statusCode as number,
+ proxyResponse.headers
+ );
+ proxyResponse.pipe(originalResponse, {end: true});
+ }
+ );
+ originalRequest.pipe(proxyRequest, {end: true});
+ proxiedRequestUrls.push(url);
+ proxiedRequestHosts.push(originalRequest.headers?.host || '');
+ }
+ )
+ .listen({
+ port: proxyUrl.port,
+ hostname: proxyUrl.hostname,
+ });
+
+ process.env['HTTPS_PROXY'] = proxyUrl.toString();
+ process.env['HTTP_PROXY'] = proxyUrl.toString();
+ });
+
+ afterEach(async () => {
+ await new Promise((resolve, reject) => {
+ proxyServer.close(error => {
+ if (error) {
+ reject(error);
+ } else {
+ resolve(undefined);
+ }
+ });
+ });
+ delete process.env['HTTP_PROXY'];
+ delete process.env['HTTPS_PROXY'];
+ });
+
+ it('can send canDownload requests via a proxy', async () => {
+ assert.strictEqual(
+ await canDownload({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: testChromeBuildId,
+ baseUrl: getServerUrl(),
+ }),
+ true
+ );
+ assert.deepStrictEqual(proxiedRequestUrls, [
+ getServerUrl() + '/113.0.5672.0/linux64/chrome-linux64.zip',
+ ]);
+ assert.deepStrictEqual(proxiedRequestHosts, [
+ getServerUrl().replace('http://', ''),
+ ]);
+ });
+
+ it('can download via a proxy', async function () {
+ this.timeout(120000);
+ const expectedOutputPath = path.join(
+ tmpDir,
+ 'chrome',
+ `${BrowserPlatform.LINUX}-${testChromeBuildId}`
+ );
+ assert.strictEqual(fs.existsSync(expectedOutputPath), false);
+ const browser = await install({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: testChromeBuildId,
+ baseUrl: getServerUrl(),
+ });
+ assert.strictEqual(browser.path, expectedOutputPath);
+ assert.ok(fs.existsSync(expectedOutputPath));
+ assert.deepStrictEqual(proxiedRequestUrls, [
+ getServerUrl() + '/113.0.5672.0/linux64/chrome-linux64.zip',
+ ]);
+ assert.deepStrictEqual(proxiedRequestHosts, [
+ getServerUrl().replace('http://', ''),
+ ]);
+ });
+ });
+});
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
new file mode 100644
index 0000000000..c420d9e0b6
--- /dev/null
+++ b/remote/test/puppeteer/packages/browsers/test/src/chrome/launch.spec.ts
@@ -0,0 +1,122 @@
+/**
+ * @license
+ * Copyright 2023 Google Inc.
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import assert from 'assert';
+import fs from 'fs';
+import os from 'os';
+import path from 'path';
+
+import {
+ CDP_WEBSOCKET_ENDPOINT_REGEX,
+ computeExecutablePath,
+ launch,
+ install,
+ Browser,
+ BrowserPlatform,
+} from '../../../lib/cjs/main.js';
+import {getServerUrl, setupTestServer, clearCache} from '../utils.js';
+import {testChromeBuildId} from '../versions.js';
+
+describe('Chrome', () => {
+ it('should compute executable path for Chrome', () => {
+ assert.strictEqual(
+ computeExecutablePath({
+ browser: Browser.CHROME,
+ platform: BrowserPlatform.LINUX,
+ buildId: '123',
+ cacheDir: '.cache',
+ }),
+ path.join('.cache', 'chrome', 'linux-123', 'chrome-linux64', 'chrome')
+ );
+ });
+
+ describe('launcher', function () {
+ setupTestServer();
+
+ this.timeout(60000);
+
+ let tmpDir = '/tmp/puppeteer-browsers-test';
+
+ beforeEach(async () => {
+ tmpDir = fs.mkdtempSync(
+ path.join(os.tmpdir(), 'puppeteer-browsers-test')
+ );
+ await install({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ buildId: testChromeBuildId,
+ baseUrl: getServerUrl(),
+ });
+ });
+
+ afterEach(() => {
+ clearCache(tmpDir);
+ });
+
+ function getArgs() {
+ return [
+ '--allow-pre-commit-input',
+ '--disable-background-networking',
+ '--disable-background-timer-throttling',
+ '--disable-backgrounding-occluded-windows',
+ '--disable-breakpad',
+ '--disable-client-side-phishing-detection',
+ '--disable-component-extensions-with-background-pages',
+ '--disable-component-update',
+ '--disable-default-apps',
+ '--disable-dev-shm-usage',
+ '--disable-extensions',
+ '--disable-features=Translate,BackForwardCache,AcceptCHFrame,MediaRouter,OptimizationHints,DialMediaRouteProvider',
+ '--disable-hang-monitor',
+ '--disable-ipc-flooding-protection',
+ '--disable-popup-blocking',
+ '--disable-prompt-on-repost',
+ '--disable-renderer-backgrounding',
+ '--disable-sync',
+ '--enable-automation',
+ '--enable-features=NetworkServiceInProcess2',
+ '--export-tagged-pdf',
+ '--force-color-profile=srgb',
+ '--headless=new',
+ '--metrics-recording-only',
+ '--no-first-run',
+ '--password-store=basic',
+ '--remote-debugging-port=9222',
+ '--use-mock-keychain',
+ `--user-data-dir=${path.join(tmpDir, 'profile')}`,
+ 'about:blank',
+ ];
+ }
+
+ it('should launch a Chrome browser', async () => {
+ const executablePath = computeExecutablePath({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ buildId: testChromeBuildId,
+ });
+ const process = launch({
+ executablePath,
+ args: getArgs(),
+ });
+ await process.close();
+ });
+
+ it('should allow parsing stderr output of the browser process', async () => {
+ const executablePath = computeExecutablePath({
+ cacheDir: tmpDir,
+ browser: Browser.CHROME,
+ buildId: testChromeBuildId,
+ });
+ const process = launch({
+ executablePath,
+ args: getArgs(),
+ });
+ const url = await process.waitForLineOutput(CDP_WEBSOCKET_ENDPOINT_REGEX);
+ await process.close();
+ assert.ok(url.startsWith('ws://127.0.0.1:9222/devtools/browser'));
+ });
+ });
+});