Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: remove all environment variables and references to puppeteer-core #47

Merged
merged 2 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ tsconfig.json

# exclude types, see https://github.com/GoogleChrome/puppeteer/issues/3878
/index.d.ts

# install.js only does stuff for development
/install.js
4 changes: 1 addition & 3 deletions chromium.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ for (const className in api.Chromium) {
helper.installAsyncStackHooks(api.Chromium[className]);
}

// If node does not support async await, use the compiled version.
const {Playwright} = require('./lib/chromium/Playwright');
const packageJson = require('./package.json');
const isPlaywrightCore = packageJson.name === 'playwright-core';

module.exports = new Playwright(__dirname, packageJson.playwright.chromium_revision, isPlaywrightCore);
module.exports = new Playwright(__dirname, packageJson.playwright.chromium_revision);
51 changes: 1 addition & 50 deletions docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

<!-- GEN:toc -->
- [Overview](#overview)
- [playwright vs playwright-core](#playwright-vs-playwright-core)
- [Environment Variables](#environment-variables)
- [Working with Chrome Extensions](#working-with-chrome-extensions)
- [class: Playwright](#class-playwright)
* [playwright.connect(options)](#playwrightconnectoptions)
Expand Down Expand Up @@ -338,50 +336,6 @@ The Playwright API is hierarchical and mirrors the browser structure.

(Diagram source: [link](https://docs.google.com/drawings/d/1Q_AM6KYs9kbyLZF-Lpp5mtpAWth73Cq8IKCsWYgi8MM/edit?usp=sharing))

### playwright vs playwright-core

Every release since v1.7.0 we publish two packages:
- [playwright](https://www.npmjs.com/package/playwright)
- [playwright-core](https://www.npmjs.com/package/playwright-core)

`playwright` is a *product* for browser automation. When installed, it downloads a version of
Chromium, which it then drives using `playwright-core`. Being an end-user product, `playwright` supports a bunch of convenient `PLAYWRIGHT_*` env variables to tweak its behavior.

`playwright-core` is a *library* to help drive anything that supports DevTools protocol. `playwright-core` doesn't download Chromium when installed. Being a library, `playwright-core` is fully driven
through its programmatic interface and disregards all the `PLAYWRIGHT_*` env variables.

To sum up, the only differences between `playwright-core` and `playwright` are:
- `playwright-core` doesn't automatically download Chromium when installed.
- `playwright-core` ignores all `PLAYWRIGHT_*` env variables.

In most cases, you'll be fine using the `playwright` package.

However, you should use `playwright-core` if:
- you're building another end-user product or library atop of DevTools protocol. For example, one might build a PDF generator using `playwright-core` and write a custom `install.js` script that downloads [`headless_shell`](https://chromium.googlesource.com/chromium/src/+/lkgr/headless/README.md) instead of Chromium to save disk space.
- you're bundling Playwright to use in Chrome Extension / browser with the DevTools protocol where downloading an additional Chromium binary is unnecessary.

When using `playwright-core`, remember to change the *include* line:

```js
const playwright = require('playwright-core');
```

You will then need to call [`playwright.connect([options])`](#playwrightconnectoptions) or [`playwright.launch([options])`](#playwrightlaunchoptions) with an explicit `executablePath` option.

### Environment Variables

Playwright looks for certain [environment variables](https://en.wikipedia.org/wiki/Environment_variable) to aid its operations.
If Playwright doesn't find them in the environment during the installation step, a lowercased variant of these variables will be used from the [npm config](https://docs.npmjs.com/cli/config).

- `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY` - defines HTTP proxy settings that are used to download and run Chromium.
- `PLAYWRIGHT_SKIP_CHROMIUM_DOWNLOAD` - do not download bundled Chromium during installation step.
- `PLAYWRIGHT_DOWNLOAD_HOST` - overwrite URL prefix that is used to download Chromium. Note: this includes protocol and might even include path prefix. Defaults to `https://storage.googleapis.com`.
- `PLAYWRIGHT_CHROMIUM_REVISION` - specify a certain version of Chromium you'd like Playwright to use. See [playwright.launch([options])](#playwrightlaunchoptions) on how executable path is inferred. **BEWARE**: Playwright is only [guaranteed to work](https://github.com/Microsoft/playwright/#q-why-doesnt-playwright-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk.
- `PLAYWRIGHT_EXECUTABLE_PATH` - specify an executable path to be used in `playwright.launch`. See [playwright.launch([options])](#playwrightlaunchoptions) on how the executable path is inferred. **BEWARE**: Playwright is only [guaranteed to work](https://github.com/Microsoft/playwright/#q-why-doesnt-playwright-vxxx-work-with-chromium-vyyy) with the bundled Chromium, use at your own risk.

> **NOTE** PLAYWRIGHT_* env variables are not accounted for in the [`playwright-core`](https://www.npmjs.com/package/playwright-core) package.


### Working with Chrome Extensions

Playwright can be used for testing Chrome Extensions.
Expand Down Expand Up @@ -508,10 +462,7 @@ try {
> **NOTE** The old way (Playwright versions <= v1.14.0) errors can be obtained with `require('playwright/Errors')`.

#### playwright.executablePath()
- returns: <[string]> A path where Playwright expects to find bundled Chromium. Chromium might not exist there if the download was skipped with [`PLAYWRIGHT_SKIP_CHROMIUM_DOWNLOAD`](#environment-variables).

> **NOTE** `playwright.executablePath()` is affected by the `PLAYWRIGHT_EXECUTABLE_PATH` and `PLAYWRIGHT_CHROMIUM_REVISION` env variables. See [Environment Variables](#environment-variables) for details.

- returns: <[string]> A path where Playwright expects to find bundled Chromium.

#### playwright.launch([options])
- `options` <[Object]> Set of configurable options to set on the browser. Can have the following fields:
Expand Down
1 change: 0 additions & 1 deletion firefox.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ for (const className in api.Firefox) {
helper.installAsyncStackHooks(api.Firefox[className]);
}

// If node does not support async await, use the compiled version.
const {Playwright} = require('./lib/firefox/Playwright');
const packageJson = require('./package.json');

Expand Down
86 changes: 26 additions & 60 deletions install.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/**
* Copyright 2017 Google Inc. All rights reserved.
* Modifications copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -14,61 +15,44 @@
* limitations under the License.
*/

// playwright-core should not install anything.
if (require('./package.json').name === 'playwright-core')
return;

const browserSkips = {Chromium: false, Firefox: false, WebKit: false};
for (const browser of ['Chromium', 'Firefox', 'WebKit']) {
const templates = [
`PLAYWRIGHT_SKIP_${browser}_DOWNLOAD`,
`NPM_CONFIG_PLAYWRIGHT_SKIP_${browser}_DOWNLOAD`,
`NPM_PACKAGE_CONFIG_PLAYWRIGHT_SKIP_${browser}_DOWNLOAD`,
];
const varNames = [...templates.map(n => n.toUpperCase()), ...templates.map(n => n.toLowerCase())];
for (const varName of varNames) {
if (process.env[varName.toUpperCase()]) {
logPolitely(`**INFO** Skipping ${browser} download. "${varName}" environment variable was found.`);
browserSkips[browser] = true;
break;
}
}
}

const downloadHost = process.env.PLAYWRIGHT_DOWNLOAD_HOST || process.env.npm_config_playwright_download_host || process.env.npm_package_config_playwright_download_host;


if (require('fs').existsSync(require('path').join(__dirname, 'src'))) {
try {
require('child_process').execSync('npm run build', {
stdio: 'ignore'
});
} catch (e) {
}
// This file is only run when someone clones the github repo for development

try {
require('child_process').execSync('npm run build', {
stdio: 'ignore'
});
} catch (e) {
console.warn('Build failed');
}

(async function() {
const {generateWebKitProtocol, generateChromeProtocol} = require('./utils/protocol-types-generator/') ;
if (!browserSkips.Chromium) {
const chromeRevision = await downloadBrowser('chromium', require('./chromium').createBrowserFetcher({host: downloadHost}));
try {
const chromeRevision = await downloadBrowser('chromium', require('./chromium').createBrowserFetcher());
await generateChromeProtocol(chromeRevision);
} catch (e) {
console.warn(e.message);
}

if (!browserSkips.Firefox)
await downloadBrowser('firefox', require('./firefox').createBrowserFetcher({host: downloadHost}));

if (!browserSkips.WebKit) {
const webkitRevision = await downloadBrowser('webkit', require('./webkit').createBrowserFetcher({host: downloadHost}));
try {
await downloadBrowser('firefox', require('./firefox').createBrowserFetcher());
} catch (e) {
console.warn(e.message);
}
try {
const webkitRevision = await downloadBrowser('webkit', require('./webkit').createBrowserFetcher());
await generateWebKitProtocol(webkitRevision);
} catch (e) {
console.warn(e.message);
}
})();
function getRevision(browser) {
if (browser === 'chromium')
return process.env.PLAYWRIGHT_CHROMIUM_REVISION || process.env.npm_config_playwright_chromium_revision || process.env.npm_package_config_playwright_chromium_revision || require('./package.json').playwright.chromium_revision;
return require('./package.json').playwright.chromium_revision;
if (browser === 'firefox')
return process.env.PLAYWRIGHT_FIREFOX_REVISION || process.env.npm_config_playwright_firefox_revision || process.env.npm_package_config_playwright_firefox_revision || require('./package.json').playwright.firefox_revision;
return require('./package.json').playwright.firefox_revision;
if (browser === 'webkit')
return process.env.PLAYWRIGHT_WEBKIT_REVISION || process.env.npm_config_playwright_webkit_revision || process.env.npm_package_config_playwright_webkit_revision || require('./package.json').playwright.webkit_revision;
return require('./package.json').playwright.webkit_revision;
}
async function downloadBrowser(browser, browserFetcher) {
const revision = getRevision(browser);
Expand All @@ -79,18 +63,6 @@ async function downloadBrowser(browser, browserFetcher) {
if (revisionInfo.local)
return revisionInfo;

// Override current environment proxy settings with npm configuration, if any.
const NPM_HTTPS_PROXY = process.env.npm_config_https_proxy || process.env.npm_config_proxy;
const NPM_HTTP_PROXY = process.env.npm_config_http_proxy || process.env.npm_config_proxy;
const NPM_NO_PROXY = process.env.npm_config_no_proxy;

if (NPM_HTTPS_PROXY)
process.env.HTTPS_PROXY = NPM_HTTPS_PROXY;
if (NPM_HTTP_PROXY)
process.env.HTTP_PROXY = NPM_HTTP_PROXY;
if (NPM_NO_PROXY)
process.env.NO_PROXY = NPM_NO_PROXY;

let progressBar = null;
let lastDownloadedBytes = 0;
function onProgress(downloadedBytes, totalBytes) {
Expand All @@ -108,13 +80,7 @@ async function downloadBrowser(browser, browserFetcher) {
progressBar.tick(delta);
}

try {
await browserFetcher.download(revisionInfo.revision, onProgress);
} catch(error) {
console.error(`ERROR: Failed to download ${browser} ${revision}! Set "PLAYWRIGHT_SKIP_${browser.toUpperCase()}_DOWNLOAD" env variable to skip download.`);
console.error(error);
process.exit(1);
}
await browserFetcher.download(revisionInfo.revision, onProgress);
logPolitely(`${browser} downloaded to ${revisionInfo.folderPath}`);
const localRevisions = await browserFetcher.localRevisions();
// Remove previous chromium revisions.
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"name": "playwright",
"version": "0.9.0-post",
"description": "A high-level API to control headless Chrome over the DevTools Protocol",
"main": "index.js",
"repository": "github:Microsoft/playwright",
"engines": {
"node": ">=8.16.0"
Expand Down
20 changes: 1 addition & 19 deletions src/chromium/Launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,10 @@ const DEFAULT_ARGS = [
export class Launcher {
private _projectRoot: string;
private _preferredRevision: string;
private _isPlaywrightCore: boolean;

constructor(projectRoot: string, preferredRevision: string, isPlaywrightCore: boolean) {
constructor(projectRoot: string, preferredRevision: string) {
this._projectRoot = projectRoot;
this._preferredRevision = preferredRevision;
this._isPlaywrightCore = isPlaywrightCore;
}

async launch(options: (LauncherLaunchOptions & LauncherChromeArgOptions & LauncherBrowserOptions) = {}): Promise<Browser> {
Expand Down Expand Up @@ -280,23 +278,7 @@ export class Launcher {
}

_resolveExecutablePath(): { executablePath: string; missingText: string | null; } {
// playwright-core doesn't take into account PLAYWRIGHT_* env variables.
if (!this._isPlaywrightCore) {
const executablePath = process.env.PLAYWRIGHT_EXECUTABLE_PATH || process.env.npm_config_playwright_executable_path || process.env.npm_package_config_playwright_executable_path;
if (executablePath) {
const missingText = !fs.existsSync(executablePath) ? 'Tried to use PLAYWRIGHT_EXECUTABLE_PATH env variable to launch browser but did not find any executable at: ' + executablePath : null;
return { executablePath, missingText };
}
}
const browserFetcher = new BrowserFetcher(this._projectRoot);
if (!this._isPlaywrightCore) {
const revision = process.env['PLAYWRIGHT_CHROMIUM_REVISION'];
if (revision) {
const revisionInfo = browserFetcher.revisionInfo(revision);
const missingText = !revisionInfo.local ? 'Tried to use PLAYWRIGHT_CHROMIUM_REVISION env variable to launch browser but did not find executable at: ' + revisionInfo.executablePath : null;
return {executablePath: revisionInfo.executablePath, missingText};
}
}
const revisionInfo = browserFetcher.revisionInfo(this._preferredRevision);
const missingText = !revisionInfo.local ? `Chromium revision is not downloaded. Run "npm install" or "yarn install"` : null;
return {executablePath: revisionInfo.executablePath, missingText};
Expand Down
4 changes: 2 additions & 2 deletions src/chromium/Playwright.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ export class Playwright {
private _projectRoot: string;
private _launcher: Launcher;

constructor(projectRoot: string, preferredRevision: string, isPlaywrightCore: boolean) {
constructor(projectRoot: string, preferredRevision: string) {
this._projectRoot = projectRoot;
this._launcher = new Launcher(projectRoot, preferredRevision, isPlaywrightCore);
this._launcher = new Launcher(projectRoot, preferredRevision);
}

launch(options: (LauncherLaunchOptions & LauncherChromeArgOptions & LauncherBrowserOptions) | undefined): Promise<Browser> {
Expand Down
6 changes: 0 additions & 6 deletions src/webkit/Launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,6 @@ export class Launcher {

_resolveExecutablePath(): { executablePath: string; missingText: string | null; } {
const browserFetcher = new BrowserFetcher(this._projectRoot);
const revision = process.env['PLAYWRIGHT_WEBKIT_REVISION'];
if (revision) {
const revisionInfo = browserFetcher.revisionInfo(revision);
const missingText = !revisionInfo.local ? 'Tried to use PLAYWRIGHT_WEBKIT_REVISION env variable to launch browser but did not find executable at: ' + revisionInfo.executablePath : null;
return {executablePath: revisionInfo.executablePath, missingText};
}
const revisionInfo = browserFetcher.revisionInfo(this._preferredRevision);
const missingText = !revisionInfo.local ? `WebKit revision is not downloaded. Run "npm install" or "yarn install"` : null;
return {executablePath: revisionInfo.executablePath, missingText};
Expand Down
25 changes: 0 additions & 25 deletions utils/prepare_playwright_core.js

This file was deleted.

1 change: 0 additions & 1 deletion webkit.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ for (const className in api.WebKit) {
helper.installAsyncStackHooks(api.WebKit[className]);
}

// If node does not support async await, use the compiled version.
const {Playwright} = require('./lib/webkit/Playwright');
const packageJson = require('./package.json');

Expand Down