mirror of
https://github.com/microsoft/playwright.git
synced 2024-12-15 22:22:53 +03:00
218 lines
7.3 KiB
JavaScript
Executable File
218 lines
7.3 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
/**
|
|
* Copyright (c) Microsoft Corporation.
|
|
*
|
|
* 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.
|
|
*/
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
const path = require('path');
|
|
const rmSync = require('rimraf').sync;
|
|
const ncp = require('ncp');
|
|
const {spawnSync} = require('child_process');
|
|
const util = require('util');
|
|
|
|
const writeFileAsync = util.promisify(fs.writeFile.bind(fs));
|
|
const cpAsync = util.promisify(ncp);
|
|
|
|
const SCRIPT_NAME = path.basename(__filename);
|
|
const ROOT_PATH = path.join(__dirname, '..');
|
|
|
|
const PLAYWRIGHT_CORE_FILES = ['bin/PrintDeps.exe', 'lib', 'types', 'NOTICE', 'LICENSE'];
|
|
const FFMPEG_FILES = ['third_party/ffmpeg'];
|
|
|
|
const PACKAGES = {
|
|
'playwright': {
|
|
description: 'A high-level API to automate web browsers',
|
|
browsers: ['chromium', 'firefox', 'webkit'],
|
|
// We copy README.md additionally for Playwright so that it looks nice on NPM.
|
|
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES, 'README.md'],
|
|
},
|
|
'playwright-core': {
|
|
description: 'A high-level API to automate web browsers',
|
|
browsers: [],
|
|
files: PLAYWRIGHT_CORE_FILES,
|
|
},
|
|
'playwright-webkit': {
|
|
description: 'A high-level API to automate WebKit',
|
|
browsers: ['webkit'],
|
|
files: PLAYWRIGHT_CORE_FILES,
|
|
},
|
|
'playwright-firefox': {
|
|
description: 'A high-level API to automate Firefox',
|
|
browsers: ['firefox'],
|
|
files: PLAYWRIGHT_CORE_FILES,
|
|
},
|
|
'playwright-chromium': {
|
|
description: 'A high-level API to automate Chromium',
|
|
browsers: ['chromium'],
|
|
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES],
|
|
},
|
|
'playwright-electron': {
|
|
version: '0.4.0', // Manually manage playwright-electron version.
|
|
description: 'A high-level API to automate Electron',
|
|
browsers: [],
|
|
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES],
|
|
},
|
|
'playwright-android': {
|
|
version: '0.0.8', // Manually manage playwright-android version.
|
|
description: 'A high-level API to automate Chrome for Android',
|
|
browsers: [],
|
|
files: [...PLAYWRIGHT_CORE_FILES, ...FFMPEG_FILES, 'bin/android-driver.apk', 'bin/android-driver-target.apk'],
|
|
},
|
|
};
|
|
|
|
// 1. Parse CLI arguments
|
|
const args = process.argv.slice(2);
|
|
if (args.some(arg => arg === '--help')) {
|
|
console.log(usage());
|
|
process.exit(1);
|
|
} else if (args.length < 1) {
|
|
console.log(`Please specify package name, e.g. 'playwright' or 'playwright-chromium'.`);
|
|
console.log(`Try running ${SCRIPT_NAME} --help`);
|
|
process.exit(1);
|
|
} else if (args.length < 2) {
|
|
console.log(`Please specify output path`);
|
|
console.log(`Try running ${SCRIPT_NAME} --help`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const packageName = args[0];
|
|
const outputPath = path.resolve(args[1]);
|
|
const packagePath = path.join(__dirname, 'output', packageName);
|
|
const package = PACKAGES[packageName];
|
|
if (!package) {
|
|
console.log(`ERROR: unknown package ${packageName}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
// 2. Setup cleanup if needed
|
|
if (!args.some(arg => arg === '--no-cleanup')) {
|
|
process.on('exit', () => {
|
|
rmSync(packagePath, {});
|
|
});
|
|
process.on('SIGINT', () => process.exit(2));
|
|
process.on('SIGHUP', () => process.exit(3));
|
|
process.on('SIGTERM', () => process.exit(4));
|
|
process.on('uncaughtException', error => {
|
|
console.error(error);
|
|
process.exit(5);
|
|
});
|
|
process.on('unhandledRejection', error => {
|
|
console.error(error);
|
|
process.exit(6);
|
|
});
|
|
}
|
|
|
|
(async () => {
|
|
// 3. Copy package files.
|
|
rmSync(packagePath, {});
|
|
fs.mkdirSync(packagePath, { recursive: true });
|
|
await copyToPackage(path.join(__dirname, 'common') + path.sep, packagePath + path.sep);
|
|
if (fs.existsSync(path.join(__dirname, packageName))) {
|
|
// Copy package-specific files, these can overwrite common ones.
|
|
await copyToPackage(path.join(__dirname, packageName) + path.sep, packagePath + path.sep);
|
|
}
|
|
for (const file of package.files)
|
|
await copyToPackage(path.join(ROOT_PATH, file), path.join(packagePath, file));
|
|
|
|
await copyToPackage(path.join(ROOT_PATH, 'api.json'), path.join(packagePath, 'api.json'));
|
|
await copyToPackage(path.join(ROOT_PATH, 'src/protocol/protocol.yml'), path.join(packagePath, 'protocol.yml'));
|
|
|
|
// 4. Generate package.json
|
|
const pwInternalJSON = require(path.join(ROOT_PATH, 'package.json'));
|
|
await writeToPackage('package.json', JSON.stringify({
|
|
name: packageName,
|
|
version: package.version || pwInternalJSON.version,
|
|
description: package.description,
|
|
repository: pwInternalJSON.repository,
|
|
engines: pwInternalJSON.engines,
|
|
homepage: pwInternalJSON.homepage,
|
|
main: 'index.js',
|
|
bin: {
|
|
playwright: './lib/cli/cli.js',
|
|
},
|
|
exports: {
|
|
// Root import: we have a wrapper ES Module to support the following syntax.
|
|
// const { chromium } = require('playwright');
|
|
// import { chromium } from 'playwright';
|
|
'.': {
|
|
import: './index.mjs',
|
|
require: './index.js',
|
|
},
|
|
// Anything else can be required/imported by providing a relative path.
|
|
'./': './',
|
|
},
|
|
scripts: {
|
|
install: 'node install.js',
|
|
},
|
|
author: pwInternalJSON.author,
|
|
license: pwInternalJSON.license,
|
|
dependencies: pwInternalJSON.dependencies
|
|
}, null, 2));
|
|
|
|
// 5. Generate browsers.json
|
|
const browsersJSON = require(path.join(ROOT_PATH, 'browsers.json'));
|
|
for (const browser of browsersJSON.browsers)
|
|
browser.download = package.browsers.includes(browser.name);
|
|
await writeToPackage('browsers.json', JSON.stringify(browsersJSON, null, 2));
|
|
|
|
// 6. Bake commit SHA into the package
|
|
const commitSHA = spawnSync('git', ['rev-parse', 'HEAD'], {cwd: __dirname, encoding: 'utf8'});
|
|
await writeToPackage('commitinfo', commitSHA.stdout.trim());
|
|
|
|
// 7. Run npm pack
|
|
const shell = os.platform() === 'win32';
|
|
const {stdout, stderr, status} = spawnSync('npm', ['pack'], {cwd: packagePath, encoding: 'utf8', shell});
|
|
if (status !== 0) {
|
|
console.log(`ERROR: "npm pack" failed`);
|
|
console.log(stderr);
|
|
process.exit(1);
|
|
}
|
|
const tgzName = stdout.trim();
|
|
|
|
// 7. Move result to the outputPath
|
|
fs.renameSync(path.join(packagePath, tgzName), outputPath);
|
|
console.log(outputPath);
|
|
})();
|
|
|
|
async function writeToPackage(fileName, content) {
|
|
const toPath = path.join(packagePath, fileName);
|
|
console.error(`- generating: //${path.relative(ROOT_PATH, toPath)}`);
|
|
await writeFileAsync(toPath, content);
|
|
}
|
|
|
|
async function copyToPackage(fromPath, toPath) {
|
|
console.error(`- copying: //${path.relative(ROOT_PATH, fromPath)} -> //${path.relative(ROOT_PATH, toPath)}`);
|
|
try {
|
|
fs.mkdirSync(path.dirname(toPath), { recursive: true });
|
|
} catch (e) {
|
|
// the folder might exist already
|
|
}
|
|
await cpAsync(fromPath, toPath);
|
|
}
|
|
|
|
function usage() {
|
|
return `
|
|
usage: ${SCRIPT_NAME} <package-name> <output-path> [--no-cleanup]
|
|
|
|
Creates a .tgz of the package and saves it at the given output path
|
|
|
|
--no-cleanup skip cleaning up generated files from package directory
|
|
|
|
Example:
|
|
${SCRIPT_NAME} playwright ./playwright.tgz
|
|
`;
|
|
}
|
|
|