Skip to content

Commit 2a785b0

Browse files
committed
2 parents 160d7e0 + cc768ef commit 2a785b0

File tree

6 files changed

+194
-58
lines changed

6 files changed

+194
-58
lines changed

README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,32 @@ module.exports = {
122122
}
123123
```
124124

125+
From version **0.0.13** you can run you tests for multiple devices.
126+
127+
```javascript
128+
module.exports = {
129+
devices: ["iPhone 6", "Pixel 2"],
130+
...
131+
}
132+
```
133+
134+
It will run your tests depending on you playwright package.
135+
136+
- If you are using specific playwright package, it will run test for this specific browser
137+
- With installed **playwright** package you can define browsers with config:
138+
139+
```javascript
140+
module.exports = {
141+
browsers: ["chromium", "firefox"],
142+
devices: ["iPhone 6", "Pixel 2"],
143+
...
144+
}
145+
```
146+
147+
If there is no defined browsers in config it will run tests for chromium browser.
148+
149+
[More details](https://github.com/mmarkelov/jest-playwright/pull/54#issuecomment-592514337)
150+
125151
- You must run your tests with **jest-playwright**
126152

127153
```json

src/bin/testProcess.ts

Lines changed: 74 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,97 @@
11
import { spawn, spawnSync, SpawnSyncOptions } from 'child_process'
2-
import { readConfig } from '../utils'
3-
import { checkBrowsers, getResultByStatus } from './utils'
4-
import { PARALLEL, BrowserType } from '../constants'
2+
import {
3+
checkBrowserEnv,
4+
getBrowserType,
5+
readConfig,
6+
readPackage,
7+
} from '../utils'
8+
import { checkCommand, getExitCode, getLogMessage } from './utils'
9+
import { BrowserType, CORE, PARALLEL, PLAYWRIGHT } from '../constants'
510

6-
const getSpawnOptions = (browser: BrowserType): SpawnSyncOptions => ({
11+
const getSpawnOptions = (
12+
browser: BrowserType,
13+
device: string | null,
14+
): SpawnSyncOptions => ({
715
stdio: 'inherit',
816
shell: true,
917
env: {
1018
...process.env,
1119
BROWSER: browser,
20+
...(device ? { DEVICE: device } : {}),
1221
},
1322
})
1423

1524
const exec = ({
1625
sequence,
1726
browser,
27+
device = null,
1828
params,
1929
}: {
2030
sequence: string
2131
browser: BrowserType
32+
device?: string | null
2233
params: string[]
23-
}): void => {
24-
const options = getSpawnOptions(browser)
25-
if (sequence === PARALLEL) {
26-
const process = spawn(
27-
'node',
28-
[`node_modules/jest/bin/jest.js ${params}`],
29-
options,
30-
)
31-
process.on('close', status => {
32-
console.log(`${getResultByStatus(status)} tests for ${browser}\n\n`)
33-
})
34-
} else {
35-
const { status } = spawnSync(
36-
'node',
37-
[`node_modules/jest/bin/jest.js ${params}`],
38-
options,
39-
)
40-
console.log(`${getResultByStatus(status)} tests for ${browser}`)
41-
}
42-
}
34+
}): Promise<number | null> =>
35+
new Promise(resolve => {
36+
const options = getSpawnOptions(browser, device)
37+
if (sequence === PARALLEL) {
38+
const process = spawn(
39+
'node',
40+
[`node_modules/jest/bin/jest.js ${params}`],
41+
options,
42+
)
43+
process.on('close', status => {
44+
console.log(getLogMessage(browser, status, device))
45+
resolve(status)
46+
})
47+
} else {
48+
const { status } = spawnSync(
49+
'node',
50+
[`node_modules/jest/bin/jest.js ${params}`],
51+
options,
52+
)
53+
console.log(getLogMessage(browser, status, device))
54+
resolve(status)
55+
}
56+
})
4357

