feat: add executablePath to InstalledBrowser (#10594)

This commit is contained in:
Alex Rudenko 2023-07-20 10:53:15 +02:00 committed by GitHub
parent 5a411ca629
commit 87522e778a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 134 additions and 59 deletions

View File

@ -8,15 +8,17 @@ sidebar_label: install
```typescript
export declare function install(
options: InstallOptions
options: InstallOptions & {
unpack?: true;
}
): Promise<InstalledBrowser>;
```
## Parameters
| Parameter | Type | Description |
| --------- | ---------------------------------------------- | ----------- |
| options | [InstallOptions](./browsers.installoptions.md) | |
| Parameter | Type | Description |
| --------- | ----------------------------------------------------------------------- | ----------- |
| options | [InstallOptions](./browsers.installoptions.md) &amp; { unpack?: true; } | |
**Returns:**

View File

@ -0,0 +1,25 @@
---
sidebar_label: install_1
---
# install() function
#### Signature:
```typescript
export declare function install(
options: InstallOptions & {
unpack: false;
}
): Promise<string>;
```
## Parameters
| Parameter | Type | Description |
| --------- | ----------------------------------------------------------------------- | ----------- |
| options | [InstallOptions](./browsers.installoptions.md) &amp; { unpack: false; } | |
**Returns:**
Promise&lt;string&gt;

View File

@ -2,19 +2,24 @@
sidebar_label: InstalledBrowser
---
# InstalledBrowser interface
# InstalledBrowser class
#### Signature:
```typescript
export interface InstalledBrowser
export declare class InstalledBrowser
```
## Remarks
The constructor for this class is marked as internal. Third-party code should not call the constructor directly or create subclasses that extend the `InstalledBrowser` class.
## Properties
| Property | Modifiers | Type | Description | Default |
| -------- | --------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| browser | | [Browser](./browsers.browser.md) | | |
| buildId | | string | | |
| path | | string | Path to the root of the installation folder. Use [computeExecutablePath()](./browsers.computeexecutablepath.md) to get the path to the executable binary. | |
| platform | | [BrowserPlatform](./browsers.browserplatform.md) | | |
| Property | Modifiers | Type | Description |
| -------------- | --------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| browser | | [Browser](./browsers.browser.md) | |
| buildId | | string | |
| executablePath | <code>readonly</code> | string | |
| path | <code>readonly</code> | string | Path to the root of the installation folder. Use [computeExecutablePath()](./browsers.computeexecutablepath.md) to get the path to the executable binary. |
| platform | | [BrowserPlatform](./browsers.browserplatform.md) | |

View File

@ -33,11 +33,12 @@ The programmatic API allows installing and launching browsers from your code. Se
## Classes
| Class | Description |
| ------------------------------------------ | ----------- |
| [CLI](./browsers.cli.md) | |
| [Process](./browsers.process.md) | |
| [TimeoutError](./browsers.timeouterror.md) | |
| Class | Description |
| -------------------------------------------------- | ----------- |
| [CLI](./browsers.cli.md) | |
| [InstalledBrowser](./browsers.installedbrowser.md) | |
| [Process](./browsers.process.md) | |
| [TimeoutError](./browsers.timeouterror.md) | |
## Enumerations
@ -58,6 +59,7 @@ The programmatic API allows installing and launching browsers from your code. Se
| [detectBrowserPlatform()](./browsers.detectbrowserplatform.md) | |
| [getInstalledBrowsers(options)](./browsers.getinstalledbrowsers.md) | Returns metadata about browsers installed in the cache directory. |
| [install(options)](./browsers.install.md) | |
| [install(options)](./browsers.install_1.md) | |
| [launch(opts)](./browsers.launch.md) | |
| [makeProgressCallback(browser, buildId)](./browsers.makeprogresscallback.md) | |
| [resolveBuildId(browser, platform, tag)](./browsers.resolvebuildid.md) | |
@ -68,7 +70,6 @@ The programmatic API allows installing and launching browsers from your code. Se
| Interface | Description |
| ------------------------------------------------------------------------ | ----------- |
| [GetInstalledBrowsersOptions](./browsers.getinstalledbrowsersoptions.md) | |
| [InstalledBrowser](./browsers.installedbrowser.md) | |
| [InstallOptions](./browsers.installoptions.md) | |
| [LaunchOptions](./browsers.launchoptions.md) | |
| [Options](./browsers.options.md) | |

View File

@ -18,19 +18,53 @@ import fs from 'fs';
import path from 'path';
import {Browser, BrowserPlatform} from './browser-data/browser-data.js';
import {computeExecutablePath} from './launch.js';
/**
* @public
*/
export interface InstalledBrowser {
export class InstalledBrowser {
browser: Browser;
buildId: string;
platform: BrowserPlatform;
#cache: Cache;
/**
* @internal
*/
constructor(
cache: Cache,
browser: Browser,
buildId: string,
platform: BrowserPlatform
) {
this.#cache = cache;
this.browser = browser;
this.buildId = buildId;
this.platform = platform;
}
/**
* Path to the root of the installation folder. Use
* {@link computeExecutablePath} to get the path to the executable binary.
*/
path: string;
browser: Browser;
buildId: string;
platform: BrowserPlatform;
get path(): string {
return this.#cache.installationDir(
this.browser,
this.platform,
this.buildId
);
}
get executablePath(): string {
return computeExecutablePath({
cacheDir: this.#cache.rootDir,
platform: this.platform,
browser: this.browser,
buildId: this.buildId,
});
}
}
/**
@ -54,6 +88,13 @@ export class Cache {
this.#rootDir = rootDir;
}
/**
* @internal
*/
get rootDir(): string {
return this.#rootDir;
}
browserRoot(browser: Browser): string {
return path.join(this.#rootDir, browser);
}
@ -106,14 +147,14 @@ export class Cache {
if (!result) {
return null;
}
return {
path: path.join(this.browserRoot(browser), file),
return new InstalledBrowser(
this,
browser,
platform: result.platform,
buildId: result.buildId,
};
result.buildId,
result.platform as BrowserPlatform
);
})
.filter((item): item is InstalledBrowser => {
.filter((item: InstalledBrowser | null): item is InstalledBrowser => {
return item !== null;
});
});

View File

@ -100,9 +100,15 @@ export interface InstallOptions {
/**
* @public
*/
export function install(
options: InstallOptions & {unpack?: true}
): Promise<InstalledBrowser>;
export function install(
options: InstallOptions & {unpack: false}
): Promise<string>;
export async function install(
options: InstallOptions
): Promise<InstalledBrowser> {
): Promise<InstalledBrowser | string> {
options.platform ??= detectBrowserPlatform();
options.unpack ??= true;
if (!options.platform) {
@ -118,8 +124,8 @@ export async function install(
);
const fileName = url.toString().split('/').pop();
assert(fileName, `A malformed download URL was found: ${url}.`);
const structure = new Cache(options.cacheDir);
const browserRoot = structure.browserRoot(options.browser);
const cache = new Cache(options.cacheDir);
const browserRoot = cache.browserRoot(options.browser);
const archivePath = path.join(browserRoot, fileName);
if (!existsSync(browserRoot)) {
await mkdir(browserRoot, {recursive: true});
@ -127,37 +133,27 @@ export async function install(
if (!options.unpack) {
if (existsSync(archivePath)) {
return {
path: archivePath,
browser: options.browser,
platform: options.platform,
buildId: options.buildId,
};
return archivePath;
}
debugInstall(`Downloading binary from ${url}`);
debugTime('download');
await downloadFile(url, archivePath, options.downloadProgressCallback);
debugTimeEnd('download');
return {
path: archivePath,
browser: options.browser,
platform: options.platform,
buildId: options.buildId,
};
return archivePath;
}
const outputPath = structure.installationDir(
const outputPath = cache.installationDir(
options.browser,
options.platform,
options.buildId
);
if (existsSync(outputPath)) {
return {
path: outputPath,
browser: options.browser,
platform: options.platform,
buildId: options.buildId,
};
return new InstalledBrowser(
cache,
options.browser,
options.buildId,
options.platform
);
}
try {
debugInstall(`Downloading binary from ${url}`);
@ -180,12 +176,12 @@ export async function install(
await unlink(archivePath);
}
}
return {
path: outputPath,
browser: options.browser,
platform: options.platform,
buildId: options.buildId,
};
return new InstalledBrowser(
cache,
options.browser,
options.buildId,
options.platform
);
}
/**

View File

@ -104,6 +104,10 @@ describe('Chrome install', () => {
const cache = new Cache(tmpDir);
const installed = cache.getInstalledBrowsers();
assert.deepStrictEqual(browser, installed[0]);
assert.deepStrictEqual(
browser!.executablePath,
installed[0]?.executablePath
);
});
it('throws on invalid URL', async function () {

View File

@ -98,5 +98,6 @@ describe('ChromeDriver install', () => {
});
assert.strictEqual(browser.path, expectedOutputPath);
assert.ok(fs.existsSync(expectedOutputPath));
assert.ok(fs.existsSync(browser.executablePath));
});
});

View File

@ -59,7 +59,7 @@ for (const version of Object.keys(versions)) {
continue;
}
const result = await install({
const archivePath = await install({
browser,
buildId,
platform,
@ -70,7 +70,7 @@ for (const version of Object.keys(versions)) {
fs.mkdirSync(path.dirname(targetPath), {
recursive: true,
});
fs.copyFileSync(result.path, targetPath);
fs.copyFileSync(archivePath, targetPath);
}
}