Skip to content

Commit

Permalink
Merge 82c6125 into 28670ea
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarkelov authored Mar 1, 2020
2 parents 28670ea + 82c6125 commit 97b1b87
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 47 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,32 @@ module.exports = {
}
```

From version **0.0.13** you can run you tests for multiple devices.

```javascript
module.exports = {
devices: ["iPhone 6", "Pixel 2"],
...
}
```

It will run your tests depending on you playwright package.

- If you are using specific playwright package, it will run test for this specific browser
- With installed **playwright** package you can define browsers with config:

```javascript
module.exports = {
browsers: ["chromium", "firefox"],
devices: ["iPhone 6", "Pixel 2"],
...
}
```

If there is no defined browsers in config it will run tests for chromium browser.

[More details](https://github.com/mmarkelov/jest-playwright/pull/54#issuecomment-592514337)

- You must run your tests with **jest-playwright**

```json
Expand Down
69 changes: 53 additions & 16 deletions src/bin/testProcess.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,47 @@
import { spawn, spawnSync, SpawnSyncOptions } from 'child_process'
import { readConfig } from '../utils'
import { checkBrowsers, getResultByStatus } from './utils'
import { PARALLEL, BrowserType } from '../constants'
import {
checkBrowserEnv,
getBrowserType,
readConfig,
readPackage,
} from '../utils'
import { checkCommand, getExitCode, getLogMessage } from './utils'
import { BrowserType, CORE, PARALLEL, PLAYWRIGHT } from '../constants'

