Skip to content

Commit 82e760f

Browse files
author
DavertMik
committed
Merge branch '4.x' of github.com:codeceptjs/CodeceptJS into 4.x
2 parents 4326bcc + fb1a602 commit 82e760f

39 files changed

Lines changed: 652 additions & 500 deletions

.mocharc.cjs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const path = require('path')
2+
3+
module.exports = {
4+
require: [path.join(__dirname, 'test', 'support', 'setup.mjs')],
5+
extension: ['js', 'mjs'],
6+
}

.mocharc.mjs

Lines changed: 0 additions & 10 deletions
This file was deleted.

docs/ai.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,9 @@ npx codeceptjs generate:heal
230230
Heal recipes should be included into `codecept.conf.js` or `codecept.conf.ts` config file:
231231

232232
```js
233+
import './heal.js'
233234

234-
require('./heal')
235-
236-
exports.config = {
235+
export const config = {
237236
// ... your codeceptjs config
238237
```
239238
@@ -491,8 +490,8 @@ It is recommended to try HTML processing on one of your web pages before launchi
491490
To do that open the common page of your application and using DevTools copy the outerHTML of `<html>` element. Don't use `Page Source` for that, as it may not include dynamically added HTML elements. Save this HTML into a file and create a NodeJS script:
492491
493492
```js
494-
const { removeNonInteractiveElements } = require('codeceptjs/lib/html')
495-
const fs = require('fs')
493+
import { removeNonInteractiveElements } from 'codeceptjs/lib/html'
494+
import fs from 'fs'
496495

497496
const htmlOpts = {
498497
interactiveElements: ['a', 'input', 'button', 'select', 'textarea', 'label', 'option'],

docs/api.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,12 @@ Or you can use the browser cookies if you are running browser session.
119119
In this case use `setSharedCookies()` from `@codeceptjs/configure` package:
120120

121121
```js
122-
const { setSharedCookies } = require('@codeceptjs/configure');
122+
import { setSharedCookies } from '@codeceptjs/configure'
123123

124-
// add this before exports.config
125-
setSharedCookies();
124+
// call before exporting config
125+
setSharedCookies()
126126

