diff options
Diffstat (limited to 'remote/test/puppeteer/test/installation/src')
9 files changed, 480 insertions, 0 deletions
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..83111f3ad3 --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/browsers.spec.ts @@ -0,0 +1,39 @@ +/** + * Copyright 2023 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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', + }); + 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..e78c93b159 --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/constants.ts @@ -0,0 +1,35 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {dirname, join, resolve} from 'path'; +import {fileURLToPath} from 'url'; + +import glob from 'glob'; + +export const PUPPETEER_CORE_PACKAGE_PATH = resolve( + glob.sync('puppeteer-core-*.tgz')[0]! +); +export const PUPPETEER_BROWSERS_PACKAGE_PATH = resolve( + glob.sync('puppeteer-browsers-[0-9]*.tgz')[0]! +); +export const PUPPETEER_PACKAGE_PATH = resolve( + glob.sync('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-configuration.spec.ts b/remote/test/puppeteer/test/installation/src/puppeteer-configuration.spec.ts new file mode 100644 index 0000000000..f74922844d --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/puppeteer-configuration.spec.ts @@ -0,0 +1,48 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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', () => { + 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, 1); + assert.equal(files[0], 'chrome'); + + 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..03a57d5437 --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/puppeteer-core.spec.ts @@ -0,0 +1,44 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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..edefbd3afe --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/puppeteer-firefox.spec.ts @@ -0,0 +1,47 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import assert from 'assert'; +import {readdir} from 'fs/promises'; +import {join} from 'path'; + +import {configureSandbox} from './sandbox.js'; +import {readAsset} from './util.js'; + +describe('`puppeteer` with Firefox', () => { + configureSandbox({ + dependencies: ['@puppeteer/browsers', 'puppeteer-core', 'puppeteer'], + env: cwd => { + return { + PUPPETEER_CACHE_DIR: join(cwd, '.cache', 'puppeteer'), + PUPPETEER_PRODUCT: 'firefox', + }; + }, + }); + + 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'); + }); +}); 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..d0b97bf75f --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/puppeteer-webpack.spec.ts @@ -0,0 +1,57 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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..6633bdb2e2 --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/puppeteer.spec.ts @@ -0,0 +1,46 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import assert from 'assert'; +import {readdir} from 'fs/promises'; +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, 1); + assert.equal(files[0], 'chrome'); + 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'); + }); +}); 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..7bb9dda194 --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/sandbox.ts @@ -0,0 +1,137 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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> { + 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}); + }; + }); + + after(async function () { + if (!process.env['KEEP_SANDBOX']) { + await rm(this.sandbox, {recursive: true, force: true, maxRetries: 5}); + } else { + console.log('sandbox saved in', this.sandbox); + } + }); +}; 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..404691840a --- /dev/null +++ b/remote/test/puppeteer/test/installation/src/util.ts @@ -0,0 +1,27 @@ +/** + * Copyright 2022 Google Inc. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +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'); +}; |