diff --git a/package.json b/package.json index 3c1e102d..8a794f0e 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,8 @@ "lerna": "^3.13.2", "lint-staged": "^8.1.5", "prettier": "^1.16.4", - "puppeteer": "^1.14.0" + "puppeteer": "^1.14.0", + "puppeteer-firefox": "^0.5.0" }, "dependencies": {} } diff --git a/packages/jest-environment-puppeteer/README.md b/packages/jest-environment-puppeteer/README.md index 3d9f1658..b7f89c1d 100644 --- a/packages/jest-environment-puppeteer/README.md +++ b/packages/jest-environment-puppeteer/README.md @@ -93,6 +93,9 @@ You can specify a `jest-puppeteer.config.js` at the root of the project or defin - `launch` <[object]> [All Puppeteer launch options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions) can be specified in config. Since it is JavaScript, you can use all stuff you need, including environment. - `connect` <[object]> [All Puppeteer connect options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerconnectoptions) can be specified in config. This is an alternative to `launch` config, allowing you to connect to an already running instance of Chrome. +- `browser` <[string]>. Define a browser to run tests into. + - `chromium` Each test uses [puppeteer](https://npmjs.com/package/puppeteer) and runs Chromium + - `firefox` Each test uses [puppeteer-firefox](https://npmjs.com/package/puppeteer-firefox) and runs Firefox. This option requires `puppeteer-firefox` as a peer dependency. - `browserContext` <[string]>. By default, the browser context (cookies, localStorage, etc) is shared between all tests. The following options are available for `browserContext`: - `default` Each test starts a tab, so all tests share the same context. - `incognito` Each tests starts an incognito window, so all tests have a separate, isolated context. Useful when running tests that could interfere with one another. (_Example: testing multiple users on the same app at once with login, transactions, etc._) diff --git a/packages/jest-environment-puppeteer/package.json b/packages/jest-environment-puppeteer/package.json index e9990b87..b0d221c0 100644 --- a/packages/jest-environment-puppeteer/package.json +++ b/packages/jest-environment-puppeteer/package.json @@ -20,9 +20,6 @@ "dev": "yarn build --watch", "prepublishOnly": "yarn build" }, - "peerDependencies": { - "puppeteer": "^1.5.0" - }, "dependencies": { "chalk": "^2.4.2", "cwd": "^0.10.0", diff --git a/packages/jest-environment-puppeteer/src/PuppeteerEnvironment.js b/packages/jest-environment-puppeteer/src/PuppeteerEnvironment.js index 74c88c0c..3ca92eaa 100644 --- a/packages/jest-environment-puppeteer/src/PuppeteerEnvironment.js +++ b/packages/jest-environment-puppeteer/src/PuppeteerEnvironment.js @@ -1,8 +1,7 @@ // eslint-disable-next-line import NodeEnvironment from 'jest-environment-node' -import puppeteer from 'puppeteer' import chalk from 'chalk' -import readConfig from './readConfig' +import { readConfig, getPuppeteer } from './readConfig' const handleError = error => { process.emit('uncaughtException', error) @@ -28,6 +27,7 @@ class PuppeteerEnvironment extends NodeEnvironment { async setup() { const config = await readConfig() + const puppeteer = getPuppeteer(config) this.global.puppeteerConfig = config const wsEndpoint = process.env.PUPPETEER_WS_ENDPOINT diff --git a/packages/jest-environment-puppeteer/src/global.js b/packages/jest-environment-puppeteer/src/global.js index e2eee77e..2f0913d0 100644 --- a/packages/jest-environment-puppeteer/src/global.js +++ b/packages/jest-environment-puppeteer/src/global.js @@ -5,14 +5,14 @@ import { ERROR_TIMEOUT, ERROR_NO_COMMAND, } from 'jest-dev-server' -import puppeteer from 'puppeteer' import chalk from 'chalk' -import readConfig from './readConfig' +import { readConfig, getPuppeteer } from './readConfig' let browser export async function setup(jestConfig = {}) { const config = await readConfig() + const puppeteer = getPuppeteer(config) if (config.connect) { browser = await puppeteer.connect(config.connect) } else { diff --git a/packages/jest-environment-puppeteer/src/readConfig.js b/packages/jest-environment-puppeteer/src/readConfig.js index 4b34d377..d147af6d 100644 --- a/packages/jest-environment-puppeteer/src/readConfig.js +++ b/packages/jest-environment-puppeteer/src/readConfig.js @@ -8,6 +8,7 @@ const exists = promisify(fs.exists) const DEFAULT_CONFIG = { launch: {}, + browser: 'chromium', browserContext: 'default', exitOnPageError: true, } @@ -23,7 +24,7 @@ const DEFAULT_CONFIG_CI = merge(DEFAULT_CONFIG, { }, }) -async function readConfig() { +export async function readConfig() { const defaultConfig = process.env.CI === 'true' ? DEFAULT_CONFIG_CI : DEFAULT_CONFIG @@ -48,4 +49,17 @@ async function readConfig() { return merge({}, defaultConfig, localConfig) } -export default readConfig +export function getPuppeteer(config) { + switch (config.browser.toLowerCase()) { + case 'chromium': + // eslint-disable-next-line global-require, import/no-dynamic-require, import/no-extraneous-dependencies + return require('puppeteer') + case 'firefox': + // eslint-disable-next-line global-require, import/no-dynamic-require, import/no-extraneous-dependencies + return require('puppeteer-firefox') + default: + throw new Error( + `Error: "browser" config option is given an unsupported value: ${browser}`, + ) + } +} diff --git a/packages/jest-environment-puppeteer/tests/readConfig.test.js b/packages/jest-environment-puppeteer/tests/readConfig.test.js index 5e478d5e..ea829237 100644 --- a/packages/jest-environment-puppeteer/tests/readConfig.test.js +++ b/packages/jest-environment-puppeteer/tests/readConfig.test.js @@ -1,6 +1,10 @@ import fs from 'fs' import path from 'path' -import readConfig from '../src/readConfig' +// eslint-disable-next-line import/no-extraneous-dependencies +import pptrChromium from 'puppeteer' +// eslint-disable-next-line import/no-extraneous-dependencies +import pptrFirefox from 'puppeteer-firefox' +import { readConfig, getPuppeteer } from '../src/readConfig' jest.mock('fs') @@ -8,6 +12,23 @@ function mockExists(value) { fs.exists.mockImplementation((path, callback) => callback(null, value)) } +describe('getPuppeteer', () => { + it('should return chromium when specified', async () => { + expect( + getPuppeteer({ + browser: 'Chromium', + }), + ).toBe(pptrChromium) + }) + it('should return firefox when specified', async () => { + expect( + getPuppeteer({ + browser: 'Firefox', + }), + ).toBe(pptrFirefox) + }) +}) + describe('readConfig', () => { describe('with custom config path', () => { beforeEach(() => { diff --git a/yarn.lock b/yarn.lock index 16ce7482..9b12ab57 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7427,6 +7427,20 @@ puppeteer@^1.14.0: rimraf "^2.6.1" ws "^6.1.0" +puppeteer-firefox@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/puppeteer-firefox/-/puppeteer-firefox-0.5.0.tgz#5800e48cbbe135adae5fbf3032114064a612d87a" + integrity sha512-80wl29/Lb0URQ1f77yVXfq+cxCW30Q+1GbpRb32HbzTR9/amOn6D5G99xo8OsDJ6kIfuLyYTLj6HZgwMuDPBBQ== + dependencies: + debug "^4.1.0" + extract-zip "^1.6.6" + https-proxy-agent "^2.2.1" + mime "^2.0.3" + progress "^2.0.1" + proxy-from-env "^1.0.0" + rimraf "^2.6.1" + ws "^6.1.0" + q@^1.4.1, q@^1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"