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 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 fbef854d..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": { @@ -38,8 +39,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", diff --git a/src/PlaywrightEnvironment.js b/src/PlaywrightEnvironment.js index 95d8f86f..41b46106 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) @@ -32,13 +36,12 @@ 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 } = config - browserPerProcess = await playwright[browserType].launch(launchBrowserApp) + browserPerProcess = await playwrightInstance.launch(launchBrowserApp) } return browserPerProcess } @@ -58,21 +61,24 @@ class PlaywrightEnvironment extends NodeEnvironment { async setup() { resetBrowserCloseWatchdog() const config = await readConfig() + const browserType = getBrowserType(config) + checkBrowserEnv(browserType) const { device, context } = config + const playwrightInstance = await getPlaywrightInstance(browserType) 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 } } } - 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) diff --git a/src/utils.js b/src/utils.js index c8587025..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,6 +30,30 @@ export function getBrowserType(config) { return config.browser || CHROMIUM } +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-dynamic-require + return require(playwrightPackage) +} + export async function readConfig() { const defaultConfig = DEFAULT_CONFIG 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') + }) +})