From f472c9612921ddf5986c59f939ebe0795855f866 Mon Sep 17 00:00:00 2001 From: Andrey Lushnikov Date: Wed, 31 Mar 2021 13:32:10 -0500 Subject: [PATCH] feat: support webkit technology preview (#5885) This patch adds support for `technology preview` webkit channel, which we will keep close to the actual Safari Technology Preview releases. This channel does not install by default. It is supposed to be installed with the following CLI command: ```sh $ npx playwright install webkit-technology-preview ``` Once the channel is installed, it can be used the following way: ```js const browser = await playwright.webkit.launch({ channel: 'technology-preview', }); ``` **NOTE:** if clients attempt using the channel without installing it, it'll throw an error with a copyable instructions to install via CLI. References #5884 --- browsers.json | 5 +++ src/cli/cli.ts | 5 ++- src/server/validateDependencies.ts | 11 +++--- src/server/webkit/webkit.ts | 14 +++++++ src/utils/registry.ts | 60 ++++++++++++++++++++++-------- 5 files changed, 72 insertions(+), 23 deletions(-) diff --git a/browsers.json b/browsers.json index c239b90ac4..976da08d94 100644 --- a/browsers.json +++ b/browsers.json @@ -19,6 +19,11 @@ "mac10.14": "1443" } }, + { + "name": "webkit-technology-preview", + "revision": "1443", + "installByDefault": false + }, { "name": "ffmpeg", "revision": "1005", diff --git a/src/cli/cli.ts b/src/cli/cli.ts index 66a778b500..c03ba11d78 100755 --- a/src/cli/cli.ts +++ b/src/cli/cli.ts @@ -32,6 +32,7 @@ import { BrowserType } from '../client/browserType'; import { BrowserContextOptions, LaunchOptions } from '../client/types'; import { spawn } from 'child_process'; import { installDeps } from '../install/installDeps'; +import { allBrowserNames } from '../utils/registry'; program .version('Version ' + require('../../package.json').version) @@ -85,10 +86,10 @@ program .description('ensure browsers necessary for this version of Playwright are installed') .action(async function(browserType) { try { - const allBrowsers = new Set(['chromium', 'firefox', 'webkit', 'ffmpeg']); + const allBrowsers = new Set(allBrowserNames); for (const type of browserType) { if (!allBrowsers.has(type)) { - console.log(`Invalid browser name: '${type}'. Expecting 'chromium', 'firefox' or 'webkit'.`); + console.log(`Invalid browser name: '${type}'. Expecting one of: ${allBrowserNames.map(name => `'${name}'`).join(', ')}`); process.exit(1); } } diff --git a/src/server/validateDependencies.ts b/src/server/validateDependencies.ts index 22281d2172..c68d94aa72 100644 --- a/src/server/validateDependencies.ts +++ b/src/server/validateDependencies.ts @@ -43,11 +43,12 @@ export async function validateHostRequirements(registry: registry.Registry, brow } const DL_OPEN_LIBRARIES = { - chromium: [], - webkit: ['libGLESv2.so.2', 'libx264.so'], - firefox: [], - clank: [], - ffmpeg: [], + 'chromium': [], + 'webkit': ['libGLESv2.so.2', 'libx264.so'], + 'webkit-technology-preview': ['libGLESv2.so.2', 'libx264.so'], + 'firefox': [], + 'clank': [], + 'ffmpeg': [], }; function isSupportedWindowsVersion(): boolean { diff --git a/src/server/webkit/webkit.ts b/src/server/webkit/webkit.ts index dbf7bc13f1..1c1660d1a9 100644 --- a/src/server/webkit/webkit.ts +++ b/src/server/webkit/webkit.ts @@ -23,12 +23,26 @@ import { BrowserType } from '../browserType'; import { ConnectionTransport } from '../transport'; import { BrowserOptions, PlaywrightOptions } from '../browser'; import * as types from '../types'; +import * as fs from 'fs'; +import { assert } from '../../utils/utils'; export class WebKit extends BrowserType { constructor(playwrightOptions: PlaywrightOptions) { super('webkit', playwrightOptions); } + executablePath(options?: types.LaunchOptions): string { + if (options?.channel) { + let executablePath = undefined; + if ((options.channel as any) === 'technology-preview') + executablePath = this._registry.executablePath('webkit-technology-preview'); + assert(executablePath, `unsupported webkit channel "${options.channel}"`); + assert(fs.existsSync(executablePath), `webkit channel "${options.channel}" is not installed. Try running 'npx playwright install webkit-technology-preview'`); + return executablePath; + } + return super.executablePath(options); + } + _connectToTransport(transport: ConnectionTransport, options: BrowserOptions): Promise { return WKBrowser.connect(transport, options); } diff --git a/src/utils/registry.ts b/src/utils/registry.ts index 85808780b1..ee796a3438 100644 --- a/src/utils/registry.ts +++ b/src/utils/registry.ts @@ -23,8 +23,8 @@ import * as util from 'util'; import { getUbuntuVersionSync } from './ubuntuVersion'; import { assert, getFromENV } from './utils'; -export type BrowserName = 'chromium'|'webkit'|'firefox'|'ffmpeg'; -export const allBrowserNames: BrowserName[] = ['chromium', 'webkit', 'firefox', 'ffmpeg']; +export type BrowserName = 'chromium'|'webkit'|'firefox'|'ffmpeg'|'webkit-technology-preview'; +export const allBrowserNames: BrowserName[] = ['chromium', 'webkit', 'firefox', 'ffmpeg', 'webkit-technology-preview']; const PACKAGE_PATH = path.join(__dirname, '..', '..'); @@ -37,7 +37,7 @@ type BrowserDescriptor = { }; const EXECUTABLE_PATHS = { - chromium: { + 'chromium': { 'ubuntu18.04': ['chrome-linux', 'chrome'], 'ubuntu20.04': ['chrome-linux', 'chrome'], 'mac10.13': ['chrome-mac', 'Chromium.app', 'Contents', 'MacOS', 'Chromium'], @@ -48,7 +48,7 @@ const EXECUTABLE_PATHS = { 'win32': ['chrome-win', 'chrome.exe'], 'win64': ['chrome-win', 'chrome.exe'], }, - firefox: { + 'firefox': { 'ubuntu18.04': ['firefox', 'firefox'], 'ubuntu20.04': ['firefox', 'firefox'], 'mac10.13': ['firefox', 'Nightly.app', 'Contents', 'MacOS', 'firefox'], @@ -59,7 +59,7 @@ const EXECUTABLE_PATHS = { 'win32': ['firefox', 'firefox.exe'], 'win64': ['firefox', 'firefox.exe'], }, - webkit: { + 'webkit': { 'ubuntu18.04': ['pw_run.sh'], 'ubuntu20.04': ['pw_run.sh'], 'mac10.13': undefined, @@ -70,7 +70,18 @@ const EXECUTABLE_PATHS = { 'win32': ['Playwright.exe'], 'win64': ['Playwright.exe'], }, - ffmpeg: { + 'webkit-technology-preview': { + 'ubuntu18.04': ['pw_run.sh'], + 'ubuntu20.04': ['pw_run.sh'], + 'mac10.13': undefined, + 'mac10.14': ['pw_run.sh'], + 'mac10.15': ['pw_run.sh'], + 'mac11': ['pw_run.sh'], + 'mac11-arm64': ['pw_run.sh'], + 'win32': ['Playwright.exe'], + 'win64': ['Playwright.exe'], + }, + 'ffmpeg': { 'ubuntu18.04': ['ffmpeg-linux'], 'ubuntu20.04': ['ffmpeg-linux'], 'mac10.13': ['ffmpeg-mac'], @@ -84,7 +95,7 @@ const EXECUTABLE_PATHS = { }; const DOWNLOAD_URLS = { - chromium: { + 'chromium': { 'ubuntu18.04': '%s/builds/chromium/%s/chromium-linux.zip', 'ubuntu20.04': '%s/builds/chromium/%s/chromium-linux.zip', 'mac10.13': '%s/builds/chromium/%s/chromium-mac.zip', @@ -95,7 +106,7 @@ const DOWNLOAD_URLS = { 'win32': '%s/builds/chromium/%s/chromium-win32.zip', 'win64': '%s/builds/chromium/%s/chromium-win64.zip', }, - firefox: { + 'firefox': { 'ubuntu18.04': '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip', 'ubuntu20.04': '%s/builds/firefox/%s/firefox-ubuntu-18.04.zip', 'mac10.13': '%s/builds/firefox/%s/firefox-mac-10.14.zip', @@ -106,7 +117,7 @@ const DOWNLOAD_URLS = { 'win32': '%s/builds/firefox/%s/firefox-win32.zip', 'win64': '%s/builds/firefox/%s/firefox-win64.zip', }, - webkit: { + 'webkit': { 'ubuntu18.04': '%s/builds/webkit/%s/webkit-ubuntu-18.04.zip', 'ubuntu20.04': '%s/builds/webkit/%s/webkit-ubuntu-20.04.zip', 'mac10.13': undefined, @@ -117,7 +128,18 @@ const DOWNLOAD_URLS = { 'win32': '%s/builds/webkit/%s/webkit-win64.zip', 'win64': '%s/builds/webkit/%s/webkit-win64.zip', }, - ffmpeg: { + 'webkit-technology-preview': { + 'ubuntu18.04': '%s/builds/webkit/%s/webkit-ubuntu-18.04.zip', + 'ubuntu20.04': '%s/builds/webkit/%s/webkit-ubuntu-20.04.zip', + 'mac10.13': undefined, + 'mac10.14': undefined, + 'mac10.15': '%s/builds/webkit/%s/webkit-mac-10.15.zip', + 'mac11': '%s/builds/webkit/%s/webkit-mac-10.15.zip', + 'mac11-arm64': '%s/builds/webkit/%s/webkit-mac-11.0-arm64.zip', + 'win32': '%s/builds/webkit/%s/webkit-win64.zip', + 'win64': '%s/builds/webkit/%s/webkit-win64.zip', + }, + 'ffmpeg': { 'ubuntu18.04': '%s/builds/ffmpeg/%s/ffmpeg-linux.zip', 'ubuntu20.04': '%s/builds/ffmpeg/%s/ffmpeg-linux.zip', 'mac10.13': '%s/builds/ffmpeg/%s/ffmpeg-mac.zip', @@ -218,12 +240,17 @@ export class Registry { const name = obj.name; const revisionOverride = (obj.revisionOverrides || {})[hostPlatform]; const revision = revisionOverride || obj.revision; - const browserDirectory = revisionOverride ? `${name}-${hostPlatform}-special-${revision}` : `${name}-${revision}`; + const browserDirectoryPrefix = revisionOverride ? `${name}_${hostPlatform}_special` : `${name}`; return { name, revision, installByDefault: !!obj.installByDefault, - browserDirectory, + // Method `isBrowserDirectory` determines directory to be browser iff + // it starts with some browser name followed by '-'. Some browser names + // are prefixes of others, e.g. 'webkit' is a prefix of `webkit-technology-preview`. + // To avoid older registries erroneously removing 'webkit-technology-preview', we have to + // ensure that browser folders to never include dashes inside. + browserDirectory: browserDirectoryPrefix.replace(/-/g, '_') + '-' + revision, }; }); } @@ -280,10 +307,11 @@ export class Registry { const browser = this._descriptors.find(browser => browser.name === browserName); assert(browser, `ERROR: Playwright does not support ${browserName}`); const envDownloadHost: { [key: string]: string } = { - chromium: 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST', - firefox: 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST', - webkit: 'PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST', - ffmpeg: 'PLAYWRIGHT_FFMPEG_DOWNLOAD_HOST', + 'chromium': 'PLAYWRIGHT_CHROMIUM_DOWNLOAD_HOST', + 'firefox': 'PLAYWRIGHT_FIREFOX_DOWNLOAD_HOST', + 'webkit': 'PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST', + 'webkit-technology-preview': 'PLAYWRIGHT_WEBKIT_DOWNLOAD_HOST', + 'ffmpeg': 'PLAYWRIGHT_FFMPEG_DOWNLOAD_HOST', }; const downloadHost = getFromENV(envDownloadHost[browserName]) || getFromENV('PLAYWRIGHT_DOWNLOAD_HOST') ||