browser-data.ts (7905B)
1 /** 2 * @license 3 * Copyright 2023 Google Inc. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 import * as chromeHeadlessShell from './chrome-headless-shell.js'; 8 import * as chrome from './chrome.js'; 9 import * as chromedriver from './chromedriver.js'; 10 import * as chromium from './chromium.js'; 11 import * as firefox from './firefox.js'; 12 import { 13 Browser, 14 BrowserPlatform, 15 BrowserTag, 16 ChromeReleaseChannel, 17 type ProfileOptions, 18 } from './types.js'; 19 20 export type {ProfileOptions}; 21 22 export const downloadUrls = { 23 [Browser.CHROMEDRIVER]: chromedriver.resolveDownloadUrl, 24 [Browser.CHROMEHEADLESSSHELL]: chromeHeadlessShell.resolveDownloadUrl, 25 [Browser.CHROME]: chrome.resolveDownloadUrl, 26 [Browser.CHROMIUM]: chromium.resolveDownloadUrl, 27 [Browser.FIREFOX]: firefox.resolveDownloadUrl, 28 }; 29 30 export const downloadPaths = { 31 [Browser.CHROMEDRIVER]: chromedriver.resolveDownloadPath, 32 [Browser.CHROMEHEADLESSSHELL]: chromeHeadlessShell.resolveDownloadPath, 33 [Browser.CHROME]: chrome.resolveDownloadPath, 34 [Browser.CHROMIUM]: chromium.resolveDownloadPath, 35 [Browser.FIREFOX]: firefox.resolveDownloadPath, 36 }; 37 38 export const executablePathByBrowser = { 39 [Browser.CHROMEDRIVER]: chromedriver.relativeExecutablePath, 40 [Browser.CHROMEHEADLESSSHELL]: chromeHeadlessShell.relativeExecutablePath, 41 [Browser.CHROME]: chrome.relativeExecutablePath, 42 [Browser.CHROMIUM]: chromium.relativeExecutablePath, 43 [Browser.FIREFOX]: firefox.relativeExecutablePath, 44 }; 45 46 export const versionComparators = { 47 [Browser.CHROMEDRIVER]: chromedriver.compareVersions, 48 [Browser.CHROMEHEADLESSSHELL]: chromeHeadlessShell.compareVersions, 49 [Browser.CHROME]: chrome.compareVersions, 50 [Browser.CHROMIUM]: chromium.compareVersions, 51 [Browser.FIREFOX]: firefox.compareVersions, 52 }; 53 54 export {Browser, BrowserPlatform, ChromeReleaseChannel}; 55 56 /** 57 * @internal 58 */ 59 async function resolveBuildIdForBrowserTag( 60 browser: Browser, 61 platform: BrowserPlatform, 62 tag: BrowserTag, 63 ): Promise<string> { 64 switch (browser) { 65 case Browser.FIREFOX: 66 switch (tag) { 67 case BrowserTag.LATEST: 68 return await firefox.resolveBuildId(firefox.FirefoxChannel.NIGHTLY); 69 case BrowserTag.BETA: 70 return await firefox.resolveBuildId(firefox.FirefoxChannel.BETA); 71 case BrowserTag.NIGHTLY: 72 return await firefox.resolveBuildId(firefox.FirefoxChannel.NIGHTLY); 73 case BrowserTag.DEVEDITION: 74 return await firefox.resolveBuildId( 75 firefox.FirefoxChannel.DEVEDITION, 76 ); 77 case BrowserTag.STABLE: 78 return await firefox.resolveBuildId(firefox.FirefoxChannel.STABLE); 79 case BrowserTag.ESR: 80 return await firefox.resolveBuildId(firefox.FirefoxChannel.ESR); 81 case BrowserTag.CANARY: 82 case BrowserTag.DEV: 83 throw new Error(`${tag.toUpperCase()} is not available for Firefox`); 84 } 85 case Browser.CHROME: { 86 switch (tag) { 87 case BrowserTag.LATEST: 88 return await chrome.resolveBuildId(ChromeReleaseChannel.CANARY); 89 case BrowserTag.BETA: 90 return await chrome.resolveBuildId(ChromeReleaseChannel.BETA); 91 case BrowserTag.CANARY: 92 return await chrome.resolveBuildId(ChromeReleaseChannel.CANARY); 93 case BrowserTag.DEV: 94 return await chrome.resolveBuildId(ChromeReleaseChannel.DEV); 95 case BrowserTag.STABLE: 96 return await chrome.resolveBuildId(ChromeReleaseChannel.STABLE); 97 case BrowserTag.NIGHTLY: 98 case BrowserTag.DEVEDITION: 99 case BrowserTag.ESR: 100 throw new Error(`${tag.toUpperCase()} is not available for Chrome`); 101 } 102 } 103 case Browser.CHROMEDRIVER: { 104 switch (tag) { 105 case BrowserTag.LATEST: 106 case BrowserTag.CANARY: 107 return await chromedriver.resolveBuildId(ChromeReleaseChannel.CANARY); 108 case BrowserTag.BETA: 109 return await chromedriver.resolveBuildId(ChromeReleaseChannel.BETA); 110 case BrowserTag.DEV: 111 return await chromedriver.resolveBuildId(ChromeReleaseChannel.DEV); 112 case BrowserTag.STABLE: 113 return await chromedriver.resolveBuildId(ChromeReleaseChannel.STABLE); 114 case BrowserTag.NIGHTLY: 115 case BrowserTag.DEVEDITION: 116 case BrowserTag.ESR: 117 throw new Error( 118 `${tag.toUpperCase()} is not available for ChromeDriver`, 119 ); 120 } 121 } 122 case Browser.CHROMEHEADLESSSHELL: { 123 switch (tag) { 124 case BrowserTag.LATEST: 125 case BrowserTag.CANARY: 126 return await chromeHeadlessShell.resolveBuildId( 127 ChromeReleaseChannel.CANARY, 128 ); 129 case BrowserTag.BETA: 130 return await chromeHeadlessShell.resolveBuildId( 131 ChromeReleaseChannel.BETA, 132 ); 133 case BrowserTag.DEV: 134 return await chromeHeadlessShell.resolveBuildId( 135 ChromeReleaseChannel.DEV, 136 ); 137 case BrowserTag.STABLE: 138 return await chromeHeadlessShell.resolveBuildId( 139 ChromeReleaseChannel.STABLE, 140 ); 141 case BrowserTag.NIGHTLY: 142 case BrowserTag.DEVEDITION: 143 case BrowserTag.ESR: 144 throw new Error(`${tag} is not available for chrome-headless-shell`); 145 } 146 } 147 case Browser.CHROMIUM: 148 switch (tag) { 149 case BrowserTag.LATEST: 150 return await chromium.resolveBuildId(platform); 151 case BrowserTag.NIGHTLY: 152 case BrowserTag.CANARY: 153 case BrowserTag.DEV: 154 case BrowserTag.DEVEDITION: 155 case BrowserTag.BETA: 156 case BrowserTag.STABLE: 157 case BrowserTag.ESR: 158 throw new Error( 159 `${tag} is not supported for Chromium. Use 'latest' instead.`, 160 ); 161 } 162 } 163 } 164 165 /** 166 * @public 167 */ 168 export async function resolveBuildId( 169 browser: Browser, 170 platform: BrowserPlatform, 171 tag: string | BrowserTag, 172 ): Promise<string> { 173 const browserTag = tag as BrowserTag; 174 if (Object.values(BrowserTag).includes(browserTag)) { 175 return await resolveBuildIdForBrowserTag(browser, platform, browserTag); 176 } 177 178 switch (browser) { 179 case Browser.FIREFOX: 180 return tag; 181 case Browser.CHROME: 182 const chromeResult = await chrome.resolveBuildId(tag); 183 if (chromeResult) { 184 return chromeResult; 185 } 186 return tag; 187 case Browser.CHROMEDRIVER: 188 const chromeDriverResult = await chromedriver.resolveBuildId(tag); 189 if (chromeDriverResult) { 190 return chromeDriverResult; 191 } 192 return tag; 193 case Browser.CHROMEHEADLESSSHELL: 194 const chromeHeadlessShellResult = 195 await chromeHeadlessShell.resolveBuildId(tag); 196 if (chromeHeadlessShellResult) { 197 return chromeHeadlessShellResult; 198 } 199 return tag; 200 case Browser.CHROMIUM: 201 return tag; 202 } 203 } 204 205 /** 206 * @public 207 */ 208 export async function createProfile( 209 browser: Browser, 210 opts: ProfileOptions, 211 ): Promise<void> { 212 switch (browser) { 213 case Browser.FIREFOX: 214 return await firefox.createProfile(opts); 215 case Browser.CHROME: 216 case Browser.CHROMIUM: 217 throw new Error(`Profile creation is not support for ${browser} yet`); 218 } 219 } 220 221 /** 222 * @public 223 */ 224 export function resolveSystemExecutablePath( 225 browser: Browser, 226 platform: BrowserPlatform, 227 channel: ChromeReleaseChannel, 228 ): string { 229 switch (browser) { 230 case Browser.CHROMEDRIVER: 231 case Browser.CHROMEHEADLESSSHELL: 232 case Browser.FIREFOX: 233 case Browser.CHROMIUM: 234 throw new Error( 235 `System browser detection is not supported for ${browser} yet.`, 236 ); 237 case Browser.CHROME: 238 return chrome.resolveSystemExecutablePath(platform, channel); 239 } 240 } 241 242 /** 243 * Returns a version comparator for the given browser that can be used to sort 244 * browser versions. 245 * 246 * @public 247 */ 248 export function getVersionComparator( 249 browser: Browser, 250 ): (a: string, b: string) => number { 251 return versionComparators[browser]; 252 }