Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ lib/injected/
!types/*
!index.d.ts

# used for npm install scripts
!download-browser.js

# root for "playwright-core" package
!index.js

Expand Down
69 changes: 0 additions & 69 deletions download-browser.js

This file was deleted.

4 changes: 2 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { initializePlaywright } = require('./download-browser');
const { Playwright } = require('./lib/server/playwright');

module.exports = initializePlaywright(__dirname, require('./browsers.json'));
module.exports = new Playwright(__dirname, require('./browsers.json')['browsers']);
7 changes: 4 additions & 3 deletions install-from-github.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,18 +63,19 @@ async function listFiles(dirpath) {
}

async function downloadAllBrowsersAndGenerateProtocolTypes() {
const { targetDirectory, executablePath, downloadBrowserWithProgressBar } = require('./download-browser');
const { downloadBrowserWithProgressBar } = require('./lib/install/browserFetcher');
const protocolGenerator = require('./utils/protocol-types-generator');
const browserPaths = require('./lib/install/browserPaths');
const browsers = require('./browsers.json')['browsers'];
for (const browser of browsers) {
if (await downloadBrowserWithProgressBar(__dirname, browser))
await protocolGenerator.generateProtocol(browser.name, executablePath(__dirname, browser)).catch(console.warn);
await protocolGenerator.generateProtocol(browser.name, browserPaths.executablePath(__dirname, browser)).catch(console.warn);
}

// Cleanup stale revisions.
const directories = new Set(await readdirAsync(path.join(__dirname, '.local-browsers')));
for (const browser of browsers)
directories.delete(targetDirectory(__dirname, browser));
directories.delete(browserPaths.browserDirectory(__dirname, browser));
await Promise.all([...directories].map(directory => rmAsync(directory)));

try {
Expand Down
8 changes: 0 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,5 @@
"typescript": "^3.8.3",
"webpack": "^4.41.0",
"webpack-cli": "^3.3.9"
},
"browser": {
"./lib/BrowserFetcher.js": false,
"ws": "./utils/browser/WebSocket",
"fs": false,
"child_process": false,
"rimraf": false,
"readline": false
}
}
4 changes: 2 additions & 2 deletions packages/playwright-chromium/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { initializePlaywright } = require('playwright-core/download-browser');
const { Playwright } = require('playwright-core/lib/server/playwright');

module.exports = initializePlaywright(__dirname, require('./browsers.json'));
module.exports = new Playwright(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright-chromium/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { downloadBrowsersWithProgressBar } = require('playwright-core/download-browser');
const { downloadBrowsersWithProgressBar } = require('playwright-core/lib/install/browserFetcher');

downloadBrowsersWithProgressBar(__dirname, require('./browsers.json'));
downloadBrowsersWithProgressBar(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright-firefox/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { initializePlaywright } = require('playwright-core/download-browser');
const { Playwright } = require('playwright-core/lib/server/playwright');

module.exports = initializePlaywright(__dirname, require('./browsers.json'));
module.exports = new Playwright(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright-firefox/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { downloadBrowsersWithProgressBar } = require('playwright-core/download-browser');
const { downloadBrowsersWithProgressBar } = require('playwright-core/lib/install/browserFetcher');

downloadBrowsersWithProgressBar(__dirname, require('./browsers.json'));
downloadBrowsersWithProgressBar(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright-webkit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { initializePlaywright } = require('playwright-core/download-browser');
const { Playwright } = require('playwright-core/lib/server/playwright');

module.exports = initializePlaywright(__dirname, require('./browsers.json'));
module.exports = new Playwright(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright-webkit/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { downloadBrowsersWithProgressBar } = require('playwright-core/download-browser');
const { downloadBrowsersWithProgressBar } = require('playwright-core/lib/install/browserFetcher');

downloadBrowsersWithProgressBar(__dirname, require('./browsers.json'));
downloadBrowsersWithProgressBar(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { initializePlaywright } = require('playwright-core/download-browser');
const { Playwright } = require('playwright-core/lib/server/playwright');

module.exports = initializePlaywright(__dirname, require('./browsers.json'));
module.exports = new Playwright(__dirname, require('./browsers.json')['browsers']);
4 changes: 2 additions & 2 deletions packages/playwright/install.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@
* limitations under the License.
*/