4458
const runner = async (sequence: string, params: string[]): Promise<void> => {
45-
const { browsers = [] } = await readConfig()
46-
checkBrowsers(browsers)
47-
browsers.forEach(browser => exec({ sequence, browser, params }))
59+
const { browsers = [], devices = [] } = await readConfig()
60+
let exitCodes: (number | null)[] = []
61+
checkCommand(browsers, devices)
62+
if (!browsers.length && devices.length) {
63+
let browserType: BrowserType
64+
const browser = await readPackage()
65+
if (browser === PLAYWRIGHT || browser === CORE) {
66+
const config = await readConfig()
67+
browserType = getBrowserType(config)
68+
checkBrowserEnv(browserType)
69+
} else {
70+
browserType = browser
71+
}
72+
exitCodes = await Promise.all(
73+
devices.map(device =>
74+
exec({ sequence, browser: browserType, device, params }),
75+
),
76+
)
77+
}
78+
if (browsers.length) {
79+
if (devices.length) {
80+
const multipleCodes = await Promise.all(
81+
browsers.map(browser =>
82+
Promise.all(
83+
devices.map(device => exec({ sequence, browser, device, params })),
84+
),
85+
),
86+
)
87+
exitCodes = multipleCodes.reduce((acc, val) => acc.concat(val), [])
88+
} else {
89+
exitCodes = await Promise.all(
90+
browsers.map(browser => exec({ sequence, browser, params })),
91+
)
92+
}
93+
}
94+
getExitCode(exitCodes)
4895
}
4996

5097
export default runner

src/bin/utils.test.ts

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
import { checkBrowsers, getResultByStatus } from './utils'
1+
import {
2+
checkCommand,
3+
getResultByStatus,
4+
getLogMessage,
5+
getExitCode,
6+
} from './utils'
27
import { BrowserType } from '../constants'
38

