Skip to content

Commit 9f62f29

Browse files
authored
feat(install): use shared installation folder by default (#2044)
1 parent c55db6d commit 9f62f29

File tree

4 files changed

+65
-42
lines changed

4 files changed

+65
-42
lines changed

docs/installation.md

Lines changed: 43 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
<!-- GEN:toc -->
44
- [System requirements](#system-requirements)
55
- [Managing browser binaries](#managing-browser-binaries)
6-
* [Download from artifact repository](#download-from-artifact-repository)
7-
* [Share browser binaries across projects](#share-browser-binaries-across-projects)
8-
* [Skip browser downloads](#skip-browser-downloads)
6+
- [Download from artifact repository](#download-from-artifact-repository)
7+
- [Skip browser downloads](#skip-browser-downloads)
98
- [Download single browser binary](#download-single-browser-binary)
109
<!-- GEN:stop -->
1110

11+
<br>
12+
1213
## System requirements
1314

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

25+
<br>
26+
2427
## Managing browser binaries
2528

26-
Each version of Playwright needs specific versions of browser binaries to operate.
29+
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:
2730

28-
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:
31+
- `HOME\AppData\Local\ms-playwright` on Windows
32+
- `~/Library/Caches/ms-playwright` on MacOS
33+
- `~/.cache/playwright/ms-playwright` on Linux
2934

3035
```sh
3136
npm i playwright
3237
```
3338

34-
These browsers will take hundreds of megabytes of the disk space when installed:
39+
These browsers will take few hundreds of megabytes of the disk space when installed:
3540

3641
```sh
37-
du -hs ./node_modules/playwright/.local-browsers/*
38-
281M .local-browsers/chromium-XXXXXX
39-
187M .local-browsers/firefox-XXXX
40-
180M .local-browsers/webkit-XXXX
42+
du -hs ./Library/Caches/ms-playwright/*
43+
281M chromium-XXXXXX
44+
187M firefox-XXXX
45+
180M webkit-XXXX
4146
```
4247

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

45-
### Download from artifact repository
50+
```sh
51+
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers npm i playwright
52+
```
4653

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

49-
Sometimes companies maintain an internal artifact repository to host browser
50-
binaries. In this case, Playwright can be configured to download from a custom
51-
location using the `PLAYWRIGHT_DOWNLOAD_HOST` env variable.
56+
```sh
57+
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers node playwright-script.js
58+
```
59+
60+
Or you can opt into the hermetic install and place binaries under the `node_modules/` folder:
5261

5362
```sh
54-
$ PLAYWRIGHT_DOWNLOAD_HOST=192.168.1.78 npm i playwright
63+
$ PLAYWRIGHT_BROWSERS_PATH=0 node playwright-script.js
5564
```
5665

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

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

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

68-
```sh
69-
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers npm i playwright
70-
```
74+
## Download from artifact repository
7175

72-
2. When running Playwright scripts, ask it to search for browsers in a shared location:
76+
By default, Playwright downloads browsers from Microsoft and Google public CDNs.
77+
78+
Sometimes companies maintain an internal artifact repository to host browser
79+
binaries. In this case, Playwright can be configured to download from a custom
80+
location using the `PLAYWRIGHT_DOWNLOAD_HOST` env variable.
7381

7482
```sh
75-
$ PLAYWRIGHT_BROWSERS_PATH=$HOME/pw-browsers node playwright-script.js
83+
$ PLAYWRIGHT_DOWNLOAD_HOST=192.168.1.78 npm i playwright
7684
```
7785

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

80-
### Skip browser downloads
88+
## Skip browser downloads
8189

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

99+
<br>
100+
91101
## Download single browser binary
92102

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

102-
1. Install a specific package
112+
Install a specific package
103113

104114
```sh
105115
$ npm i playwright-webkit
106116
```
107117

108-
2. Require package
118+
Require package
109119

110120
```js
111121
// Notice a proper package name in require

src/install/browserPaths.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,27 @@ export function executablePath(browserPath: string, browser: BrowserDescriptor):
7777
return tokens ? path.join(browserPath, ...tokens) : undefined;
7878
}
7979

80+
function cacheDirectory() {
81+
if (process.platform === 'linux')
82+
return process.env.XDG_CACHE_HOME || path.join(os.homedir(), '.cache');
83+
84+
if (process.platform === 'darwin')
85+
return path.join(os.homedir(), 'Library', 'Caches');
86+
87+
if (process.platform === 'win32')
88+
return process.env.LOCALAPPDATA || path.join(os.homedir(), 'AppData', 'Local');
89+
throw new Error('Unsupported platform: ' + process.platform);
90+
}
91+
92+
const defaultBrowsersPath = ((): string | undefined => {
93+
const envDefined = getFromENV('PLAYWRIGHT_BROWSERS_PATH');
94+
if (envDefined === '0')
95+
return undefined;
96+
return envDefined || path.join(cacheDirectory(), 'ms-playwright');
97+
})();
98+
8099
export function browsersPath(packagePath: string): string {
81-
const result = getFromENV('PLAYWRIGHT_BROWSERS_PATH');
82-
return result || path.join(packagePath, '.local-browsers');
100+
return defaultBrowsersPath || path.join(packagePath, '.local-browsers');
83101
}
84102

85103
export function browserDirectory(browsersPath: string, browser: BrowserDescriptor): string {

src/install/installer.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import * as browserPaths from '../install/browserPaths';
2424
import * as browserFetcher from '../install/browserFetcher';
2525

2626
const fsMkdirAsync = util.promisify(fs.mkdir.bind(fs));
27-
const fsExistsAsync = (path: string) => new Promise(f => fs.exists(path, f));
2827
const fsReaddirAsync = util.promisify(fs.readdir.bind(fs));
2928
const fsReadFileAsync = util.promisify(fs.readFile.bind(fs));
3029
const fsUnlinkAsync = util.promisify(fs.unlink.bind(fs));
@@ -39,11 +38,7 @@ export async function installBrowsersWithProgressBar(packagePath: string) {
3938
logPolitely('Skipping browsers download because `PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD` env variable is set');
4039
return false;
4140
}
42-
if (!await fsExistsAsync(browsersPath))
43-
await fsMkdirAsync(browsersPath);
44-
if (!await fsExistsAsync(linksDir))
45-
await fsMkdirAsync(linksDir);
46-
41+
await fsMkdirAsync(linksDir, { recursive: true });
4742
await fsWriteFileAsync(path.join(linksDir, sha1(packagePath)), packagePath);
4843
await validateCache(browsersPath, linksDir);
4944
}

test/installation-tests/installation-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ npm pack ../../../packages/playwright-firefox
1919

2020
# cleanup environment
2121
unset PLAYWRIGHT_DOWNLOAD_HOST
22-
unset PLAYWRIGHT_BROWSERS_PATH
2322
unset PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD
23+
export PLAYWRIGHT_BROWSERS_PATH=0
2424

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

0 commit comments

Comments
 (0)