const { downloadBrowsersWithProgressBar } = require('playwright-core/download-browser');
const { downloadBrowsersWithProgressBar } = require('playwright-core/lib/install/browserFetcher');

downloadBrowsersWithProgressBar(__dirname, require('./browsers.json'));
downloadBrowsersWithProgressBar(__dirname, require('./browsers.json')['browsers']);
119 changes: 26 additions & 93 deletions src/server/browserFetcher.ts → src/install/browserFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
* limitations under the License.
*/

import { execSync } from 'child_process';
import * as extract from 'extract-zip';
import * as fs from 'fs';
import * as ProxyAgent from 'https-proxy-agent';
Expand All @@ -25,37 +24,23 @@ import * as ProgressBar from 'progress';
import { getProxyForUrl } from 'proxy-from-env';
import * as URL from 'url';
import * as util from 'util';
import { assert, logPolitely } from '../helper';
import { assert, logPolitely, getFromENV } from '../helper';
import * as browserPaths from './browserPaths';
import { BrowserName, BrowserPlatform, BrowserDescriptor } from './browserPaths';

const unlinkAsync = util.promisify(fs.unlink.bind(fs));
const chmodAsync = util.promisify(fs.chmod.bind(fs));
const existsAsync = (path: string): Promise<boolean> => new Promise(resolve => fs.stat(path, err => resolve(!err)));

export type OnProgressCallback = (downloadedBytes: number, totalBytes: number) => void;
export type BrowserName = ('chromium'|'webkit'|'firefox');
export type BrowserPlatform = ('win32'|'win64'|'mac10.13'|'mac10.14'|'mac10.15'|'linux');