4-
describe('checkBrowsers', () => {
5-
it('should throw an error without arguments', () => {
6-
expect(() => checkBrowsers()).toThrow(
7-
'You should define browsers with your jest-playwright.config.js',
8-
)
9-
})
10-
it('should throw an error when passed empty array', () => {
11-
expect(() => checkBrowsers([])).toThrow(
12-
'You should define browsers with your jest-playwright.config.js',
9+
describe('checkCommand', () => {
10+
it('should throw an error with empty browsers and devices', () => {
11+
expect(() => checkCommand([], [])).toThrow(
12+
'You should define browsers or devices with your jest-playwright.config.js',
1313
)
1414
})
15+
1516
it('should throw an error when passed wrong browser', () => {
16-
expect(() =>
17-
checkBrowsers(['chromium', 'unknown' as BrowserType]),
18-
).toThrow()
17+
expect(() => checkCommand(['unknown' as BrowserType], [])).toThrow()
1918
})
2019
})
2120

@@ -32,3 +31,33 @@ describe('getResultByStatus', () => {
3231
expect(getResultByStatus(0)).toBe('Passed')
3332
})
3433
})
34+
35+
describe('getLogMessage', () => {
36+
it('should return right log', () => {
37+
expect(getLogMessage('chromium', 0, null)).toBe(
38+
'Passed tests for browser: chromium \n\n',
39+
)
40+
})
41+
42+
it('should return right log', () => {
43+
expect(getLogMessage('chromium', 1, 'iPhone 6')).toBe(
44+
'Failed tests for browser: chromium and device: iPhone 6\n\n',
45+
)
46+
})
47+
})
48+
49+
describe('getExitCode', () => {
50+
const mockExit = jest.spyOn(process, 'exit').mockImplementation(() => {
51+
return undefined as never
52+
})
53+
54+
it('should exit with code 1 for some failed tests', () => {
55+
getExitCode([0, 0, 1, null])
56+
expect(mockExit).toHaveBeenCalledWith(1)
57+
})
58+
59+
it('should exit with code 0 for passed tests', () => {
60+
getExitCode([0, 0, 0, 0])
61+
expect(mockExit).toHaveBeenCalledWith(0)
62+
})
63+
})

src/bin/utils.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,39 @@
11
import { checkBrowserEnv } from '../utils'
22
import { BrowserType } from '../constants'
33

4-
export const checkBrowsers = (browsers?: BrowserType[]): void => {
5-
if (!browsers || !browsers.length) {
4+
export const checkCommand = (
5+
browsers: BrowserType[],
6+
devices: string[],
7+
): void => {
8+
if (!browsers.length && !devices.length) {
69
throw new Error(
7-
'You should define browsers with your jest-playwright.config.js',
10+
'You should define browsers or devices with your jest-playwright.config.js',
811
)
912
}
1013
browsers.forEach(checkBrowserEnv)
14+
// TODO Add check for devices
15+
// devices.forEach(checkDeviceEnv)
1116
}
1217

1318
export const getResultByStatus = (status: number | null): string => {
1419
return status !== 0 ? 'Failed' : 'Passed'
1520
}
21+
22+
export const getLogMessage = (
23+
browser: BrowserType,
24+
status: number | null,
25+
device: string | null,
26+
): string => {
27+
return `${getResultByStatus(status)} tests for browser: ${browser} ${
28+
device ? `and device: ${device}` : ''
29+
}\n\n`
30+
}
31+
32+
export const getExitCode = (exitCodes: (number | null)[]): void => {
33+
if (exitCodes.every(code => code === 0)) {
34+
process.exit(0)
35+
} else {
36+
console.log('One of the test has not passed successfully')
37+
process.exit(1)
38+
}
39+
}

src/constants.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ import { LaunchOptions } from 'playwright-core/lib/server/browserType'
22
import { BrowserContextOptions } from 'playwright-core/lib/browserContext'
33
import { JestDevServerOptions } from 'jest-dev-server'
44

5-
export type BrowserType = 'chromium' | 'firefox' | 'webkit'
5+
export const CORE = 'core'
6+
export const PLAYWRIGHT = 'playwright'
67

7-
export const CHROMIUM: BrowserType = 'chromium'
8-
export const FIREFOX: BrowserType = 'firefox'
9-
export const WEBKIT: BrowserType = 'webkit'
8+
export const CHROMIUM = 'chromium'
9+
export const FIREFOX = 'firefox'
10+
export const WEBKIT = 'webkit'
11+
12+
export type BrowserType = typeof CHROMIUM | typeof FIREFOX | typeof WEBKIT
13+
14+
export type PlaywrightRequireType =
15+
| BrowserType
16+
| typeof PLAYWRIGHT
17+
| typeof CORE
1018

1119
export const PARALLEL = '--parallel'
1220

@@ -17,6 +25,7 @@ export interface Config {
1725
browser?: BrowserType
1826
browsers?: BrowserType[]
1927
device?: string
28+
devices?: string[]
2029
server?: JestDevServerOptions
2130
}
2231

src/utils.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@ import fs from 'fs'
22
import path from 'path'
33
import { promisify } from 'util'
44
import {
5+
BrowserType,
56
CHROMIUM,
7+
Config,
8+
CORE,
9+
DEFAULT_CONFIG,
610
FIREFOX,
11+
PLAYWRIGHT,
12+
PlaywrightRequireType,
713
WEBKIT,
8-
DEFAULT_CONFIG,
9-
Config,
10-
BrowserType,
1114
} from './constants'
1215
import { BrowserType as PlayWrightBrowserType } from 'playwright'
1316

1417
const exists = promisify(fs.exists)
1518

16-
type PlaywrightRequireType = BrowserType | 'core' | 'playwright'
17-
1819
const checkDependencies = (
1920
dependencies: Record<string, string>,
2021
): PlaywrightRequireType | null => {
2122
if (!dependencies) return null
22-
if (dependencies.playwright) return 'playwright'
23-
if (dependencies['playwright-core']) return 'core'
23+
if (dependencies.playwright) return PLAYWRIGHT
24+
if (dependencies[`playwright-${CORE}`]) return CORE
2425
if (dependencies[`playwright-${CHROMIUM}`]) return CHROMIUM
2526
if (dependencies[`playwright-${FIREFOX}`]) return FIREFOX
2627
if (dependencies[`playwright-${WEBKIT}`]) return WEBKIT
@@ -68,7 +69,7 @@ export const readPackage = async (): Promise<PlaywrightRequireType> => {
6869
const packageConfig = await require(absConfigPath)
6970
// for handling the local tests
7071
if (packageConfig.name === 'jest-playwright-preset') {
71-
return 'core'
72+
return CORE
7273
}
7374
const playwright =
7475
checkDependencies(packageConfig.dependencies) ||
@@ -83,11 +84,11 @@ export const getPlaywrightInstance = async (
8384
browserType: BrowserType,
8485
): Promise<PlayWrightBrowserType> => {
8586
const playwrightPackage = await readPackage()
86-
if (playwrightPackage === 'playwright') {
87+
if (playwrightPackage === PLAYWRIGHT) {
8788
return require('playwright')[browserType]
8889
}
89-
if (playwrightPackage === 'core') {
90-
const browser = require('playwright-core')[browserType]
90+
if (playwrightPackage === CORE) {
91+
const browser = require(`playwright-${CORE}`)[browserType]
9192
await browser.downloadBrowserIfNeeded()
9293
return browser
9394
}

0 commit comments

Comments
 (0)