const getSpawnOptions = (browser: BrowserType): SpawnSyncOptions => ({
const getSpawnOptions = (
browser: BrowserType,
device: string | null,
): SpawnSyncOptions => ({
stdio: 'inherit',
shell: true,
env: {
...process.env,
BROWSER: browser,
...(device ? { DEVICE: device } : {}),
},
})

const exec = ({
sequence,
browser,
device = null,
params,
}: {
sequence: string
browser: BrowserType
device?: string | null
params: string[]
}): Promise<number | null> =>
new Promise(resolve => {
const options = getSpawnOptions(browser)
const options = getSpawnOptions(browser, device)
if (sequence === PARALLEL) {
const process = spawn(
'node',
[`node_modules/jest/bin/jest.js ${params}`],
options,
)
process.on('close', status => {
console.log(`${getResultByStatus(status)} tests for ${browser}\n\n`)
console.log(getLogMessage(browser, status, device))
resolve(status)
})
} else {
Expand All @@ -39,22 +50,48 @@ const exec = ({
[`node_modules/jest/bin/jest.js ${params}`],
options,
)
console.log(`${getResultByStatus(status)} tests for ${browser}`)
console.log(getLogMessage(browser, status, device))
resolve(status)
}
})

const runner = async (sequence: string, params: string[]): Promise<void> => {
const { browsers = [] } = await readConfig()
checkBrowsers(browsers)
const exitCodes = await Promise.all(
browsers.map(browser => exec({ sequence, browser, params })),
)
if (exitCodes.every(code => code === 0)) {
process.exit(0)
} else {
process.exit(1)
const { browsers = [], devices = [] } = await readConfig()
let exitCodes: (number | null)[] = []
checkCommand(browsers, devices)
if (!browsers.length && devices.length) {
let browserType: BrowserType
const browser = await readPackage()
if (browser === PLAYWRIGHT || browser === CORE) {
const config = await readConfig()
browserType = getBrowserType(config)
checkBrowserEnv(browserType)
} else {
browserType = browser
}
exitCodes = await Promise.all(
devices.map(device =>
exec({ sequence, browser: browserType, device, params }),
),
)
}
if (browsers.length) {
if (devices.length) {
const multipleCodes = await Promise.all(
browsers.map(browser =>
Promise.all(
devices.map(device => exec({ sequence, browser, device, params })),
),
),
)
exitCodes = multipleCodes.reduce((acc, val) => acc.concat(val), [])
} else {
exitCodes = await Promise.all(
browsers.map(browser => exec({ sequence, browser, params })),
)
}
}
getExitCode(exitCodes)
}

export default runner
55 changes: 42 additions & 13 deletions src/bin/utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import { checkBrowsers, getResultByStatus } from './utils'
import {
checkCommand,
getResultByStatus,
getLogMessage,
getExitCode,
} from './utils'
import { BrowserType } from '../constants'

describe('checkBrowsers', () => {
it('should throw an error without arguments', () => {
expect(() => checkBrowsers()).toThrow(
'You should define browsers with your jest-playwright.config.js',
)
})
it('should throw an error when passed empty array', () => {
expect(() => checkBrowsers([])).toThrow(
'You should define browsers with your jest-playwright.config.js',
describe('checkCommand', () => {
it('should throw an error with empty browsers and devices', () => {
expect(() => checkCommand([], [])).toThrow(
'You should define browsers or devices with your jest-playwright.config.js',
)
})

it('should throw an error when passed wrong browser', () => {
expect(() =>
checkBrowsers(['chromium', 'unknown' as BrowserType]),
).toThrow()
expect(() => checkCommand(['unknown' as BrowserType], [])).toThrow()
})
})

Expand All @@ -32,3 +31,33 @@ describe('getResultByStatus', () => {
expect(getResultByStatus(0)).toBe('Passed')
})
})

describe('getLogMessage', () => {
it('should return right log', () => {
expect(getLogMessage('chromium', 0, null)).toBe(
'Passed tests for browser: chromium \n\n',
)
})

it('should return right log', () => {
expect(getLogMessage('chromium', 1, 'iPhone 6')).toBe(
'Failed tests for browser: chromium and device: iPhone 6\n\n',
)
})
})

describe('getExitCode', () => {
const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {
return undefined as never
})

it('should exit with code 1 for some failed tests', () => {
getExitCode([0, 0, 1, null])
expect(mockExit).toHaveBeenCalledWith(1)
})

it('should exit with code 0 for passed tests', () => {
getExitCode([0, 0, 0, 0])
expect(mockExit).toHaveBeenCalledWith(0)
})
})
30 changes: 27 additions & 3 deletions src/bin/utils.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
import { checkBrowserEnv } from '../utils'
import { BrowserType } from '../constants'

export const checkBrowsers = (browsers?: BrowserType[]): void => {
if (!browsers || !browsers.length) {
export const checkCommand = (
browsers: BrowserType[],
devices: string[],
): void => {
if (!browsers.length && !devices.length) {
throw new Error(
'You should define browsers with your jest-playwright.config.js',
'You should define browsers or devices with your jest-playwright.config.js',
)
}
browsers.forEach(checkBrowserEnv)
// TODO Add check for devices
// devices.forEach(checkDeviceEnv)
}

export const getResultByStatus = (status: number | null): string => {
return status !== 0 ? 'Failed' : 'Passed'
}

export const getLogMessage = (
browser: BrowserType,
status: number | null,
device: string | null,
): string => {
return `${getResultByStatus(status)} tests for browser: ${browser} ${
device ? `and device: ${device}` : ''
}\n\n`
}

export const getExitCode = (exitCodes: (number | null)[]): void => {
if (exitCodes.every(code => code === 0)) {
process.exit(0)
} else {
console.log('One of the test has not passed successfully')
process.exit(1)
}
}
17 changes: 13 additions & 4 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import { LaunchOptions } from 'playwright-core/lib/server/browserType'
import { BrowserContextOptions } from 'playwright-core/lib/browserContext'
import { JestDevServerOptions } from 'jest-dev-server'

export type BrowserType = 'chromium' | 'firefox' | 'webkit'
export const CORE = 'core'
export const PLAYWRIGHT = 'playwright'

export const CHROMIUM: BrowserType = 'chromium'
export const FIREFOX: BrowserType = 'firefox'
export const WEBKIT: BrowserType = 'webkit'
export const CHROMIUM = 'chromium'
export const FIREFOX = 'firefox'
export const WEBKIT = 'webkit'

export type BrowserType = typeof CHROMIUM | typeof FIREFOX | typeof WEBKIT

export type PlaywrightRequireType =
| BrowserType
| typeof PLAYWRIGHT
| typeof CORE

export const PARALLEL = '--parallel'

Expand All @@ -17,6 +25,7 @@ export interface Config {
browser?: BrowserType
browsers?: BrowserType[]
device?: string
devices?: string[]
server?: JestDevServerOptions
}

Expand Down
23 changes: 12 additions & 11 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,26 @@ import fs from 'fs'
import path from 'path'
import { promisify } from 'util'
import {
BrowserType,
CHROMIUM,
Config,
CORE,
DEFAULT_CONFIG,
FIREFOX,
PLAYWRIGHT,
PlaywrightRequireType,
WEBKIT,
DEFAULT_CONFIG,
Config,
BrowserType,
} from './constants'
import { BrowserType as PlayWrightBrowserType } from 'playwright'

const exists = promisify(fs.exists)

type PlaywrightRequireType = BrowserType | 'core' | 'playwright'

const checkDependencies = (
dependencies: Record<string, string>,
): PlaywrightRequireType | null => {
if (!dependencies) return null
if (dependencies.playwright) return 'playwright'
if (dependencies['playwright-core']) return 'core'
if (dependencies.playwright) return PLAYWRIGHT
if (dependencies[`playwright-${CORE}`]) return CORE
if (dependencies[`playwright-${CHROMIUM}`]) return CHROMIUM
if (dependencies[`playwright-${FIREFOX}`]) return FIREFOX
if (dependencies[`playwright-${WEBKIT}`]) return WEBKIT
Expand Down Expand Up @@ -68,7 +69,7 @@ export const readPackage = async (): Promise<PlaywrightRequireType> => {
const packageConfig = await require(absConfigPath)
// for handling the local tests
if (packageConfig.name === 'jest-playwright-preset') {
return 'core'
return CORE
}
const playwright =
checkDependencies(packageConfig.dependencies) ||
Expand All @@ -83,11 +84,11 @@ export const getPlaywrightInstance = async (
browserType: BrowserType,
): Promise<PlayWrightBrowserType> => {
const playwrightPackage = await readPackage()
if (playwrightPackage === 'playwright') {
if (playwrightPackage === PLAYWRIGHT) {
return require('playwright')[browserType]
}
if (playwrightPackage === 'core') {
const browser = require('playwright-core')[browserType]
if (playwrightPackage === CORE) {
const browser = require(`playwright-${CORE}`)[browserType]
await browser.downloadBrowserIfNeeded()
return browser
}
Expand Down

0 comments on commit 97b1b87

Please sign in to comment.