Skip to content
This repository was archived by the owner on Sep 11, 2025. It is now read-only.

Commit 0f6ff1b

Browse files
authored
Fix debug functions (#525)
* Add information about shadow dom selectors * Fix debug functions * Fix tests * Added test for jestPlaywrightDebug * Some improvements * Env improvements * Fix viewport type * Using Nullable type * Simplify define new context options in resetContext function
1 parent 0bf57da commit 0f6ff1b

File tree

8 files changed

+274
-113
lines changed

8 files changed

+274
-113
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ You can use this snippet to reset current browser for each individual test. It w
242242

243243
## Debug helper functions
244244

245-
`jest-playwright` provides some functions to debug your tests
245+
`jest-playwright` provides some functions to debug your tests.
246+
247+
**IMPORTANT NOTE**: For these kind of tests you should use properties passed through callback function instead of [globals](https://github.com/playwright-community/jest-playwright#globals)
246248

247249
### jestPlaywrightDebug
248250

@@ -275,14 +277,15 @@ module.exports = {
275277
### jestPlaywrightConfig
276278

277279
This helper function provide you ability to run specific tests with passed options.
280+
You can define `browser` and `device` properties to run test for them, otherwise test run for current configuration.
278281

279282
```js
280283
test.jestPlaywrightConfig(
281284
{
282285
// your jest-playwright options
283286
},
284287
'test name',
285-
async () => {
288+
async ({ browser, context, page }) => {
286289
/* ... */
287290
},
288291
)

e2e/more.test.ts

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,51 @@ describe('Example setContext test', () => {
1414
expect(element).toBeTruthy()
1515
},
1616
)
17-
describe.jestPlaywrightSkip(
18-
{ browsers: ['chromium'] },
19-
'can skip describe block',
20-
() => {
21-
it('should be able to execute javascript 1', async () => {
22-
page.setContent(`<script>document.write("test")</script>`)
23-
const element = await page.waitForSelector('text=test')
24-
expect(element).toBeTruthy()
25-
})
17+
})
18+
19+
describe.jestPlaywrightSkip(
20+
{ browsers: ['chromium'] },
21+
'Can skip describe block',
22+
() => {
23+
it('should be able to execute javascript 1', async () => {
24+
page.setContent(`<script>document.write("test")</script>`)
25+
const element = await page.waitForSelector('text=test')
26+
expect(element).toBeTruthy()
27+
})
28+
},
29+
)
30+
31+
describe('Debug helper functions', () => {
32+
const configOptions = {
33+
contextOptions: { locale: 'nl-NL' },
34+
browser: 'webkit',
35+
}
36+
37+
it.jestPlaywrightConfig(
38+
configOptions,
39+
'jestPlaywrightConfig',
40+
async ({ page }) => {
41+
await page.goto('https://www.whatismybrowser.com/')
42+
const browser = await (await page.$('.string-major'))?.innerHTML()
43+
expect(browser).toContain('Safari')
44+
},
45+
)
46+
47+
const debugOptions = {
48+
launchOptions: {
49+
devtools: false,
50+
headless: true,
51+
},
52+
browser: 'firefox',
53+
}
54+
55+
it.jestPlaywrightDebug(
56+
debugOptions,
57+
'jestPlaywrightDebug',
58+
async ({ page }) => {
59+
await page.goto('https://www.whatismybrowser.com/')
60+
const browser = await (await page.$('.string-major'))?.innerHTML()
61+
expect(browser).toContain('Firefox')
2662
},
2763
)
2864
})

src/PlaywrightEnvironment.ts

Lines changed: 129 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* eslint-disable no-console */
1+
/* eslint-disable no-console, @typescript-eslint/no-unused-vars */
22
import type { Event, State } from 'jest-circus'
33
import type {
44
Browser,
@@ -8,25 +8,31 @@ import type {
88
} from 'playwright-core'
99
import type {
1010
BrowserType,
11+
ConfigDeviceType,
1112
ConfigParams,
1213
ConnectOptions,
1314
GenericBrowser,
1415
JestPlaywrightConfig,
1516
JestPlaywrightProjectConfig,
17+
Nullable,
18+
Playwright,
19+
TestPlaywrightConfigOptions,
1620
} from '../types/global'
1721
import {
1822
CHROMIUM,
23+
CONFIG_ENVIRONMENT_NAME,
24+
DEFAULT_CONFIG,
1925
FIREFOX,
2026
IMPORT_KIND_PLAYWRIGHT,
2127
PERSISTENT,
2228
LAUNCH,
23-
CONFIG_ENVIRONMENT_NAME,
2429
} from './constants'
2530
import {
2631
deepMerge,
2732
formatError,
2833
getBrowserOptions,
2934
getBrowserType,
35+
getDeviceBrowserType,
3036
getDeviceType,
3137
getPlaywrightInstance,
3238
} from './utils'
@@ -72,6 +78,36 @@ const getBrowserPerProcess = async (
7278
return playwrightInstance.connect(options)
7379
}
7480

81+
const getDeviceConfig = (
82+
device: Nullable<ConfigDeviceType> | undefined,
83+
availableDevices: Playwright['devices'],
84+
): BrowserContextOptions => {
85+
if (device) {
86+
if (typeof device === 'string') {
87+
const { defaultBrowserType, ...deviceProps } = availableDevices[device]
88+
return deviceProps
89+
} else {
90+
const { name, defaultBrowserType, ...deviceProps } = device
91+
return deviceProps
92+
}
93+
}
94+
return {}
95+
}
96+
97+
const getDeviceName = (
98+
device: Nullable<ConfigDeviceType>,
99+
): Nullable<string> => {
100+
let deviceName: Nullable<string> = null
101+
if (device != null) {
102+
if (typeof device === 'string') {
103+
deviceName = device
104+
} else {
105+
deviceName = device.name
106+
}
107+
}
108+
return deviceName
109+
}
110+
75111
export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
76112
const RootEnv = require(basicEnv === 'node'
77113
? 'jest-environment-node'
@@ -86,6 +122,65 @@ export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
86122
this._config = config
87123
}
88124

125+
_getSeparateEnvBrowserConfig(
126+
isDebug: boolean,
127+
config: TestPlaywrightConfigOptions,
128+
): JestPlaywrightConfig {
129+
const { debugOptions } = this._jestPlaywrightConfig
130+
const defaultBrowserConfig: JestPlaywrightConfig = {
131+
...DEFAULT_CONFIG,
132+
launchType: LAUNCH,
133+
}
134+
let resultBrowserConfig: JestPlaywrightConfig = deepMerge(
135+
defaultBrowserConfig,
136+
config,
137+
)
138+
if (isDebug) {
139+
if (debugOptions) {
140+
resultBrowserConfig = deepMerge(resultBrowserConfig, debugOptions)
141+
}
142+
} else {
143+
resultBrowserConfig = deepMerge(
144+
this._jestPlaywrightConfig,
145+
resultBrowserConfig,
146+
)
147+
}
148+
return resultBrowserConfig
149+
}
150+
151+
_getSeparateEnvContextConfig(
152+
isDebug: boolean,
153+
config: TestPlaywrightConfigOptions,
154+
browserName: BrowserType,
155+
devices: Playwright['devices'],
156+
): BrowserContextOptions {
157+
const { device, contextOptions } = config
158+
const { debugOptions } = this._jestPlaywrightConfig
159+
const deviceContextOptions: BrowserContextOptions = getDeviceConfig(
160+
device,
161+
devices,
162+
)
163+
let resultContextOptions: BrowserContextOptions = contextOptions || {}
164+
if (isDebug) {
165+
if (debugOptions?.contextOptions) {
166+
resultContextOptions = deepMerge(
167+
resultContextOptions,
168+
debugOptions.contextOptions!,
169+
)
170+
}
171+
} else {
172+
resultContextOptions = deepMerge(
173+
this._jestPlaywrightConfig.contextOptions!,
174+
resultContextOptions,
175+
)
176+
}
177+
resultContextOptions = deepMerge(
178+
deviceContextOptions,
179+
resultContextOptions,
180+
)
181+
return getBrowserOptions(browserName, resultContextOptions)
182+
}
183+
89184
async setup(): Promise<void> {
90185
const { wsEndpoint, browserName, testEnvironmentOptions } = this._config
91186
this._jestPlaywrightConfig = testEnvironmentOptions[
@@ -97,7 +192,6 @@ export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
97192
exitOnPageError,
98193
selectors,
99194
launchType,
100-
debugOptions,
101195
skipInitialization,
102196
} = this._jestPlaywrightConfig
103197
if (wsEndpoint) {
@@ -112,41 +206,32 @@ export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
112206
this._jestPlaywrightConfig.contextOptions,
113207
)
114208
const device = getDeviceType(this._config.device)
115-
let deviceName: string | null = null
209+
const deviceName: Nullable<string> = getDeviceName(device)
116210
const {
117211
name,
118212
instance: playwrightInstance,
119213
devices,
120214
} = getPlaywrightInstance(browserType)
121215

122216
if (name === IMPORT_KIND_PLAYWRIGHT) {
123-
// eslint-disable-next-line @typescript-eslint/no-var-requires
124217
const playwright = require('playwright')
125218
if (selectors) {
126219
await Promise.all(
127-
selectors.map(({ name, script }) => {
128-
return playwright.selectors
220+
selectors.map(({ name, script }) =>
221+
playwright.selectors
129222
.register(name, script)
130223
.catch((e: Error): void => {
131224
if (!e.toString().includes('has been already')) {
132225
throw e
133226
}
134-
})
135-
}),
227+
}),
228+
),
136229
)
137230
}
138231
}
139232

140-
if (device != null) {
141-
if (typeof device === 'string') {
142-
deviceName = device
143-
contextOptions = { ...devices[device], ...contextOptions }
144-
} else {
145-
const { name, ...deviceProps } = device
146-
deviceName = name
147-
contextOptions = { ...deviceProps, ...contextOptions }
148-
}
149-
}
233+
const deviceBrowserContextOptions = getDeviceConfig(device, devices)
234+
contextOptions = deepMerge(deviceBrowserContextOptions, contextOptions)
150235
if (browserType === FIREFOX && contextOptions.isMobile) {
151236
console.warn(formatError(`isMobile is not supported in ${FIREFOX}.`))
152237
delete contextOptions.isMobile
@@ -184,37 +269,32 @@ export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
184269
}
185270
this.global.jestPlaywright = {
186271
configSeparateEnv: async (
187-
config: JestPlaywrightConfig,
188-
isDebug?: boolean,
272+
config: TestPlaywrightConfigOptions,
273+
isDebug = false,
189274
): Promise<ConfigParams> => {
190-
let resultBrowserConfig: JestPlaywrightConfig
191-
let resultContextOptions: BrowserContextOptions | undefined
192-
if (isDebug) {
193-
resultBrowserConfig = debugOptions
194-
? deepMerge(config, debugOptions)
195-
: config
196-
resultContextOptions = debugOptions?.contextOptions
197-
? deepMerge(config.contextOptions!, debugOptions.contextOptions!)
198-
: config.contextOptions
199-
} else {
200-
resultBrowserConfig = deepMerge(this._jestPlaywrightConfig, config)
201-
resultContextOptions = {
202-
...this._jestPlaywrightConfig.contextOptions,
203-
...config.contextOptions,
204-
}
205-
}
206-
resultBrowserConfig.launchType = LAUNCH
207-
const browser = await getBrowserPerProcess(
208-
playwrightInstance as GenericBrowser,
209-
browserType,
210-
resultBrowserConfig,
275+
const { device } = config
276+
const browserName =
277+
config.useDefaultBrowserType && device
278+
? getDeviceBrowserType(device, devices)
279+
: config.browser || browserType
280+
const resultBrowserConfig: JestPlaywrightConfig = this._getSeparateEnvBrowserConfig(
281+
isDebug,
282+
config,
211283
)
212-
const newContextOptions = getBrowserOptions(
284+
const resultContextOptions: BrowserContextOptions = this._getSeparateEnvContextConfig(
285+
isDebug,
286+
config,
213287
browserName,
214-
resultContextOptions,
288+
devices,
289+
)
290+
const { instance } = getPlaywrightInstance(browserName)
291+
const browser = await getBrowserPerProcess(
292+
instance as GenericBrowser,
293+
browserName,
294+
resultBrowserConfig,
215295
)
216296
const context = await (browser as Browser)!.newContext(
217-
newContextOptions,
297+
resultContextOptions,
218298
)
219299
const page = await context!.newPage()
220300
return { browser, context, page }
@@ -239,11 +319,9 @@ export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
239319

240320
await context?.close()
241321

242-
let newContextOptions = contextOptions
243-
244-
if (newOptions) {
245-
newContextOptions = { ...newContextOptions, ...newOptions }
246-
}
322+
const newContextOptions = newOptions
323+
? deepMerge(contextOptions, newOptions)
324+
: contextOptions
247325

248326
this.global.context = await browser.newContext(newContextOptions)
249327

@@ -277,11 +355,7 @@ export const getPlaywrightEnv = (basicEnv = 'node'): unknown => {
277355
const { stdin } = process
278356
const listening = stdin.listenerCount('data') > 0
279357
const onKeyPress = (key: string): void => {
280-
if (
281-
key === KEYS.CONTROL_C ||
282-
key === KEYS.CONTROL_D ||
283-
key === KEYS.ENTER
284-
) {
358+
if (Object.values(KEYS).includes(key)) {
285359
stdin.removeListener('data', onKeyPress)
286360
if (!listening) {
287361
if (stdin.isTTY) {

0 commit comments

Comments
 (0)