chore: enable ESRP CDN
This commit is contained in:
parent
a6b6b243d0
commit
98bcf84bc6
|
|
@ -149,12 +149,8 @@ program
|
|||
const version = executable.browserVersion ? `version ` + executable.browserVersion : '';
|
||||
console.log(`browser: ${executable.name}${version ? ' ' + version : ''}`);
|
||||
console.log(` Install location: ${executable.directory ?? '<system>'}`);
|
||||
if (executable.downloadURLs?.length) {
|
||||
const [url, ...fallbacks] = executable.downloadURLs;
|
||||
console.log(` Download url: ${url}`);
|
||||
for (let i = 0; i < fallbacks.length; ++i)
|
||||
console.log(` Download fallback ${i + 1}: ${fallbacks[i]}`);
|
||||
}
|
||||
if (executable.downloadURL)
|
||||
console.log(` Download url: ${executable.downloadURL}`);
|
||||
console.log(``);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ import { browserDirectoryToMarkerFilePath } from '.';
|
|||
import { getUserAgent } from '../../utils/userAgent';
|
||||
import type { DownloadParams } from './oopDownloadBrowserMain';
|
||||
|
||||
export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string | undefined, downloadURLs: string[], downloadFileName: string, downloadConnectionTimeout: number): Promise<boolean> {
|
||||
export async function downloadBrowserWithProgressBar(title: string, browserDirectory: string, executablePath: string | undefined, downloadURLs: string, downloadFileName: string, downloadConnectionTimeout: number): Promise<boolean> {
|
||||
if (await existsAsync(browserDirectoryToMarkerFilePath(browserDirectory))) {
|
||||
// Already downloaded.
|
||||
debugLogger.log('install', `${title} is already downloaded.`);
|
||||
|
|
@ -39,9 +39,8 @@ export async function downloadBrowserWithProgressBar(title: string, browserDirec
|
|||
const retryCount = 3;
|
||||
for (let attempt = 1; attempt <= retryCount; ++attempt) {
|
||||
debugLogger.log('install', `downloading ${title} - attempt #${attempt}`);
|
||||
const url = downloadURLs[(attempt - 1) % downloadURLs.length];
|
||||
logPolitely(`Downloading ${title}` + colors.dim(` from ${url}`));
|
||||
const { error } = await downloadBrowserWithProgressBarOutOfProcess(title, browserDirectory, url, zipPath, executablePath, downloadConnectionTimeout);
|
||||
logPolitely(`Downloading ${title}` + colors.dim(` from ${downloadURLs}`));
|
||||
const { error } = await downloadBrowserWithProgressBarOutOfProcess(title, browserDirectory, downloadURLs, zipPath, executablePath, downloadConnectionTimeout);
|
||||
if (!error) {
|
||||
debugLogger.log('install', `SUCCESS installing ${title}`);
|
||||
break;
|
||||
|
|
@ -96,6 +95,7 @@ function downloadBrowserWithProgressBarOutOfProcess(title: string, browserDirect
|
|||
promise.resolve({ error });
|
||||
});
|
||||
|
||||
|
||||
debugLogger.log('install', `running download:`);
|
||||
debugLogger.log('install', `-- from url: ${url}`);
|
||||
debugLogger.log('install', `-- to location: ${zipPath}`);
|
||||
|
|
|
|||
|
|
@ -36,19 +36,7 @@ import { debugLogger } from '../../utils/debugLogger';
|
|||
const PACKAGE_PATH = path.join(__dirname, '..', '..', '..');
|
||||
const BIN_PATH = path.join(__dirname, '..', '..', '..', 'bin');
|
||||
|
||||
const PLAYWRIGHT_CDN_MIRRORS = [
|
||||
'https://playwright.azureedge.net',
|
||||
'https://playwright-akamai.azureedge.net',
|
||||
'https://playwright-verizon.azureedge.net',
|
||||
];
|
||||
|
||||
if (process.env.PW_TEST_CDN_THAT_SHOULD_WORK) {
|
||||
for (let i = 0; i < PLAYWRIGHT_CDN_MIRRORS.length; i++) {
|
||||
const cdn = PLAYWRIGHT_CDN_MIRRORS[i];
|
||||
if (cdn !== process.env.PW_TEST_CDN_THAT_SHOULD_WORK)
|
||||
PLAYWRIGHT_CDN_MIRRORS[i] = cdn + '.does-not-resolve.playwright.dev';
|
||||
}
|
||||
}
|
||||
const PLAYWRIGHT_CDN_MIRROR = 'https://playwright.azureedge.net';
|
||||
|
||||
const EXECUTABLE_PATHS = {
|
||||
'chromium': {
|
||||
|
|
@ -360,7 +348,7 @@ export interface Executable {
|
|||
browserName: BrowserName | undefined;
|
||||
installType: 'download-by-default' | 'download-on-demand' | 'install-script' | 'none';
|
||||
directory: string | undefined;
|
||||
downloadURLs?: string[],
|
||||
downloadURL?: string,
|
||||
browserVersion?: string,
|
||||
executablePathOrDie(sdkLanguage: string): string;
|
||||
executablePath(sdkLanguage: string): string | undefined;
|
||||
|
|
@ -428,7 +416,7 @@ export class Registry {
|
|||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('chromium', chromiumExecutable, chromium.installByDefault, sdkLanguage),
|
||||
installType: chromium.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, 'chromium', chromium.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||
downloadURLs: this._downloadURLs(chromium),
|
||||
downloadURL: this._downloadURL(chromium),
|
||||
browserVersion: chromium.browserVersion,
|
||||
_install: () => this._downloadExecutable(chromium, chromiumExecutable),
|
||||
_dependencyGroup: 'chromium',
|
||||
|
|
@ -446,7 +434,7 @@ export class Registry {
|
|||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('chromium-tip-of-tree', chromiumTipOfTreeExecutable, chromiumTipOfTree.installByDefault, sdkLanguage),
|
||||
installType: chromiumTipOfTree.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, 'chromium', chromiumTipOfTree.dir, ['chrome-linux'], [], ['chrome-win']),
|
||||
downloadURLs: this._downloadURLs(chromiumTipOfTree),
|
||||
downloadURL: this._downloadURL(chromiumTipOfTree),
|
||||
browserVersion: chromiumTipOfTree.browserVersion,
|
||||
_install: () => this._downloadExecutable(chromiumTipOfTree, chromiumTipOfTreeExecutable),
|
||||
_dependencyGroup: 'chromium',
|
||||
|
|
@ -532,7 +520,7 @@ export class Registry {
|
|||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('firefox', firefoxExecutable, firefox.installByDefault, sdkLanguage),
|
||||
installType: firefox.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, 'firefox', firefox.dir, ['firefox'], [], ['firefox']),
|
||||
downloadURLs: this._downloadURLs(firefox),
|
||||
downloadURL: this._downloadURL(firefox),
|
||||
browserVersion: firefox.browserVersion,
|
||||
_install: () => this._downloadExecutable(firefox, firefoxExecutable),
|
||||
_dependencyGroup: 'firefox',
|
||||
|
|
@ -550,7 +538,7 @@ export class Registry {
|
|||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('firefox-beta', firefoxBetaExecutable, firefoxBeta.installByDefault, sdkLanguage),
|
||||
installType: firefoxBeta.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, 'firefox', firefoxBeta.dir, ['firefox'], [], ['firefox']),
|
||||
downloadURLs: this._downloadURLs(firefoxBeta),
|
||||
downloadURL: this._downloadURL(firefoxBeta),
|
||||
browserVersion: firefoxBeta.browserVersion,
|
||||
_install: () => this._downloadExecutable(firefoxBeta, firefoxBetaExecutable),
|
||||
_dependencyGroup: 'firefox',
|
||||
|
|
@ -578,7 +566,7 @@ export class Registry {
|
|||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('webkit', webkitExecutable, webkit.installByDefault, sdkLanguage),
|
||||
installType: webkit.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||
_validateHostRequirements: (sdkLanguage: string) => this._validateHostRequirements(sdkLanguage, 'webkit', webkit.dir, webkitLinuxLddDirectories, ['libGLESv2.so.2', 'libx264.so'], ['']),
|
||||
downloadURLs: this._downloadURLs(webkit),
|
||||
downloadURL: this._downloadURL(webkit),
|
||||
browserVersion: webkit.browserVersion,
|
||||
_install: () => this._downloadExecutable(webkit, webkitExecutable),
|
||||
_dependencyGroup: 'webkit',
|
||||
|
|
@ -596,7 +584,7 @@ export class Registry {
|
|||
executablePathOrDie: (sdkLanguage: string) => executablePathOrDie('ffmpeg', ffmpegExecutable, ffmpeg.installByDefault, sdkLanguage),
|
||||
installType: ffmpeg.installByDefault ? 'download-by-default' : 'download-on-demand',
|
||||
_validateHostRequirements: () => Promise.resolve(),
|
||||
downloadURLs: this._downloadURLs(ffmpeg),
|
||||
downloadURL: this._downloadURL(ffmpeg),
|
||||
_install: () => this._downloadExecutable(ffmpeg, ffmpegExecutable),
|
||||
_dependencyGroup: 'tools',
|
||||
_isHermeticInstallation: true,
|
||||
|
|
@ -611,7 +599,7 @@ export class Registry {
|
|||
executablePathOrDie: () => '',
|
||||
installType: 'download-on-demand',
|
||||
_validateHostRequirements: () => Promise.resolve(),
|
||||
downloadURLs: this._downloadURLs(android),
|
||||
downloadURL: this._downloadURL(android),
|
||||
_install: () => this._downloadExecutable(android),
|
||||
_dependencyGroup: 'tools',
|
||||
_isHermeticInstallation: true,
|
||||
|
|
@ -828,14 +816,14 @@ export class Registry {
|
|||
await fs.promises.writeFile(markerFile, '').catch(() => {});
|
||||
}
|
||||
|
||||
private _downloadURLs(descriptor: BrowsersJSONDescriptor): string[] {
|
||||
private _downloadURL(descriptor: BrowsersJSONDescriptor): string | undefined {
|
||||
const paths = (DOWNLOAD_PATHS as any)[descriptor.name];
|
||||
const downloadPathTemplate: string|undefined = paths[hostPlatform] || paths['<unknown>'];
|
||||
if (!downloadPathTemplate)
|
||||
return [];
|
||||
return undefined;
|
||||
const downloadPath = util.format(downloadPathTemplate, descriptor.revision);
|
||||
|
||||
let downloadURLs = PLAYWRIGHT_CDN_MIRRORS.map(mirror => `${mirror}/${downloadPath}`) ;
|
||||
let downloadURL = `${PLAYWRIGHT_CDN_MIRROR}/download/playwright/${downloadPath}`;
|
||||
let downloadHostEnv;
|
||||
if (descriptor.name.startsWith('chromium'))
|
||||
downloadHostEnv = 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST';
|
||||
|
|
@ -846,13 +834,13 @@ export class Registry {
|
|||
|
||||
const customHostOverride = (downloadHostEnv && getFromENV(downloadHostEnv)) || getFromENV('PLAYWRIGHT_DOWNLOAD_HOST');
|
||||
if (customHostOverride)
|
||||
downloadURLs = [`${customHostOverride}/${downloadPath}`];
|
||||
return downloadURLs;
|
||||
downloadURL = `${customHostOverride}/${downloadPath}`;
|
||||
return downloadURL;
|
||||
}
|
||||
|
||||
private async _downloadExecutable(descriptor: BrowsersJSONDescriptor, executablePath?: string) {
|
||||
const downloadURLs = this._downloadURLs(descriptor);
|
||||
if (!downloadURLs.length)
|
||||
const downloadURL = this._downloadURL(descriptor);
|
||||
if (!downloadURL)
|
||||
throw new Error(`ERROR: Playwright does not support ${descriptor.name} on ${hostPlatform}`);
|
||||
if (!isOfficiallySupportedPlatform)
|
||||
logPolitely(`BEWARE: your OS is not officially supported by Playwright; downloading fallback build for ${hostPlatform}.`);
|
||||
|
|
@ -867,7 +855,7 @@ export class Registry {
|
|||
const downloadFileName = `playwright-download-${descriptor.name}-${hostPlatform}-${descriptor.revision}.zip`;
|
||||
const downloadConnectionTimeoutEnv = getFromENV('PLAYWRIGHT_DOWNLOAD_CONNECTION_TIMEOUT');
|
||||
const downloadConnectionTimeout = +(downloadConnectionTimeoutEnv || '0') || 30_000;
|
||||
await downloadBrowserWithProgressBar(title, descriptor.dir, executablePath, downloadURLs, downloadFileName, downloadConnectionTimeout).catch(e => {
|
||||
await downloadBrowserWithProgressBar(title, descriptor.dir, executablePath, downloadURL, downloadFileName, downloadConnectionTimeout).catch(e => {
|
||||
throw new Error(`Failed to download ${title}, caused by\n${e.stack}`);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,39 +18,8 @@ import http from 'http';
|
|||
import net from 'net';
|
||||
import type { AddressInfo } from 'net';
|
||||
|
||||
const CDNS = [
|
||||
'https://playwright.azureedge.net',
|
||||
'https://playwright-akamai.azureedge.net',
|
||||
'https://playwright-verizon.azureedge.net',
|
||||
];
|
||||
|
||||
const DL_STAT_BLOCK = /^.*from url: (.*)$\n^.*to location: (.*)$\n^.*response status code: (.*)$\n^.*total bytes: (\d+)$\n^.*download complete, size: (\d+)$\n^.*SUCCESS downloading (\w+) .*$/gm;
|
||||
|
||||
const parsedDownloads = (rawLogs: string) => {
|
||||
const out: { url: string, status: number, name: string }[] = [];
|
||||
for (const match of rawLogs.matchAll(DL_STAT_BLOCK)) {
|
||||
const [, url, /* filepath */, status, /* size */, /* receivedBytes */, name] = match;
|
||||
out.push({ url, status: Number.parseInt(status, 10), name: name.toLocaleLowerCase() });
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
test.use({ isolateBrowsers: true });
|
||||
|
||||
for (const cdn of CDNS) {
|
||||
test(`playwright cdn failover should work (${cdn})`, async ({ exec, installedSoftwareOnDisk }) => {
|
||||
await exec('npm i playwright');
|
||||
const result = await exec('npx playwright install', { env: { PW_TEST_CDN_THAT_SHOULD_WORK: cdn, DEBUG: 'pw:install' } });
|
||||
expect(result).toHaveLoggedSoftwareDownload(['chromium', 'ffmpeg', 'firefox', 'webkit']);
|
||||
expect(await installedSoftwareOnDisk()).toEqual(['chromium', 'ffmpeg', 'firefox', 'webkit']);
|
||||
const dls = parsedDownloads(result);
|
||||
for (const software of ['chromium', 'ffmpeg', 'firefox', 'webkit'])
|
||||
expect(dls).toContainEqual({ status: 200, name: software, url: expect.stringContaining(cdn) });
|
||||
await exec('node sanity.js playwright chromium firefox webkit');
|
||||
await exec('node esm-playwright.mjs');
|
||||
});
|
||||
}
|
||||
|
||||
test(`playwright cdn should race with a timeout`, async ({ exec }) => {
|
||||
const server = http.createServer(() => {});
|
||||
await new Promise<void>(resolve => server.listen(0, resolve));
|
||||
|
|
|
|||
Loading…
Reference in a new issue