127-
exports.config = {
127+
export const config = {
128128
// ...
129129
helpers: {
130130
// also works with Playwright or Puppeteer

docs/basics.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,15 @@ import { setHeadlessWhen } from '@codeceptjs/configure'
387387
setHeadlessWhen(process.env.CI) // headless only on CI, show browser locally
388388
```
389389
390+
For a single run without editing config, use the `browser` plugin:
391+
392+
```sh
393+
npx codeceptjs run -p browser:show # force visible browser
394+
npx codeceptjs run -p browser:hide # force headless
395+
```
396+
397+
See [Plugin Arguments](/commands#plugin-arguments).
398+
390399
391400
## Configuration
392401

docs/bdd.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ Examples of tables using:
291291
| Chuck | Norris |
292292
```
293293
```js
294-
const { DataTableArgument } = require('codeceptjs');
294+
import { dataTableArgument as DataTableArgument } from 'codeceptjs';
295295
//...
296296
Given('I have a short employees card', (table) => {
297297
const dataTableArgument = new DataTableArgument(table);
@@ -309,7 +309,7 @@ Given('I have a short employees card', (table) => {
309309
| Harry | Potter | Seeker |
310310
```
311311
```js
312-
const { DataTableArgument } = require('codeceptjs');
312+
import { dataTableArgument as DataTableArgument } from 'codeceptjs';
313313
//...
314314
Given('I have an employee card', (table) => {
315315
const dataTableArgument = new DataTableArgument(table);
@@ -327,7 +327,7 @@ Given('I have an employee card', (table) => {
327327
| position | Seeker |
328328
```
329329
```js
330-
const { DataTableArgument } = require('codeceptjs');
330+
import { dataTableArgument as DataTableArgument } from 'codeceptjs';
331331
//...
332332
Given('I have a formatted employee card', (table) => {
333333
const dataTableArgument = new DataTableArgument(table);

docs/best.md

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ class CheckoutForm {
100100
}
101101

102102
}
103-
module.exports = new CheckoutForm();
104-
module.exports.CheckoutForm = CheckoutForm; // for inheritance
103+
export default new CheckoutForm();
104+
export { CheckoutForm }; // for inheritance
105105
```
106106

107107
* for components that are repeated accross a website (widgets) but don't belong to any page, use component objects. They are the same as page objects but focused only aroung one element:
@@ -143,8 +143,8 @@ class DatePicker {
143143
}
144144

145145

146-
module.exports = new DatePicker();
147-
module.exports.DatePicker = DatePicker; // for inheritance
146+
export default new DatePicker();
147+
export { DatePicker }; // for inheritance
148148
```
149149

150150
## Configuration
@@ -156,15 +156,15 @@ module.exports.DatePicker = DatePicker; // for inheritance
156156
* use `.env` files and dotenv package to load sensitive data
157157

158158
```js
159-
require('dotenv').config({ path: '.env' });
159+
import 'dotenv/config'
160160
```
161161

162162
* move similar parts in those configs by moving them to modules and putting them to `config` dir
163163
* when you need to load lots of page objects/components, you can get components/pageobjects file declaring them:
164164

165165
```js
166166
// inside config/components.js
167-
module.exports = {
167+
export default {
168168
DatePicker: "./components/datePicker",
169169
Dropdown: "./components/dropdown",
170170
}
@@ -173,10 +173,13 @@ module.exports = {
173173
include them like this:
174174

175175
```js
176+
import pages from './config/pages.js'
177+
import components from './config/components.js'
178+
176179
include: {
177180
I: './steps_file',
178-
...require('./config/pages'), // require POs and DOs for module
179-
...require('./config/components'), // require all components
181+
...pages, // import POs and DOs for module
182+
...components, // import all components
180183
},
181184
```
182185

@@ -215,9 +218,9 @@ include: {
215218
* When you need to customize access to API and go beyond what ApiDataFactory provides, implement DAO:
216219

217220
```js
218-
const { faker } = require('@faker-js/faker');
221+
import { faker } from '@faker-js/faker';
222+
import { output } from 'codeceptjs';
219223
const { I } = inject();
220-
const { output } = require('codeceptjs');
221224

222225
class InterfaceData {
223226

@@ -233,5 +236,5 @@ class InterfaceData {
233236
}
234237
}
235238

236-
module.exports = new InterfaceData;
239+
export default new InterfaceData;
237240
```

docs/commands.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,47 @@ Display complete debug output including scheduled promises
100100
DEBUG=codeceptjs:* npx codeceptjs run
101101
```
102102

103+
## Plugin Arguments
104+
105+
`run`, `run-workers`, `run-multiple`, `run-rerun` and `dry-run` accept a `-p` (`--plugins`) flag to enable plugins on the command line, with optional arguments per plugin. Tokens are colon-chained per plugin, comma-separated across plugins:
106+
107+
```sh
108+
npx codeceptjs run -p <name> # enable plugin
109+
npx codeceptjs run -p <name>:<arg1>:<arg2> # enable + pass args
110+
npx codeceptjs run -p <plugin1>,<plugin2>:<arg> # multiple plugins
111+
```
112+
113+
Plugins listed via `-p` are activated even when their config has `enabled: false` (or no `enabled` flag). This is the supported way to switch a plugin on for a single run without editing `codecept.conf`.
114+
115+
A few examples:
116+
117+
```sh
118+
npx codeceptjs run -p pauseOnFail # pause on first failure
119+
npx codeceptjs run -p pauseOn:step # pause before every step
120+
npx codeceptjs run -p pauseOn:url:/checkout/* # pause on URL match
121+
npx codeceptjs run -p stepByStepReport # produce a step-by-step HTML report
122+
```
123+
124+
### Browser Control
125+
126+
The built-in `browser` plugin overrides browser-helper config from the CLI — works for Playwright, Puppeteer, WebDriver and Appium without editing `codecept.conf`.
127+
128+
```sh
129+
npx codeceptjs run -p browser:show # force visible browser
130+
npx codeceptjs run -p browser:hide # force headless
131+
npx codeceptjs run -p browser:browser=firefox # switch engine
132+
npx codeceptjs run -p browser:windowSize=1024x768 # set viewport
133+
npx codeceptjs run -p browser:hide:browser=webkit:windowSize=800x600
134+
```
135+
136+
Tokens after `browser:` are either flags (`show`, `hide`) or `key=value` pairs. Three keys get per-helper translation:
137+
138+
- `browser=<name>` — Puppeteer receives `product`, Playwright/WebDriver receive `browser`. Validated per helper (`chromium`/`webkit`/`firefox` for Playwright, `chrome`/`firefox` for Puppeteer).
139+
- `show=true|false` (or the `show`/`hide` flag) — sets `show` on Playwright/Puppeteer; injects/strips `--headless` in WebDriver chrome/firefox capability args.
140+
- `windowSize=WxH` — sets `windowSize` on every helper; also adds `--window-size=W,H` to chromium/chrome args for Playwright/Puppeteer.
141+
142+
Anything else (`-p browser:video=false:waitForTimeout=10000`) is shallow-merged onto every browser helper present in config. Values are coerced (`true`/`false` → boolean, digits → Number, otherwise string).
143+
103144
## Run Workers
104145

105146
Run tests in parallel threads. CodeceptJS supports different distribution strategies for optimal performance.

docs/configuration.md

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ Create `codecept.conf.js` file and make it export `config` property.
119119
See the config example:
120120

121121
```js
122-
exports.config = {
122+
export const config = {
123123
helpers: {
124124
WebDriver: {
125125
// load variables from the environment and provide defaults
@@ -158,21 +158,52 @@ codeceptjs run --config=./path/to/my/config.js
158158

159159
> 📺 [Watch this material](https://www.youtube.com/watch?v=onBnfo_rJa4&t=4s) on YouTube
160160
161-
[`@codeceptjs/configure` package](https://github.com/codeceptjs/configure) contains shared recipes for common configuration patterns. This allows to set meta-configuration, independent from a current helper enabled.
161+
[`@codeceptjs/configure`](https://github.com/codeceptjs/configure) ships with CodeceptJS as a dependency and contains shared recipes for common configuration patterns. It lets you set meta-configuration that's independent of the active helper.
162162

163-
Install it and enable to easily switch to headless/window mode, change window size, etc.
163+
Toggle headless/headed mode, change window size, etc.:
164164

165165
```js
166-
const { setHeadlessWhen, setWindowSize } = require('@codeceptjs/configure')
166+
import { setHeadlessWhen, setWindowSize } from '@codeceptjs/configure'
167167

168168
setHeadlessWhen(process.env.CI)
169169
setWindowSize(1600, 1200)
170170

171-
exports.config = {
171+
export const config = {
172172
// ...
173173
}
174174
```
175175

176+
For one-shot bundles use `setBrowserConfig` — pass any subset of `{ browser, show, windowSize, url, ... }` and the right per-helper translation happens automatically (Puppeteer receives `product` for `browser`, WebDriver gets `--headless` injected, etc.). Keys whose value is `undefined` are skipped, so unset env vars don't clobber existing config:
177+
178+
```js
179+
import { setBrowserConfig } from '@codeceptjs/configure'
180+
181+
setBrowserConfig({
182+
browser: process.env.BROWSER, // optional engine override
183+
show: !process.env.HEADLESS, // headed unless HEADLESS is set
184+
windowSize: '1280x720',
185+
url: process.env.URL, // overrides helper.url when set
186+
})
187+
```
188+
189+
`setCommonPlugins()` enables a curated set of plugins and registers a few more as discoverable (so they can be activated ad-hoc via [`-p` plugin arguments](/commands#plugin-arguments) without editing config):
190+
191+
```js
192+
import { setCommonPlugins } from '@codeceptjs/configure'
193+
194+
setCommonPlugins()
195+
```
196+
197+
| Plugin | Default | Notes |
198+
| :----------------- | :------------- | :----------------------------------------------------------------------------- |
199+
| `retryFailedStep` | enabled | Retry steps that fail with transient errors |
200+
| `screenshotOnFail` | enabled | Capture a screenshot when a test fails |
201+
| `pauseOn` | registered | Pause on failure / step / file / URL — `-p pauseOn:fail`, `-p pauseOn:step`, `-p pauseOn:file:tests/login_test.js`, `-p pauseOn:url:/checkout/*` |
202+
| `browser` | registered | CLI overrides for browser helpers — `-p browser:show`, `-p browser:browser=firefox`, see [commands](/commands#browser-control) |
203+
| `aiTrace` | registered | Capture AI traces — `-p aiTrace` |
204+
205+
> `eachElement`, `tryTo`, and `retryTo` are no longer plugins in 4.x — import them from `codeceptjs/effects`.
206+
176207
## Profile
177208

178209
Using `process.env.profile` you can change the config dynamically.
@@ -186,7 +217,7 @@ codeceptjs run --profile firefox
186217
```
187218

188219
```js
189-
exports.config = {
220+
export const config = {
190221
helpers: {
191222
WebDriver: {
192223
url: 'http://localhost:3000',

docs/custom-helpers.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Helpers are classes inherited from [corresponding abstract class](https://github
3434
Created helper file should look like this:
3535

3636
```js
37-
const Helper = require('@codeceptjs/helper')
37+
import Helper from '@codeceptjs/helper'
3838

3939
class MyHelper extends Helper {
4040
// before/after hooks
@@ -51,14 +51,14 @@ class MyHelper extends Helper {
5151
// use: this.helpers['helperName']
5252
}
5353

54-
module.exports = MyHelper
54+
export default MyHelper
5555
```
5656

5757
When the helper is enabled in config all methods of a helper class are available in `I` object.
5858
For instance, if we add a new method to helper class:
5959

6060
```js
61-
const Helper = require('@codeceptjs/helper')
61+
import Helper from '@codeceptjs/helper'
6262

6363
class MyHelper extends Helper {
6464
doAwesomeThings() {
@@ -202,8 +202,9 @@ This can be done inside a helper using the global [promise recorder](/hooks/#api
202202
Example: Retrying rendering errors in Puppeteer.
203203

204204
```js
205+
import { recorder } from 'codeceptjs'
206+
205207
_before() {
206-
const recorder = require('codeceptjs').recorder;
207208
recorder.retry({
208209
retries: 2,
209210
when: err => err.message.indexOf('Cannot find context with specified id') > -1,
@@ -217,7 +218,7 @@ Retry rules are available in array `recorder.retries`. The last retry rule can b
217218

218219
## Using Typescript
219220

220-
With Typescript, just simply replacing `module.exports` with `export` for autocompletion.
221+
With Typescript, just simply replacing `export default` with `export` for autocompletion.
221222

222223
## Helper Examples
223224

@@ -226,7 +227,7 @@ With Typescript, just simply replacing `module.exports` with `export` for autoco
226227
In this example we take the power of Playwright to change geolocation in our tests:
227228

228229
```js
229-
const Helper = require('@codeceptjs/helper')
230+
import Helper from '@codeceptjs/helper'
230231

231232
class MyHelper extends Helper {
232233
async setGeoLocation(longitude, latitude) {
@@ -242,10 +243,10 @@ class MyHelper extends Helper {
242243
Next example demonstrates how to use WebDriver library to create your own test action. Method `seeAuthentication` will use `browser` instance of WebDriver to get access to cookies. Standard NodeJS assertion library will be used (you can use any).
243244

244245
```js
245-
const Helper = require('@codeceptjs/helper')
246+
import Helper from '@codeceptjs/helper'
246247

247248
// use any assertion library you like
248-
const assert = require('assert')
249+
import assert from 'assert'
249250

250251
class MyHelper extends Helper {
251252
/**
@@ -271,7 +272,7 @@ class MyHelper extends Helper {
271272
}
272273
}
273274

274-
module.exports = MyHelper
275+
export default MyHelper
275276
```
276277

277278
### Puppeteer Example
@@ -281,8 +282,8 @@ Puppeteer has [nice and elegant API](https://github.com/puppeteer/puppeteer/blob
281282
Let's see how we can use [emulate](https://github.com/puppeteer/puppeteer/blob/main/docs/api/puppeteer.page.emulate.md) function to emulate iPhone browser in a test.
282283

283284
```js
284-
const Helper = require('@codeceptjs/helper')
285-
const puppeteer = require('puppeteer')
285+
import Helper from '@codeceptjs/helper'
286+
import puppeteer from 'puppeteer'
286287
const iPhone = puppeteer.devices['iPhone 6']
287288

288289
class MyHelper extends Helper {
@@ -292,5 +293,5 @@ class MyHelper extends Helper {
292293
}
293294
}
294295

295-
module.exports = MyHelper
296+
export default MyHelper
296297
```

0 commit comments

Comments
 (0)