diff --git a/packages/browsers/src/Cache.ts b/packages/browsers/src/Cache.ts index 255c5a7b0f5..0cb31b95d0f 100644 --- a/packages/browsers/src/Cache.ts +++ b/packages/browsers/src/Cache.ts @@ -19,6 +19,16 @@ import path from 'path'; import {Browser, BrowserPlatform} from './browser-data/browser-data.js'; +/** + * @public + */ +export type InstalledBrowser = { + path: string; + browser: Browser; + buildId: string; + platform: BrowserPlatform; +}; + /** * The cache used by Puppeteer relies on the following structure: * @@ -65,4 +75,50 @@ export class Cache { retryDelay: 500, }); } + + getInstalledBrowsers(): InstalledBrowser[] { + if (!fs.existsSync(this.#rootDir)) { + return []; + } + const types = fs.readdirSync(this.#rootDir); + const browsers = types.filter((t): t is Browser => { + return (Object.values(Browser) as string[]).includes(t); + }); + return browsers.flatMap(browser => { + const files = fs.readdirSync(this.browserRoot(browser)); + return files + .map(file => { + const result = parseFolderPath( + path.join(this.browserRoot(browser), file) + ); + if (!result) { + return null; + } + return { + path: path.join(this.browserRoot(browser), file), + browser, + platform: result.platform, + buildId: result.buildId, + }; + }) + .filter((item): item is InstalledBrowser => { + return item !== null; + }); + }); + } +} + +function parseFolderPath( + folderPath: string +): {platform: string; buildId: string} | undefined { + const name = path.basename(folderPath); + const splits = name.split('-'); + if (splits.length !== 2) { + return; + } + const [platform, buildId] = splits; + if (!buildId || !platform) { + return; + } + return {platform, buildId}; } diff --git a/packages/browsers/src/install.ts b/packages/browsers/src/install.ts index 92354b41c9b..054e0484202 100644 --- a/packages/browsers/src/install.ts +++ b/packages/browsers/src/install.ts @@ -25,7 +25,7 @@ import { BrowserPlatform, downloadUrls, } from './browser-data/browser-data.js'; -import {Cache} from './Cache.js'; +import {Cache, InstalledBrowser} from './Cache.js'; import {debug} from './debug.js'; import {detectBrowserPlatform} from './detectPlatform.js'; import {unpackArchive} from './fileUtil.js'; @@ -97,16 +97,6 @@ export interface InstallOptions { unpack?: boolean; } -/** - * @public - */ -export type InstalledBrowser = { - path: string; - browser: Browser; - buildId: string; - platform: BrowserPlatform; -}; - /** * @public */ diff --git a/packages/browsers/src/main.ts b/packages/browsers/src/main.ts index 2a16e8dbdbe..14ca6a838a8 100644 --- a/packages/browsers/src/main.ts +++ b/packages/browsers/src/main.ts @@ -26,12 +26,7 @@ export { WEBDRIVER_BIDI_WEBSOCKET_ENDPOINT_REGEX, Process, } from './launch.js'; -export { - install, - canDownload, - InstallOptions, - InstalledBrowser, -} from './install.js'; +export {install, canDownload, InstallOptions} from './install.js'; export {detectBrowserPlatform} from './detectPlatform.js'; export { resolveBuildId, @@ -42,4 +37,4 @@ export { ProfileOptions, } from './browser-data/browser-data.js'; export {CLI, makeProgressCallback} from './CLI.js'; -export {Cache} from './Cache.js'; +export {Cache, InstalledBrowser} from './Cache.js'; diff --git a/packages/browsers/test/src/chrome/install.spec.ts b/packages/browsers/test/src/chrome/install.spec.ts index b150acf1653..8ae8960eafa 100644 --- a/packages/browsers/test/src/chrome/install.spec.ts +++ b/packages/browsers/test/src/chrome/install.spec.ts @@ -100,6 +100,10 @@ describe('Chrome install', () => { }); assert.strictEqual(browser.path, expectedOutputPath); assert.ok(fs.existsSync(expectedOutputPath)); + // Should discover installed browsers. + const cache = new Cache(tmpDir); + const installed = cache.getInstalledBrowsers(); + assert.deepStrictEqual(browser, installed[0]); }); it('throws on invalid URL', async function () {