Skip to content

Commit

Permalink
feat(install): use shared installation folder by default (#2044)
Browse files Browse the repository at this point in the history
  • Loading branch information
pavelfeldman authored Apr 30, 2020
1 parent c55db6d commit 9f62f29
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 42 deletions.
76 changes: 43 additions & 33 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
<!-- GEN:toc -->
- [System requirements](#system-requirements)
- [Managing browser binaries](#managing-browser-binaries)
* [Download from artifact repository](#download-from-artifact-repository)
* [Share browser binaries across projects](#share-browser-binaries-across-projects)
* [Skip browser downloads](#skip-browser-downloads)
- [Download from artifact repository](#download-from-artifact-repository)
- [Skip browser downloads](#skip-browser-downloads)
- [Download single browser binary](#download-single-browser-binary)
<!-- GEN:stop -->

<br>

## System requirements

Playwright requires Node.js version 10.15 or above. The browser binaries for Chromium,
Expand All @@ -21,63 +22,70 @@ Firefox and WebKit work across the 3 platforms (Windows, macOS, Linux):
* For Ubuntu 18.04, the additional dependencies are defined in [our Docker image](docker/Dockerfile.bionic),
which is based on Ubuntu.

<br>

## Managing browser binaries

Each version of Playwright needs specific versions of browser binaries to operate.
Each version of Playwright needs specific versions of browser binaries to operate. By default Playwright downloads Chromium, WebKit and Firefox browsers into the OS-specific cache folders:

By default it downloads Chromium, WebKit and Firefox browsers into the `node_modules/` folder. This way no extra steps are needed to get playwright up and running:
- `HOME\AppData\Local\ms-playwright` on Windows
- `~/Library/Caches/ms-playwright` on MacOS
- `~/.cache/playwright/ms-playwright` on Linux

```sh
npm i playwright
```

These browsers will take hundreds of megabytes of the disk space when installed:
These browsers will take few hundreds of megabytes of the disk space when installed:

```sh
du -hs ./node_modules/playwright/.local-browsers/*
281M .local-browsers/chromium-XXXXXX
187M .local-browsers/firefox-XXXX
180M .local-browsers/webkit-XXXX
du -hs ./Library/Caches/ms-playwright/*
281M chromium-XXXXXX
187M firefox-XXXX
180M webkit-XXXX
```

To mitigate that, Playwright has a rich set of options to control browser management.
You can override default behavior using environment variables. When installing Playwright, ask it to download browsers into a specific location:

### Download from artifact repository
```sh
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers npm i playwright
```

By default, Playwright downloads browsers from Microsoft and Google public CDNs.
When running Playwright scripts, ask it to search for browsers in a shared location:

Sometimes companies maintain an internal artifact repository to host browser
binaries. In this case, Playwright can be configured to download from a custom
location using the `PLAYWRIGHT_DOWNLOAD_HOST` env variable.
```sh
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers node playwright-script.js
```

Or you can opt into the hermetic install and place binaries under the `node_modules/` folder:

```sh
$ PLAYWRIGHT_DOWNLOAD_HOST=192.168.1.78 npm i playwright
$ PLAYWRIGHT_BROWSERS_PATH=0 node playwright-script.js
```

### Share browser binaries across projects
Playwright keeps track of packages that need those browsers and will garbage collect them as you update Playwright to the newer versions.

Often times, developers work with multiple NPM projects that all use Playwright.
By default, every project will have browser binaries in its own `node_modules/` folder.
To save the disk space and to speedup installation, Playwright can re-use
these binaries.
<br>

Sharing browser binaries is a two-step process:
> **NOTE** Developers can opt-in in this mode via exporting `PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers` in their `.bashrc`.
1. When installing Playwright, ask it to download browsers into a shared location:
<br>

```sh
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers npm i playwright
```
## Download from artifact repository

2. When running Playwright scripts, ask it to search for browsers in a shared location:
By default, Playwright downloads browsers from Microsoft and Google public CDNs.

Sometimes companies maintain an internal artifact repository to host browser
binaries. In this case, Playwright can be configured to download from a custom
location using the `PLAYWRIGHT_DOWNLOAD_HOST` env variable.

```sh
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers node playwright-script.js
$ PLAYWRIGHT_DOWNLOAD_HOST=192.168.1.78 npm i playwright
```

> **NOTE** Developers can opt-in in this mode via exporting `PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers` in their `.bashrc`.
<br>

### Skip browser downloads
## Skip browser downloads

In certain cases, it is desired to avoid browser downloads altogether because
browser binaries are managed separately.
Expand All @@ -88,6 +96,8 @@ This can be done by setting `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` variable before i
$ PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 npm i playwright
```

<br>

## Download single browser binary

Playwright ships three packages that bundle only a single browser:
Expand All @@ -99,13 +109,13 @@ Playwright ships three packages that bundle only a single browser:
Using these packages is as easy as using a regular Playwright:

1. Install a specific package
Install a specific package

```sh
$ npm i playwright-webkit
```

2. Require package
Require package

```js
// Notice a proper package name in require
Expand Down
22 changes: 20 additions & 2 deletions src/install/browserPaths.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,27 @@ export function executablePath(browserPath: string, browser: BrowserDescriptor):
return tokens ? path.join(browserPath, ...tokens) : undefined;
}

function cacheDirectory() {
if (process.platform === 'linux')
return process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');

if (process.platform === 'darwin')
return path.join(os.homedir(), 'Library', 'Caches');

if (process.platform === 'win32')
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
throw new Error('Unsupported platform: ' + process.platform);
}

const defaultBrowsersPath = ((): string | undefined => {
const envDefined = getFromENV('PLAYWRIGHT_BROWSERS_PATH');
if (envDefined === '0')
return undefined;
return envDefined || path.join(cacheDirectory(), 'ms-playwright');
})();

export function browsersPath(packagePath: string): string {
const result = getFromENV('PLAYWRIGHT_BROWSERS_PATH');
return result || path.join(packagePath, '.local-browsers');
return defaultBrowsersPath || path.join(packagePath, '.local-browsers');
}

export function browserDirectory(browsersPath: string, browser: BrowserDescriptor): string {
Expand Down
7 changes: 1 addition & 6 deletions src/install/installer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import * as browserPaths from '../install/browserPaths';
import * as browserFetcher from '../install/browserFetcher';

const fsMkdirAsync = util.promisify(fs.mkdir.bind(fs));
const fsExistsAsync = (path: string) => new Promise(f => fs.exists(path, f));
const fsReaddirAsync = util.promisify(fs.readdir.bind(fs));
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
const fsUnlinkAsync = util.promisify(fs.unlink.bind(fs));
Expand All @@ -39,11 +38,7 @@ export async function installBrowsersWithProgressBar(packagePath: string) {
logPolitely('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set');
return false;
}
if (!await fsExistsAsync(browsersPath))
await fsMkdirAsync(browsersPath);
if (!await fsExistsAsync(linksDir))
await fsMkdirAsync(linksDir);

await fsMkdirAsync(linksDir, { recursive: true });
await fsWriteFileAsync(path.join(linksDir, sha1(packagePath)), packagePath);
await validateCache(browsersPath, linksDir);
}
Expand Down
2 changes: 1 addition & 1 deletion test/installation-tests/installation-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ npm pack ../../../packages/playwright-firefox

# cleanup environment
unset PLAYWRIGHT_DOWNLOAD_HOST
unset PLAYWRIGHT_BROWSERS_PATH
unset PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD
export PLAYWRIGHT_BROWSERS_PATH=0

# There is no option to specify output for `npm pack`, but the format is
# fixed.
Expand Down

0 comments on commit 9f62f29

Please sign in to comment.