diff --git a/docs/installation.md b/docs/installation.md
index 6860610c94dbc..67e44b2f25759 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -3,12 +3,13 @@
- [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)
+
+
## System requirements
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):
* For Ubuntu 18.04, the additional dependencies are defined in [our Docker image](docker/Dockerfile.bionic),
which is based on Ubuntu.
+
+
## 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.
+
-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:
+
-```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`.
+
-### Skip browser downloads
+## Skip browser downloads
In certain cases, it is desired to avoid browser downloads altogether because
browser binaries are managed separately.
@@ -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
```
+
+
## Download single browser binary
Playwright ships three packages that bundle only a single browser:
@@ -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
diff --git a/src/install/browserPaths.ts b/src/install/browserPaths.ts
index a7bf8b62f8bd4..c48073d643d2c 100644
--- a/src/install/browserPaths.ts
+++ b/src/install/browserPaths.ts
@@ -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 {
diff --git a/src/install/installer.ts b/src/install/installer.ts
index 633b64c109794..6fdf30ef5e11b 100644
--- a/src/install/installer.ts
+++ b/src/install/installer.ts
@@ -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));
@@ -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);
}
diff --git a/test/installation-tests/installation-tests.sh b/test/installation-tests/installation-tests.sh
index 60efa11b53fc2..aed1172d55809 100755
--- a/test/installation-tests/installation-tests.sh
+++ b/test/installation-tests/installation-tests.sh
@@ -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.