From 1176625b15322a064aac16811a40db611f60cba8 Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Thu, 6 Feb 2020 16:34:55 +0300 Subject: [PATCH 1/8] Ability to support specific browser --- src/PlaywrightEnvironment.js | 28 +++++++++++++++++++++------- src/utils.js | 12 ++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/PlaywrightEnvironment.js b/src/PlaywrightEnvironment.js index 894c39ab..e6b3cec9 100644 --- a/src/PlaywrightEnvironment.js +++ b/src/PlaywrightEnvironment.js @@ -1,6 +1,10 @@ import NodeEnvironment from 'jest-environment-node' -import playwright from 'playwright' -import { checkBrowserEnv, getBrowserType, readConfig } from './utils' +import { + checkBrowserEnv, + getBrowserType, + getPlaywrightInstance, + readConfig, +} from './utils' const handleError = error => { process.emit('uncaughtException', error) @@ -31,8 +35,12 @@ async function getBrowserPerProcess() { const config = await readConfig() const browserType = getBrowserType(config) checkBrowserEnv(browserType) - const { launchBrowserApp } = config - browserPerProcess = await playwright[browserType].launch(launchBrowserApp) + const { launchBrowserApp, useStandaloneVersion } = config + const playwrightInstance = getPlaywrightInstance( + browserType, + useStandaloneVersion, + ) + browserPerProcess = await playwrightInstance.launch(launchBrowserApp) } return browserPerProcess } @@ -41,17 +49,23 @@ class PlaywrightEnvironment extends NodeEnvironment { async setup() { resetBrowserCloseWatchdog() const config = await readConfig() - const { device, context } = config + const browserType = getBrowserType(config) + checkBrowserEnv(browserType) + const { device, context, useStandaloneVersion } = config + const playwrightInstance = getPlaywrightInstance( + browserType, + useStandaloneVersion, + ) let contextOptions = context - const availableDevices = Object.keys(playwright.devices) + const availableDevices = Object.keys(playwrightInstance.devices) if (device) { if (!availableDevices.includes(device)) { throw new Error( `Wrong device. Should be one of [${availableDevices}], but got ${device}`, ) } else { - const { viewport, userAgent } = playwright.devices[device] + const { viewport, userAgent } = playwrightInstance.devices[device] contextOptions = { ...contextOptions, viewport, userAgent } } } diff --git a/src/utils.js b/src/utils.js index 191d7930..a2d83a6d 100644 --- a/src/utils.js +++ b/src/utils.js @@ -21,6 +21,18 @@ export function getBrowserType(config) { return config.browser || CHROMIUM } +export function getPlaywrightInstance( + browserType, + useStandaloneVersion = process.env.USE_STANDALONE_VERSION, +) { + if (useStandaloneVersion) { + // eslint-disable-next-line global-require, import/no-dynamic-require + return require(`playwright-${browserType}`) + } + // eslint-disable-next-line global-require + return require('playwright')[browserType] +} + export async function readConfig() { const defaultConfig = DEFAULT_CONFIG From a49a78ed763885ae10a9b75d304a787756e3cca9 Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sat, 8 Feb 2020 15:18:28 +0300 Subject: [PATCH 2/8] Move playwright to optionalDependencies --- package-lock.json | 16 ++++++++-------- package.json | 9 +++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 80dbdd2c..49336789 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "jest-playwright-preset", - "version": "0.0.3", + "version": "0.0.5", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -6524,18 +6524,18 @@ } }, "playwright": { - "version": "0.9.24", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-0.9.24.tgz", - "integrity": "sha512-CdSY4rcrzkNkLIBhbu2qlhMrQdVXZzdL/Ybufh+SB+OLutNBnfFiZsnOJ6vow2W0ik1MWM1fabqXNnyoQsVItg==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-0.10.0.tgz", + "integrity": "sha512-f3VRME/PIO5NbcWnlCDfXwPC0DAZJ7ETkcAdE+sensLCOkfDtLh97E71ZuxNCaPYsUA6FIPi5syD8pHJW/4hQQ==", "dev": true, "requires": { - "playwright-core": "=0.9.24" + "playwright-core": "=0.10.0" } }, "playwright-core": { - "version": "0.9.24", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-0.9.24.tgz", - "integrity": "sha512-4yxhmbk9wQGnhOsh8C6NLeQcez/uKzCgGAVwru47/1JrQV/MNyr+t4E+VBwGEcgnjzI9F33IaKsMuYDrqhBz4w==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-0.10.0.tgz", + "integrity": "sha512-yernA6yrrBhmb8M5eO6GZsJOrBKWOZszlu65Luz8LP7ryaDExN1sE9XjQBNbiwJ5Gfs8cehtAO7GfTDJt+Z2cQ==", "dev": true, "requires": { "debug": "^4.1.0", diff --git a/package.json b/package.json index b120e048..33b6dfcc 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,13 @@ "*.js": "eslint --fix" }, "peerDependencies": { - "jest-environment-node": "^25.1.0", - "playwright": "*" + "jest-environment-node": "^25.1.0" + }, + "optionalDependencies": { + "playwright": "*", + "playwright-chromium": "*", + "playwright-firefox": "*", + "playwright-webkit": "*" }, "devDependencies": { "@babel/cli": "^7.8.4", From 0a2c4e0fb6c15603196d6b961db9d73e26c86d86 Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sat, 8 Feb 2020 15:36:51 +0300 Subject: [PATCH 3/8] Add check for installed defined playwright version --- src/utils.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/utils.js b/src/utils.js index a2d83a6d..658d13cf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -26,10 +26,15 @@ export function getPlaywrightInstance( useStandaloneVersion = process.env.USE_STANDALONE_VERSION, ) { if (useStandaloneVersion) { - // eslint-disable-next-line global-require, import/no-dynamic-require - return require(`playwright-${browserType}`) + const playwrightPackage = `playwright-${browserType}` + try { + // eslint-disable-next-line global-require, import/no-dynamic-require + return require(playwrightPackage) + } catch (e) { + throw new Error(`You need to install ${playwrightPackage}`) + } } - // eslint-disable-next-line global-require + // eslint-disable-next-line global-require,import/no-extraneous-dependencies return require('playwright')[browserType] } From 748db2935fda349fd539bf6f0e130b214b17a920 Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sun, 9 Feb 2020 12:53:15 +0300 Subject: [PATCH 4/8] Reduce some unnecessary initializations --- src/PlaywrightEnvironment.js | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/src/PlaywrightEnvironment.js b/src/PlaywrightEnvironment.js index ba4c4122..f31f79c9 100644 --- a/src/PlaywrightEnvironment.js +++ b/src/PlaywrightEnvironment.js @@ -36,16 +36,11 @@ function startBrowserCloseWatchdog() { }, 50) } -async function getBrowserPerProcess() { +async function getBrowserPerProcess(playwrightInstance, config) { if (!browserPerProcess) { - const config = await readConfig() const browserType = getBrowserType(config) checkBrowserEnv(browserType) - const { launchBrowserApp, useStandaloneVersion } = config - const playwrightInstance = getPlaywrightInstance( - browserType, - useStandaloneVersion, - ) + const { launchBrowserApp } = config browserPerProcess = await playwrightInstance.launch(launchBrowserApp) } return browserPerProcess @@ -69,7 +64,7 @@ class PlaywrightEnvironment extends NodeEnvironment { const browserType = getBrowserType(config) checkBrowserEnv(browserType) const { device, context, useStandaloneVersion } = config - const playwrightInstance = getPlaywrightInstance( + const playwrightInstance = await getPlaywrightInstance( browserType, useStandaloneVersion, ) @@ -86,7 +81,7 @@ class PlaywrightEnvironment extends NodeEnvironment { contextOptions = { ...contextOptions, viewport, userAgent } } } - this.global.browser = await getBrowserPerProcess() + this.global.browser = await getBrowserPerProcess(playwrightInstance, config) this.global.context = await this.global.browser.newContext(contextOptions) this.global.page = await this.global.context.newPage() this.global.page.on('pageerror', handleError) From b9fb82e8ccdcc11fe357e8a33ab34766438d69ef Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sun, 9 Feb 2020 15:05:22 +0300 Subject: [PATCH 5/8] New implementation of useStandaloneVersion feature --- src/PlaywrightEnvironment.js | 7 ++---- src/utils.js | 44 ++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/PlaywrightEnvironment.js b/src/PlaywrightEnvironment.js index f31f79c9..41b46106 100644 --- a/src/PlaywrightEnvironment.js +++ b/src/PlaywrightEnvironment.js @@ -63,11 +63,8 @@ class PlaywrightEnvironment extends NodeEnvironment { const config = await readConfig() const browserType = getBrowserType(config) checkBrowserEnv(browserType) - const { device, context, useStandaloneVersion } = config - const playwrightInstance = await getPlaywrightInstance( - browserType, - useStandaloneVersion, - ) + const { device, context } = config + const playwrightInstance = await getPlaywrightInstance(browserType) let contextOptions = context const availableDevices = Object.keys(playwrightInstance.devices) diff --git a/src/utils.js b/src/utils.js index 8349e25b..14222e46 100644 --- a/src/utils.js +++ b/src/utils.js @@ -5,6 +5,15 @@ import { CHROMIUM, FIREFOX, WEBKIT, DEFAULT_CONFIG } from './constants' const exists = promisify(fs.exists) +const checkDependencies = dependencies => { + if (!dependencies) return null + if (dependencies.playwright) return 'playwright' + if (dependencies[`playwright-${CHROMIUM}`]) return `playwright-${CHROMIUM}` + if (dependencies[`playwright-${FIREFOX}`]) return `playwright-${FIREFOX}` + if (dependencies[`playwright-${WEBKIT}`]) return `playwright-${WEBKIT}` + return null +} + export function checkBrowserEnv(param) { if (param !== CHROMIUM && param !== FIREFOX && param !== WEBKIT) { throw new Error( @@ -21,21 +30,28 @@ export function getBrowserType(config) { return config.browser || CHROMIUM } -export function getPlaywrightInstance( - browserType, - useStandaloneVersion = process.env.USE_STANDALONE_VERSION, -) { - if (useStandaloneVersion) { - const playwrightPackage = `playwright-${browserType}` - try { - // eslint-disable-next-line global-require, import/no-dynamic-require - return require(playwrightPackage) - } catch (e) { - throw new Error(`You need to install ${playwrightPackage}`) - } +export async function readPackage() { + const packagePath = 'package.json' + const absConfigPath = path.resolve(process.cwd(), packagePath) + // eslint-disable-next-line global-require,import/no-dynamic-require + const packageConfig = await require(absConfigPath) + const playwright = + checkDependencies(packageConfig.dependencies) || + checkDependencies(packageConfig.devDependencies) + if (!playwright) { + throw new Error('None of playwright packages was not found in dependencies') + } + return playwright +} + +export async function getPlaywrightInstance(browserType) { + const playwrightPackage = await readPackage() + if (playwrightPackage === 'playwright') { + // eslint-disable-next-line global-require, import/no-dynamic-require + return require(playwrightPackage)[browserType] } - // eslint-disable-next-line global-require,import/no-extraneous-dependencies - return require('playwright')[browserType] + // eslint-disable-next-line global-require, import/no-dynamic-require + return require(playwrightPackage) } export async function readConfig() { From e5638f2241e892959ad91fe82b1066c8dcb12b91 Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sun, 9 Feb 2020 15:05:36 +0300 Subject: [PATCH 6/8] Add soe new tests --- src/utils.test.js | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/utils.test.js b/src/utils.test.js index 8dd89108..b2a34fb3 100644 --- a/src/utils.test.js +++ b/src/utils.test.js @@ -1,3 +1,5 @@ +import { checkBrowserEnv, readPackage } from './utils' + const fs = require('fs') const path = require('path') const { readConfig, getBrowserType } = require('./utils') @@ -80,3 +82,71 @@ describe('getBrowserType', () => { expect(browserType).toBe(CHROMIUM) }) }) + +describe('checkBrowserEnv', () => { + it('should throw Error with unknown type', async () => { + fs.exists.mockImplementationOnce((_, cb) => cb(true)) + jest.mock( + path.join(__dirname, '..', 'jest-playwright.config.js'), + () => ({ + browser: 'unknown', + }), + { virtual: true }, + ) + const config = await readConfig() + const browserType = getBrowserType(config) + expect(() => checkBrowserEnv(browserType)).toThrow() + }) +}) + +describe('readPackage', () => { + it('should return null when dependencies does not passed', async () => { + fs.exists.mockImplementationOnce((_, cb) => cb(true)) + jest.mock( + path.join(__dirname, '..', 'package.json'), + () => ({ + dependencies: {}, + }), + { virtual: true }, + ) + let error + try { + await readPackage() + } catch (e) { + error = e + } + expect(error).toEqual( + new Error('None of playwright packages was not found in dependencies'), + ) + }) + it('should return playwright when it is defined', async () => { + fs.exists.mockImplementationOnce((_, cb) => cb(true)) + jest.mock( + path.join(__dirname, '..', 'package.json'), + () => ({ + dependencies: { + playwright: '*', + }, + }), + { virtual: true }, + ) + + const playwright = await readPackage() + expect(playwright).toEqual('playwright') + }) + it('should return playwright-firefox when it is defined', async () => { + fs.exists.mockImplementationOnce((_, cb) => cb(true)) + jest.mock( + path.join(__dirname, '..', 'package.json'), + () => ({ + devDependencies: { + 'playwright-firefox': '*', + }, + }), + { virtual: true }, + ) + + const playwright = await readPackage() + expect(playwright).toEqual('playwright-firefox') + }) +}) From b46326fb4183a974c9730cc9f94d2a524aead7ac Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sun, 9 Feb 2020 15:23:20 +0300 Subject: [PATCH 7/8] Rewrite tests command --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 520e1987..cc894012 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,8 @@ "format": "prettier --write \"*.{js,md}\" \"src/*.js\"", "lint": "eslint .", "prepublishOnly": "yarn run build", - "test": "jest" + "test:utils": "jest src/utils.test.js", + "test": "npm run test:utils && jest tests" }, "husky": { "hooks": { From 06d264b99d2bd38f2dc5e739ca28c2d24076a42e Mon Sep 17 00:00:00 2001 From: mmarkelov Date: Sun, 9 Feb 2020 15:32:47 +0300 Subject: [PATCH 8/8] Update Readme --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 18407037..16155db2 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,13 @@ Running your tests using [Jest](https://github.com/facebook/jest) & [Playwright] npm install jest-playwright-preset playwright ``` +Also you can use `jest-playwright-preset` with specific playwright packages: +`playwright-webkit`, `playwright-chromium` and `playwright-firefox` + +``` +npm install jest-playwright-preset playwright-firefox +``` + ## Usage Update your Jest configuration: @@ -47,6 +54,7 @@ You can specify a `jest-playwright.config.js` at the root of the project or defi ## Browser type You can specify browser in multiple ways: +**Note**: You should do it only if you are using whole playwright package - With `BROWSER` environment variable - With your `jest-playwright.config.js` @@ -56,7 +64,7 @@ If you don't pass any value it will be use `chromium` as default Use Playwright in your tests: ```json -"test": "BROWSER=chromium jest" +"test": "jest" ``` ```js