Skip to content

Commit

Permalink
chore: reuse BrowserFetcher between browsers (microsoft#177)
Browse files Browse the repository at this point in the history
  • Loading branch information
dgozman authored and pavelfeldman committed Dec 8, 2019
1 parent ba4cfe9 commit f38ab5d
Show file tree
Hide file tree
Showing 14 changed files with 206 additions and 659 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
/test/output-webkit
/test/test-user-data-dir*
/.local-chromium/
/.local-browser/
/.local-firefox/
/.local-webkit/
/.dev_profile*
.DS_Store
Expand Down
79 changes: 19 additions & 60 deletions src/webkit/BrowserFetcher.ts → src/browserFetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,12 @@
import * as extract from 'extract-zip';
import * as fs from 'fs';
import * as ProxyAgent from 'https-proxy-agent';
import * as os from 'os';
import * as path from 'path';
// @ts-ignore
import { getProxyForUrl } from 'proxy-from-env';
import * as removeRecursive from 'rimraf';
import * as URL from 'url';
import * as util from 'util';
import { assert, helper } from '../helper';
import {execSync} from 'child_process';

const DEFAULT_DOWNLOAD_HOST = 'https://playwrightaccount.blob.core.windows.net';

const supportedPlatforms = ['linux', 'mac'];
const downloadURLs = {
linux: '%s/builds/webkit/%s/minibrowser-linux.zip',
mac: '%s/builds/webkit/%s/minibrowser-mac-%s.zip',
};
let cachedMacVersion = undefined;
function getMacVersion() {
if (!cachedMacVersion) {
const [major, minor] = execSync('sw_vers -productVersion').toString('utf8').trim().split('.');
cachedMacVersion = major + '.' + minor;
}
return cachedMacVersion;
}

function downloadURL(platform: string, host: string, revision: string): string {
if (platform === 'mac')
return util.format(downloadURLs['mac'], host, revision, getMacVersion());
return util.format(downloadURLs[platform], host, revision);
}
import { assert, helper } from './helper';

const readdirAsync = helper.promisify(fs.readdir.bind(fs));
const mkdirAsync = helper.promisify(fs.mkdir.bind(fs));
Expand All @@ -61,34 +37,23 @@ function existsAsync(filePath) {
return promise;
}

type ParamsGetter = (platform: string, revision: string) => { downloadUrl: string, executablePath: string };

export type OnProgressCallback = (downloadedBytes: number, totalBytes: number) => void;

export class BrowserFetcher {
private _downloadsFolder: string;
private _downloadHost: string;
private _platform: string;
private _params: ParamsGetter;

constructor(projectRoot: string, options: BrowserFetcherOptions = {}) {
this._downloadsFolder = options.path || path.join(projectRoot, '.local-webkit');
this._downloadHost = options.host || DEFAULT_DOWNLOAD_HOST;
this._platform = options.platform || '';
if (!this._platform) {
const platform = os.platform();
if (platform === 'darwin')
this._platform = 'mac';
else if (platform === 'linux')
this._platform = 'linux';
else if (platform === 'win32')
this._platform = 'linux'; // Windows gets linux binaries and uses WSL
assert(this._platform, 'Unsupported platform: ' + os.platform());
}
assert(supportedPlatforms.includes(this._platform), 'Unsupported platform: ' + this._platform);
}

platform(): string {
return this._platform;
constructor(downloadsFolder: string, platform: string, params: ParamsGetter) {
this._downloadsFolder = downloadsFolder;
this._platform = platform;
this._params = params;
}

canDownload(revision: string): Promise<boolean> {
const url = downloadURL(this._platform, this._downloadHost, revision);
const url = this._params(this._platform, revision).downloadUrl;
let resolve;
const promise = new Promise<boolean>(x => resolve = x);
const request = httpRequest(url, 'HEAD', response => {
Expand All @@ -100,8 +65,9 @@ export class BrowserFetcher {
});
return promise;
}
async download(revision: string, progressCallback: ((arg0: number, arg1: number) => void) | null): Promise<BrowserFetcherRevisionInfo> {
const url = downloadURL(this._platform, this._downloadHost, revision);

async download(revision: string, progressCallback: OnProgressCallback | null): Promise<BrowserFetcherRevisionInfo> {
const url = this._params(this._platform, revision).downloadUrl;
const zipPath = path.join(this._downloadsFolder, `download-${this._platform}-${revision}.zip`);
const folderPath = this._getFolderPath(revision);
if (await existsAsync(folderPath))
Expand Down Expand Up @@ -136,14 +102,9 @@ export class BrowserFetcher {

revisionInfo(revision: string): BrowserFetcherRevisionInfo {
const folderPath = this._getFolderPath(revision);
let executablePath = '';
if (this._platform === 'linux' || this._platform === 'mac')
executablePath = path.join(folderPath, 'pw_run.sh');
else
throw new Error('Unsupported platform: ' + this._platform);
const url = downloadURL(this._platform, this._downloadHost, revision);
const params = this._params(this._platform, revision);
const local = fs.existsSync(folderPath);
return {revision, executablePath, folderPath, local, url};
return {revision, executablePath: path.join(folderPath, params.executablePath), folderPath, local, url: params.downloadUrl};
}

_getFolderPath(revision: string): string {
Expand All @@ -157,12 +118,10 @@ function parseFolderPath(folderPath: string): { platform: string; revision: stri
if (splits.length !== 2)
return null;
const [platform, revision] = splits;
if (!supportedPlatforms.includes(platform))
return null;
return {platform, revision};
}

function downloadFile(url: string, destinationPath: string, progressCallback: ((arg0: number, arg1: number) => void) | null): Promise<any> {
function downloadFile(url: string, destinationPath: string, progressCallback: OnProgressCallback | null): Promise<any> {
let fulfill, reject;
let downloadedBytes = 0;
let totalBytes = 0;
Expand Down Expand Up @@ -244,7 +203,7 @@ export type BrowserFetcherOptions = {
host ?: string,
};

type BrowserFetcherRevisionInfo = {
export type BrowserFetcherRevisionInfo = {
folderPath: string,
executablePath: string,
url: string,
Expand Down
Loading

0 comments on commit f38ab5d

Please sign in to comment.