const DEFAULT_DOWNLOAD_HOSTS = {
const DEFAULT_DOWNLOAD_HOSTS: { [key: string]: string } = {
chromium: 'https://storage.googleapis.com',
firefox: 'https://playwright.azureedge.net',
webkit: 'https://playwright.azureedge.net',
};

const hostPlatform = ((): BrowserPlatform => {
const platform = os.platform();
if (platform === 'darwin') {
const macVersion = execSync('sw_vers -productVersion').toString('utf8').trim().split('.').slice(0, 2).join('.');
return `mac${macVersion}` as BrowserPlatform;
}
if (platform === 'linux')
return 'linux';
if (platform === 'win32')
return os.arch() === 'x64' ? 'win64' : 'win32';
return platform as BrowserPlatform;
})();

function getDownloadUrl(browserName: BrowserName, platform?: BrowserPlatform): string | undefined {
platform = platform || hostPlatform;
function getDownloadUrl(browserName: BrowserName, platform: BrowserPlatform): string | undefined {
if (browserName === 'chromium') {
return new Map<BrowserPlatform, string>([
['linux', '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip'],
Expand Down Expand Up @@ -90,79 +75,31 @@ function getDownloadUrl(browserName: BrowserName, platform?: BrowserPlatform): s
}
}

function getRelativeExecutablePath(browserName: BrowserName): string[] | undefined {
if (browserName === 'chromium') {
return new Map<BrowserPlatform, string[]>([
['linux', ['chrome-linux', 'chrome']],
['mac10.13', ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium']],
['mac10.14', ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium']],
['mac10.15', ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium']],
['win32', ['chrome-win', 'chrome.exe']],
['win64', ['chrome-win', 'chrome.exe']],
]).get(hostPlatform);
}

if (browserName === 'firefox') {
return new Map<BrowserPlatform, string[]>([
['linux', ['firefox', 'firefox']],
['mac10.13', ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox']],
['mac10.14', ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox']],
['mac10.15', ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox']],
['win32', ['firefox', 'firefox.exe']],
['win64', ['firefox', 'firefox.exe']],
]).get(hostPlatform);
}

if (browserName === 'webkit') {
return new Map<BrowserPlatform, string[] | undefined>([
['linux', ['pw_run.sh']],
['mac10.13', undefined],
['mac10.14', ['pw_run.sh']],
['mac10.15', ['pw_run.sh']],
['win32', ['Playwright.exe']],
['win64', ['Playwright.exe']],
]).get(hostPlatform);
}
}

export type DownloadOptions = {
baseDir: string,
browserName: BrowserName,
browserRevision: string,
browser: BrowserDescriptor,
packagePath: string,
serverHost?: string,
};

function revisionURL(options: DownloadOptions, platform?: BrowserPlatform): string {
const {
browserName,
browserRevision,
serverHost = DEFAULT_DOWNLOAD_HOSTS[browserName],
} = options;
assert(browserRevision, `'revision' must be specified`);
const urlTemplate = getDownloadUrl(browserName, platform);
assert(urlTemplate, `ERROR: Playwright does not support ${browserName} on ${hostPlatform}`);
return util.format(urlTemplate, serverHost, browserRevision);
function revisionURL(browser: BrowserDescriptor, platform = browserPaths.hostPlatform): string {
const serverHost = getFromENV('PLAYWRIGHT_DOWNLOAD_HOST') || DEFAULT_DOWNLOAD_HOSTS[browser.name];
const urlTemplate = getDownloadUrl(browser.name, platform);
assert(urlTemplate, `ERROR: Playwright does not support ${browser.name} on ${platform}`);
return util.format(urlTemplate, serverHost, browser.revision);
}

export function targetDirectory(baseDir: string, browserName: string, browserRevision: string): string {
return path.join(baseDir, `${browserName}-${browserRevision}`);
}

export function executablePath(baseDir: string, browserName: BrowserName, browserRevision: string): string {
const relativePath = getRelativeExecutablePath(browserName);
assert(relativePath, `Unsupported platform for ${browserName}: ${hostPlatform}`);
return path.join(targetDirectory(baseDir, browserName, browserRevision), ...relativePath);
export async function downloadBrowsersWithProgressBar(packagePath: string, browsers: BrowserDescriptor[]) {
if (getFromENV('PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD')) {
logPolitely('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set');
return false;
}
for (const browser of browsers)
await downloadBrowserWithProgressBar(packagePath, browser);
}

export async function downloadBrowserWithProgressBar(options: DownloadOptions): Promise<boolean> {
const {
baseDir,
browserName,
browserRevision,
} = options;
const progressBarName = `${browserName} v${browserRevision}`;
assert(baseDir, '`baseDir` must be provided');
const targetDir = targetDirectory(baseDir, browserName, browserRevision);
export async function downloadBrowserWithProgressBar(packagePath: string, browser: BrowserDescriptor): Promise<boolean> {
const progressBarName = `${browser.name} v${browser.revision}`;
const targetDir = browserPaths.browserDirectory(packagePath, browser);
if (await existsAsync(targetDir)) {
// Already downloaded.
return false;
Expand All @@ -185,12 +122,12 @@ export async function downloadBrowserWithProgressBar(options: DownloadOptions):
progressBar.tick(delta);
}

const url = revisionURL(options);
const zipPath = path.join(os.tmpdir(), `playwright-download-${browserName}-${hostPlatform}-${browserRevision}.zip`);
const url = revisionURL(browser);
const zipPath = path.join(os.tmpdir(), `playwright-download-${browser.name}-${browserPaths.hostPlatform}-${browser.revision}.zip`);
try {
await downloadFile(url, zipPath, progress);
await extract(zipPath, {dir: targetDir});
await chmodAsync(executablePath(baseDir, browserName, browserRevision), 0o755);
await chmodAsync(browserPaths.executablePath(packagePath, browser), 0o755);
} catch (e) {
process.exitCode = 1;
throw e;
Expand All @@ -208,11 +145,7 @@ function toMegabytes(bytes: number) {
}

export async function canDownload(browserName: BrowserName, browserRevision: string, platform: BrowserPlatform): Promise<boolean> {
const url = revisionURL({
baseDir: '',
browserName,
browserRevision
}, platform);
const url = revisionURL({ name: browserName, revision: browserRevision }, platform);
let resolve: (result: boolean) => void = () => {};
const promise = new Promise<boolean>(x => resolve = x);
const request = httpRequest(url, 'HEAD', response => {
Expand Down
Loading