codeceptjs 4.0.0-rc.21 → 4.0.0-rc.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/advanced.md +1 -1
- package/docs/architecture.md +219 -0
- package/docs/configuration.md +82 -127
- package/docs/continuous-integration.md +113 -151
- package/docs/custom-helpers.md +1 -1
- package/docs/hooks.md +76 -277
- package/docs/installation.md +95 -40
- package/docs/parallel.md +98 -496
- package/docs/plugins.md +43 -0
- package/docs/reports.md +102 -401
- package/docs/retry.md +44 -37
- package/docs/typescript.md +54 -269
- package/lib/actor.js +1 -1
- package/lib/command/workers/runTests.js +1 -5
- package/lib/heal.js +2 -2
- package/lib/helper/Playwright.js +10 -4
- package/lib/plugin/aiTrace.js +4 -3
- package/lib/plugin/junitReporter.js +303 -0
- package/lib/plugin/retryFailedStep.js +4 -3
- package/lib/plugin/screencast.js +1 -1
- package/lib/plugin/screenshot.js +2 -2
- package/lib/plugin/stepTimeout.js +2 -1
- package/lib/step/base.js +7 -7
- package/lib/step/comment.js +2 -2
- package/lib/step/helper.js +4 -4
- package/lib/step/meta.js +3 -3
- package/lib/step/record.js +3 -3
- package/package.json +1 -1
- package/docs/internal-api.md +0 -265
package/docs/advanced.md
CHANGED
|
@@ -134,7 +134,7 @@ Feature('My feature', {key: val});
|
|
|
134
134
|
Scenario('My scenario', {key: val},({ I }) => {});
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
You can use
|
|
137
|
+
You can use these options to build your own [plugins](https://codecept.io/hooks#plugins) with [event listeners](https://codecept.io/architecture#events). Example:
|
|
138
138
|
|
|
139
139
|
```js
|
|
140
140
|
// for test
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
---
|
|
2
|
+
permalink: /architecture
|
|
3
|
+
title: Architecture
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CodeceptJS Architecture
|
|
7
|
+
|
|
8
|
+
How CodeceptJS runs a test, and the internal modules you build [plugins, listeners, and helpers](/hooks) against.
|
|
9
|
+
|
|
10
|
+
## How a Test Runs
|
|
11
|
+
|
|
12
|
+
CodeceptJS is built on top of [Mocha](https://mochajs.org). A run goes through these stages:
|
|
13
|
+
|
|
14
|
+
1. **Load.** CodeceptJS reads the config, builds the [container](#container) (helpers, support objects, plugins), and runs the `bootstrap` hook. `event.all.before` fires.
|
|
15
|
+
2. **Suite.** For each suite, `event.suite.before` fires. Helper `_beforeSuite` hooks run.
|
|
16
|
+
3. **Test.** For each test: `event.test.started` fires; `Before` hooks from helpers (`_before`) and from the suite run, then `event.test.before` fires; the scenario function runs; `event.test.passed` or `event.test.failed` fires; `After` hooks run; `event.test.after` and then `event.test.finished` fire.
|
|
17
|
+
4. **Step.** Each `I.*` call inside a scenario becomes a step. It is *scheduled* onto the [recorder](#the-recorder) — `event.step.before` fires — then executed: `event.step.started`, `event.step.passed` or `event.step.failed`, `event.step.after`, `event.step.finished`.
|
|
18
|
+
5. **Finish.** `event.suite.after` fires after each suite, `event.all.after` after the last one, and `event.all.result` when results are printed. The `teardown` hook runs.
|
|
19
|
+
|
|
20
|
+
The key idea is step 4: **a scenario doesn't execute its steps as it runs** — it queues them. `I.click()` returns immediately; the [recorder](#the-recorder) runs the queued action later. This is why scenarios rarely need `await`, and why anything that injects async work has to go through the recorder.
|
|
21
|
+
|
|
22
|
+
## The Internal API
|
|
23
|
+
|
|
24
|
+
CodeceptJS exposes its internals as named exports of the `codeceptjs` package. Import only what you need:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import { recorder, event, output, container, config } from 'codeceptjs'
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
| Export | What it is |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| [`codecept`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/codecept.js) | the test runner class |
|
|
33
|
+
| [`config`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/config.js) | the loaded configuration |
|
|
34
|
+
| [`container`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/container.js) | dependency-injection container: helpers, support objects, plugins, the Mocha instance |
|
|
35
|
+
| [`recorder`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/recorder.js) | the global promise chain that orders every step |
|
|
36
|
+
| [`event`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/event.js) | the event dispatcher and the names of all lifecycle events |
|
|
37
|
+
| [`output`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/output.js) | the printer used for all console output |
|
|
38
|
+
| [`helper`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/helper.js) | the base class every helper extends |
|
|
39
|
+
| [`actor`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/actor.js) | the base class behind the `I` object |
|
|
40
|
+
|
|
41
|
+
> Older code relied on a global `codeceptjs` object (`const { recorder } = codeceptjs`). That global only exists under `noGlobals: false`, the deprecated 3.x default — prefer named imports.
|
|
42
|
+
|
|
43
|
+
The [API reference](https://github.com/codeceptjs/CodeceptJS/tree/master/docs/api) on GitHub documents these modules; the source is the final word.
|
|
44
|
+
|
|
45
|
+
## The Recorder
|
|
46
|
+
|
|
47
|
+
The recorder is a single global promise chain. Every step a scenario "calls" is appended to it, and the chain runs the steps one after another. To run your own async code at the right point in a test, append it to the recorder too:
|
|
48
|
+
|
|
49
|
+
```js
|
|
50
|
+
import { event, recorder } from 'codeceptjs'
|
|
51
|
+
|
|
52
|
+
event.dispatcher.on(event.test.before, () => {
|
|
53
|
+
recorder.add('seed fixture data', async () => {
|
|
54
|
+
await api.post('/users', { name: 'john', email: 'john@example.com' })
|
|
55
|
+
})
|
|
56
|
+
})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
- `recorder.add(name, fn)` — append `fn` (async, or returning a promise) to the chain. The name shows up in `--verbose` output.
|
|
60
|
+
- `recorder.startUnlessRunning()` — start a chain if none is running. Call it before `add()` from a listener that may fire outside a running chain, such as `event.all.before`.
|
|
61
|
+
- `recorder.retry({ retries, when })` — retry failing steps that match `when`. See [conditional retries](/helpers#conditional-retries).
|
|
62
|
+
|
|
63
|
+
Run tests with `--verbose` to watch the recorder schedule and execute each entry.
|
|
64
|
+
|
|
65
|
+
## Container
|
|
66
|
+
|
|
67
|
+
The container resolves helpers and support objects by name:
|
|
68
|
+
|
|
69
|
+
```js
|
|
70
|
+
import { container } from 'codeceptjs'
|
|
71
|
+
|
|
72
|
+
const helpers = container.helpers() // every helper, keyed by name
|
|
73
|
+
const { Playwright } = container.helpers() // one helper
|
|
74
|
+
const support = container.support() // every support object
|
|
75
|
+
const { UserPage } = container.support() // one page object
|
|
76
|
+
const plugins = container.plugins() // enabled plugins
|
|
77
|
+
const mocha = container.mocha() // the current Mocha instance
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Add objects at runtime — useful from a `bootstrap` script:
|
|
81
|
+
|
|
82
|
+
```js
|
|
83
|
+
import { container } from 'codeceptjs'
|
|
84
|
+
import UserPage from './pages/user.js'
|
|
85
|
+
|
|
86
|
+
container.append({
|
|
87
|
+
helpers: { MyHelper: new MyHelper({ host: 'http://example.com' }) },
|
|
88
|
+
support: { UserPage },
|
|
89
|
+
})
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Events
|
|
93
|
+
|
|
94
|
+
`event.dispatcher` is a Node `EventEmitter`. Attach listeners to it from a [plugin](/hooks#plugins) or `bootstrap` script.
|
|
95
|
+
|
|
96
|
+
Events are **sync** or **async**:
|
|
97
|
+
|
|
98
|
+
- **sync** — fires the moment the action happens. Do synchronous work only.
|
|
99
|
+
- **async** — fires when the action is *scheduled*. To do async work in the right order, queue it with `recorder.add()`.
|
|
100
|
+
|
|
101
|
+
| Event | Kind | When |
|
|
102
|
+
| --- | --- | --- |
|
|
103
|
+
| `event.all.before` | — | before any test runs |
|
|
104
|
+
| `event.suite.before(suite)` | async | before a suite |
|
|
105
|
+
| `event.test.started(test)` | sync | at the very start of a test |
|
|
106
|
+
| `event.test.before(test)` | async | after `Before` hooks from helpers and the test are run |
|
|
107
|
+
| `event.test.passed(test)` | sync | test passed |
|
|
108
|
+
| `event.test.failed(test, err)` | sync | test failed |
|
|
109
|
+
| `event.test.skipped(test)` | sync | test skipped |
|
|
110
|
+
| `event.test.after(test)` | async | after each test |
|
|
111
|
+
| `event.test.finished(test)` | sync | test finished |
|
|
112
|
+
| `event.suite.after(suite)` | async | after a suite |
|
|
113
|
+
| `event.step.before(step)` | async | step scheduled for execution |
|
|
114
|
+
| `event.step.started(step)` | sync | step starts executing |
|
|
115
|
+
| `event.step.passed(step)` | sync | step passed |
|
|
116
|
+
| `event.step.failed(step, err)` | sync | step failed |
|
|
117
|
+
| `event.step.after(step)` | async | after a step |
|
|
118
|
+
| `event.step.finished(step)` | sync | step finished |
|
|
119
|
+
| `event.step.comment(step)` | sync | a comment such as `I.say(...)` |
|
|
120
|
+
| `event.bddStep.before(step)` / `event.bddStep.after(step)` | async | around a Gherkin step |
|
|
121
|
+
| `event.hook.started(hook)` / `event.hook.passed` / `event.hook.failed` / `event.hook.finished` | sync | around `Before` / `After` / `BeforeSuite` / `AfterSuite` hooks |
|
|
122
|
+
| `event.all.after` | — | after all tests |
|
|
123
|
+
| `event.all.result(result)` | — | when results are printed |
|
|
124
|
+
| `event.all.failures(failures)` | — | when a run reports failures |
|
|
125
|
+
| `event.workers.before` / `event.workers.after` / `event.workers.result(result)` | — | around a [parallel run](/parallel) (parent process only) |
|
|
126
|
+
|
|
127
|
+
The [built-in listeners](https://github.com/codeceptjs/CodeceptJS/tree/master/lib/listener) are working examples — every reporter and several plugins are listeners.
|
|
128
|
+
|
|
129
|
+
### Test object
|
|
130
|
+
|
|
131
|
+
Test events pass a test object with these fields:
|
|
132
|
+
|
|
133
|
+
- `title` — the test title
|
|
134
|
+
- `body` — the test function as a string
|
|
135
|
+
- `opts` — test options such as `retries` (see [test options](/advanced#test-options))
|
|
136
|
+
- `pending` — `true` while scheduled, `false` once finished
|
|
137
|
+
- `tags` — array of [tags](/test-structure#tags) for this test
|
|
138
|
+
- `artifacts` — files attached to this test (screenshots, videos, …), shared across reporters
|
|
139
|
+
- `file` — path to the test file
|
|
140
|
+
- `steps` — executed steps (only on `test.passed`, `test.failed`, `test.finished`)
|
|
141
|
+
- `skipInfo` — present when the test was skipped: `{ message, description }`
|
|
142
|
+
|
|
143
|
+
### Step object
|
|
144
|
+
|
|
145
|
+
Step events pass a step object with these fields:
|
|
146
|
+
|
|
147
|
+
- `name` — the step name, such as `see` or `click`
|
|
148
|
+
- `actor` — the current actor, usually `I`
|
|
149
|
+
- `helper` — the helper instance that executes this step
|
|
150
|
+
- `helperMethod` — the helper method, usually the same as `name`
|
|
151
|
+
- `status` — `passed` or `failed`
|
|
152
|
+
- `prefix` — for a step inside a `within` block, the within text (e.g. `Within .js-signup-form`)
|
|
153
|
+
- `args` — the arguments passed to the step
|
|
154
|
+
|
|
155
|
+
## Config
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
import { config } from 'codeceptjs'
|
|
159
|
+
|
|
160
|
+
config.get() // the full config object
|
|
161
|
+
config.get('myKey') // one value
|
|
162
|
+
config.get('myKey', 'fallback') // one value, with a default
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Output
|
|
166
|
+
|
|
167
|
+
Output has four verbosity levels, each toggled by a CLI flag:
|
|
168
|
+
|
|
169
|
+
| Level | Flag | Use |
|
|
170
|
+
| --- | --- | --- |
|
|
171
|
+
| default | — | `output.print` — basic information |
|
|
172
|
+
| steps | `--steps` | step execution |
|
|
173
|
+
| debug | `--debug` | steps plus `output.debug` |
|
|
174
|
+
| verbose | `--verbose` | debug plus `output.log` (internal logs and recorder activity) |
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
import { output } from 'codeceptjs'
|
|
178
|
+
|
|
179
|
+
output.print('basic information')
|
|
180
|
+
output.debug('debug information')
|
|
181
|
+
output.log('verbose logging information')
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Use these instead of `console.log` so messages respect the chosen verbosity.
|
|
185
|
+
|
|
186
|
+
## Helpers and the Actor
|
|
187
|
+
|
|
188
|
+
The `I` object is an **actor** assembled from the enabled helpers. Each `I.method()` call delegates to the matching helper method and is wrapped as a step. Methods whose names start with `_` are private to the helper and not exposed on `I`. To add your own actions, write a [custom helper](/helpers).
|
|
189
|
+
|
|
190
|
+
## Running CodeceptJS from Code
|
|
191
|
+
|
|
192
|
+
CodeceptJS can be driven from your own script. Create the runner with a config and options, initialize it, then bootstrap, load tests, and run:
|
|
193
|
+
|
|
194
|
+
```js
|
|
195
|
+
import { codecept as Codecept } from 'codeceptjs'
|
|
196
|
+
|
|
197
|
+
const config = { helpers: { Playwright: { browser: 'chromium', url: 'http://localhost' } } }
|
|
198
|
+
const opts = { steps: true }
|
|
199
|
+
|
|
200
|
+
const codecept = new Codecept(config, opts)
|
|
201
|
+
codecept.init(import.meta.dirname) // the test root directory
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
await codecept.bootstrap()
|
|
205
|
+
codecept.loadTests('**/*_test.js')
|
|
206
|
+
await codecept.run() // pass a test file path to run only that file
|
|
207
|
+
} catch (err) {
|
|
208
|
+
console.error(err)
|
|
209
|
+
process.exitCode = 1
|
|
210
|
+
} finally {
|
|
211
|
+
await codecept.teardown()
|
|
212
|
+
}
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
> To run tests inside workers from a script, see [parallel execution](/parallel).
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
**See also:** [Extending CodeceptJS](/hooks) · [Custom Helpers](/helpers) · [Plugins](/plugins) · [Bootstrap & Teardown](/bootstrap)
|
package/docs/configuration.md
CHANGED
|
@@ -5,167 +5,129 @@ title: Configuration
|
|
|
5
5
|
|
|
6
6
|
# Configuration
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
After running `codeceptjs init` it should be saved in test root.
|
|
11
|
-
|
|
12
|
-
| Name | Type | Description |
|
|
13
|
-
| :------------------- | :----------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
14
|
-
| `bootstrap?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code before](https://codecept.io/bootstrap/) tests are run. Can be either JS module file or async function: `bootstrap: async () => server.launch(), ` or `bootstrap: 'bootstrap.js', ` |
|
|
15
|
-
| `bootstrapAll?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code before launching tests in parallel mode](https://codecept.io/bootstrap/#bootstrapall-teardownall) |
|
|
16
|
-
| `gherkin?` | { `features`: `string` \| `string`[] ; `steps`: `string`[] } | Enable [BDD features](https://codecept.io/bdd/#configuration). Sample configuration: `gherkin: { features: "./features/*.feature", steps: ["./step_definitions/steps.js"] } ` |
|
|
17
|
-
| `gherkin.features` | `string` \| `string`[] | load feature files by pattern. Multiple patterns can be specified as array |
|
|
18
|
-
| `gherkin.steps` | `string`[] | load step definitions from JS files |
|
|
19
|
-
| `grep?` | `string` | Pattern to filter tests by name. This option is useful if you plan to use multiple configs for different environments. To execute only tests with @firefox tag use `grep: '@firefox' ` |
|
|
20
|
-
| `helpers?` | {} | Enable and configure helpers: `helpers: { Playwright: { url: 'https://mysite.com', browser: 'firefox' } } ` |
|
|
21
|
-
| `include?` | `any` | Include page objects to access them via dependency injection `I: "./custom_steps.js", loginPage: "./pages/Login.js", User: "./pages/User.js", ` Configured modules can be injected by name in a Scenario: `Scenario('test', { I, loginPage, User }) ` |
|
|
22
|
-
| `mocha?` | `any` | [Mocha test runner options](https://mochajs.org/#configuring-mocha-nodejs), additional [reporters](https://codecept.io/reports/#xml) can be configured here. Example: `mocha: { "mocha-junit-reporter": { stdout: "./output/console.log", options: { mochaFile: "./output/result.xml", attachments: true //add screenshot for a failed test } } } ` |
|
|
23
|
-
| `noGlobals?` | `boolean` | Disable registering global functions (Before, Scenario, etc). Not recommended |
|
|
24
|
-
| `output` | `string` | Where to store failure screenshots, artifacts, etc `output: './output' ` |
|
|
25
|
-
| `plugins?` | `any` | Enable CodeceptJS plugins. Example: `plugins: { autoDelay: { enabled: true } } ` |
|
|
26
|
-
| `require?` | `string`[] | [Require additional JS modules](https://codecept.io/configuration/#require) Example: `require: ["should"]` |
|
|
27
|
-
| `teardown?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute code after tests](https://codecept.io/bootstrap/) finished. Can be either JS module file or async function: `teardown: async () => server.stop(), ` or `teardown: 'teardown.js', ` |
|
|
28
|
-
| `teardownAll?` | (() => `Promise`<`void`\>) \| `boolean` \| `string` | [Execute JS code after finishing tests in parallel mode](https://codecept.io/bootstrap/#bootstrapall-teardownall) |
|
|
29
|
-
| `tests` | `string` | Pattern to locate CodeceptJS tests. Allows to enter glob pattern or an Array<string> of patterns to match tests / test file names. For tests in JavaScript: `tests: 'tests/**.test.js' ` For tests in TypeScript: `tests: 'tests/**.test.ts' ` |
|
|
30
|
-
| `timeout?` | `number` | Set default tests timeout in seconds. Tests will be killed on no response after timeout. `timeout: 20, ` |
|
|
31
|
-
| `translation?` | `string` | Enable [localized test commands](https://codecept.io/translation/) |
|
|
32
|
-
| `maskSensitiveData?` | `boolean` | Enable to mask Sensitive Data in console. |
|
|
8
|
+
`codeceptjs init` creates a `codecept.conf.js` (or `codecept.conf.ts`) in your test root. It exports a `config` object:
|
|
33
9
|
|
|
34
|
-
|
|
10
|
+
```js
|
|
11
|
+
export const config = {
|
|
12
|
+
tests: './**/*_test.js',
|
|
13
|
+
output: './output',
|
|
14
|
+
helpers: {
|
|
15
|
+
Playwright: { url: 'http://localhost', browser: 'chromium' },
|
|
16
|
+
},
|
|
17
|
+
include: {
|
|
18
|
+
I: './steps_file.js',
|
|
19
|
+
},
|
|
20
|
+
}
|
|
21
|
+
```
|
|
35
22
|
|
|
36
|
-
|
|
37
|
-
- **Assertion libraries:** e.g., `'should'` instead of manually requiring it in each test
|
|
38
|
-
- **TypeScript loaders:** Enable TypeScript test files in ESM or CommonJS projects
|
|
39
|
-
- **Setup modules:** Initialize testing environment
|
|
40
|
-
- **Custom modules:** With relative paths like `"require": ["./lib/setup"]`
|
|
23
|
+
## Options
|
|
41
24
|
|
|
42
|
-
|
|
25
|
+
**Tests and files**
|
|
43
26
|
|
|
44
|
-
|
|
27
|
+
- `tests` — glob pattern (or array of patterns) locating your test files, e.g. `'tests/**/*_test.js'` (or `*_test.ts` for TypeScript).
|
|
28
|
+
- `output` — directory for failure screenshots, artifacts, and temporary files. Default `./output`.
|
|
29
|
+
- `include` — page objects and support objects exposed via dependency injection: `{ I: './steps_file.js', loginPage: './pages/Login.js' }`. They can then be injected by name — `Scenario('test', ({ I, loginPage }) => …)`.
|
|
30
|
+
- `require` — extra modules to load before tests run: assertion libraries, TypeScript loaders, setup files. See [Require](#require).
|
|
31
|
+
- `grep` — run only tests whose name matches this pattern, e.g. `grep: '@firefox'`. Handy when you keep separate configs per environment.
|
|
45
32
|
|
|
46
|
-
|
|
33
|
+
**Helpers and plugins**
|
|
47
34
|
|
|
48
|
-
|
|
35
|
+
- `helpers` — enable and configure [helpers](/helpers): `{ Playwright: { url: 'https://mysite.com', browser: 'firefox' } }`.
|
|
36
|
+
- `plugins` — enable [plugins](/plugins): `{ autoDelay: { enabled: true } }`.
|
|
49
37
|
|
|
50
|
-
|
|
51
|
-
// codecept.conf.ts
|
|
52
|
-
export const config = {
|
|
53
|
-
tests: './**/*_test.ts',
|
|
54
|
-
require: ['tsx/cjs'], // ← Modern TypeScript loader
|
|
55
|
-
helpers: {},
|
|
56
|
-
include: {},
|
|
57
|
-
}
|
|
58
|
-
```
|
|
38
|
+
**Hooks**
|
|
59
39
|
|
|
60
|
-
|
|
40
|
+
- `bootstrap` / `teardown` — run code before / after the whole run; an async function or a path to a JS module. See [Bootstrap](/bootstrap).
|
|
41
|
+
- `bootstrapAll` / `teardownAll` — run once around a parallel run (before any worker starts / after all finish). See [bootstrapAll / teardownAll](/bootstrap#bootstrapall-teardownall).
|
|
61
42
|
|
|
62
|
-
|
|
63
|
-
// codecept.conf.ts
|
|
64
|
-
export const config = {
|
|
65
|
-
tests: './**/*_test.ts',
|
|
66
|
-
require: ['ts-node/esm'], // ← Established TypeScript loader
|
|
67
|
-
helpers: {},
|
|
68
|
-
include: {},
|
|
69
|
-
}
|
|
70
|
-
```
|
|
43
|
+
**Test runner**
|
|
71
44
|
|
|
72
|
-
|
|
45
|
+
- `timeout` — default per-test timeout in seconds; a test is killed if it stops responding.
|
|
46
|
+
- `mocha` — [Mocha options](https://mochajs.org/#configuring-mocha-nodejs), including extra reporters. See [Reporters](/reports).
|
|
73
47
|
|
|
74
|
-
|
|
48
|
+
**BDD**
|
|
75
49
|
|
|
76
|
-
|
|
50
|
+
- `gherkin` — enable [BDD features](/bdd#configuration): `{ features: './features/*.feature', steps: ['./step_definitions/steps.js'] }`.
|
|
51
|
+
- `gherkin.features` — feature file glob, or an array of globs.
|
|
52
|
+
- `gherkin.steps` — JS files with step definitions.
|
|
77
53
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
helpers: {},
|
|
84
|
-
include: {},
|
|
85
|
-
}
|
|
86
|
-
```
|
|
54
|
+
**TypeScript**
|
|
55
|
+
|
|
56
|
+
- `fullPromiseBased` — generate typings where `I.*` methods return promises, so you can `await` each command. See [TypeScript](/typescript#promise-based-typings).
|
|
57
|
+
|
|
58
|
+
**Other**
|
|
87
59
|
|
|
88
|
-
|
|
60
|
+
- `translation` — enable [localized commands](/translation).
|
|
61
|
+
- `maskSensitiveData` — mask secrets in console output.
|
|
62
|
+
- `noGlobals` — don't register the global functions (`Feature`, `Scenario`, `Before`, …). Not recommended.
|
|
89
63
|
|
|
90
|
-
|
|
64
|
+
## Require
|
|
65
|
+
|
|
66
|
+
`require` loads modules before tests run — assertion libraries (`'should'`), setup files (`'./lib/setup'`), and TypeScript loaders. Modules load in the order listed.
|
|
67
|
+
|
|
68
|
+
For TypeScript test files in CodeceptJS 4.x, use the [`tsx`](https://tsx.is) loader:
|
|
91
69
|
|
|
92
|
-
```
|
|
70
|
+
```ts
|
|
93
71
|
// codecept.conf.ts
|
|
94
72
|
export const config = {
|
|
95
|
-
tests:
|
|
96
|
-
require: [
|
|
97
|
-
'tsx/cjs', // TypeScript loader
|
|
98
|
-
'should', // Assertion library
|
|
99
|
-
'./lib/testSetup' // Custom setup
|
|
100
|
-
],
|
|
73
|
+
tests: './**/*_test.ts',
|
|
74
|
+
require: ['tsx/cjs'],
|
|
101
75
|
helpers: {},
|
|
102
76
|
include: {},
|
|
103
77
|
}
|
|
104
78
|
```
|
|
105
79
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
## Dynamic Configuration
|
|
109
|
-
|
|
110
|
-
By default `codecept.json` is used for configuration. You can override its values in runtime by using `--override` or `-o` option in command line, passing valid JSON as a value:
|
|
80
|
+
Combine several modules:
|
|
111
81
|
|
|
112
|
-
```
|
|
113
|
-
|
|
82
|
+
```ts
|
|
83
|
+
require: ['tsx/cjs', 'should', './lib/testSetup']
|
|
114
84
|
```
|
|
115
85
|
|
|
116
|
-
|
|
117
|
-
|
|
86
|
+
The config file itself (`codecept.conf.ts`) and helpers are transpiled automatically — only test files need the loader. See [TypeScript](/typescript) for the full setup.
|
|
87
|
+
|
|
88
|
+
## Dynamic configuration
|
|
118
89
|
|
|
119
|
-
|
|
90
|
+
A JS/TS config file is plain code, so you can read environment variables and build the config at runtime:
|
|
120
91
|
|
|
121
92
|
```js
|
|
122
93
|
export const config = {
|
|
123
94
|
helpers: {
|
|
124
95
|
WebDriver: {
|
|
125
|
-
// load variables from the environment and provide defaults
|
|
126
96
|
url: process.env.CODECEPT_URL || 'http://localhost:3000',
|
|
127
|
-
|
|
128
97
|
user: process.env.CLOUDSERVICE_USER,
|
|
129
98
|
key: process.env.CLOUDSERVICE_KEY,
|
|
130
|
-
|
|
131
|
-
coloredLogs: true,
|
|
132
99
|
waitForTimeout: 10000,
|
|
133
100
|
},
|
|
134
101
|
},
|
|
135
|
-
|
|
136
|
-
// don't build monolithic configs
|
|
137
|
-
mocha: require('./mocha.conf.js') || {},
|
|
138
102
|
include: {
|
|
139
103
|
I: './src/steps_file.js',
|
|
140
|
-
loginPage: './src/pages/login_page',
|
|
141
|
-
dashboardPage: new DashboardPage(),
|
|
104
|
+
loginPage: './src/pages/login_page.js',
|
|
142
105
|
},
|
|
143
|
-
|
|
144
|
-
// here goes config as it was in codecept.conf.ts
|
|
145
|
-
// ....
|
|
146
106
|
}
|
|
147
107
|
```
|
|
148
108
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
If you prefer to store your configuration files in a different location, or with a different name, you can do that with `--config` or `-c:
|
|
109
|
+
Override config values at runtime with `--override` / `-o`, passing JSON:
|
|
152
110
|
|
|
153
111
|
```sh
|
|
154
|
-
codeceptjs run
|
|
112
|
+
npx codeceptjs run -o '{ "helpers": { "WebDriver": { "browser": "firefox" } } }'
|
|
155
113
|
```
|
|
156
114
|
|
|
157
|
-
|
|
115
|
+
Point at a non-default config file with `--config` / `-c`:
|
|
158
116
|
|
|
159
|
-
|
|
117
|
+
```sh
|
|
118
|
+
npx codeceptjs run --config ./path/to/config.js
|
|
119
|
+
```
|
|
160
120
|
|
|
161
|
-
|
|
121
|
+
## Common configuration patterns
|
|
162
122
|
|
|
163
|
-
|
|
123
|
+
[`@codeceptjs/configure`](https://github.com/codeceptjs/configure) ships with CodeceptJS as a dependency. It holds shared recipes for config that's independent of the active helper.
|
|
124
|
+
|
|
125
|
+
Toggle headless mode, set window size, and so on:
|
|
164
126
|
|
|
165
127
|
```js
|
|
166
128
|
import { setHeadlessWhen, setWindowSize } from '@codeceptjs/configure'
|
|
167
129
|
|
|
168
|
-
setHeadlessWhen(process.env.CI)
|
|
130
|
+
setHeadlessWhen(process.env.HEADLESS || process.env.CI)
|
|
169
131
|
setWindowSize(1600, 1200)
|
|
170
132
|
|
|
171
133
|
export const config = {
|
|
@@ -173,20 +135,20 @@ export const config = {
|
|
|
173
135
|
}
|
|
174
136
|
```
|
|
175
137
|
|
|
176
|
-
For one-shot bundles use `setBrowserConfig` — pass any subset of `{ browser, show, windowSize, url
|
|
138
|
+
For one-shot bundles use `setBrowserConfig` — pass any subset of `{ browser, show, windowSize, url }` and the right per-helper translation happens automatically (Puppeteer gets `product`, WebDriver gets `--headless` injected, …). Keys whose value is `undefined` are skipped, so an unset env var won't clobber existing config:
|
|
177
139
|
|
|
178
140
|
```js
|
|
179
141
|
import { setBrowserConfig } from '@codeceptjs/configure'
|
|
180
142
|
|
|
181
143
|
setBrowserConfig({
|
|
182
|
-
browser: process.env.BROWSER,
|
|
183
|
-
show: !process.env.HEADLESS,
|
|
144
|
+
browser: process.env.BROWSER, // optional engine override
|
|
145
|
+
show: !process.env.HEADLESS, // headed unless HEADLESS is set
|
|
184
146
|
windowSize: '1280x720',
|
|
185
|
-
url: process.env.URL,
|
|
147
|
+
url: process.env.URL, // overrides helper.url when set
|
|
186
148
|
})
|
|
187
149
|
```
|
|
188
150
|
|
|
189
|
-
`setCommonPlugins()` enables a curated set of plugins and registers a few more as discoverable
|
|
151
|
+
`setCommonPlugins()` enables a curated set of plugins and registers a few more as discoverable, so they can be switched on ad-hoc with [`-p` plugin arguments](/commands#plugin-arguments) without editing the config:
|
|
190
152
|
|
|
191
153
|
```js
|
|
192
154
|
import { setCommonPlugins } from '@codeceptjs/configure'
|
|
@@ -194,27 +156,21 @@ import { setCommonPlugins } from '@codeceptjs/configure'
|
|
|
194
156
|
setCommonPlugins()
|
|
195
157
|
```
|
|
196
158
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
| `aiTrace` | registered | Capture AI traces — `-p aiTrace`, narrow with `on=fail|test|step|file|url` |
|
|
204
|
-
| `heal` | registered | Self-heal failing steps — `-p heal`, narrow with `on=file|url` |
|
|
159
|
+
- `retryFailedStep` — *enabled*. Retries steps that fail with transient errors.
|
|
160
|
+
- `screenshot` — *enabled*. Screenshot on `fail` (default), or `test` / `step` / `file` / `url`.
|
|
161
|
+
- `pause` — *registered*. Pause on failure / step / file / URL: `-p pause:on=fail`, `-p pause:on=step`, `-p pause:on=file:path=tests/login_test.js`, `-p pause:on=url:pattern=/checkout/*`.
|
|
162
|
+
- `browser` — *registered*. CLI overrides for browser helpers: `-p browser:show`, `-p browser:browser=firefox`. See [browser control](/commands#browser-control).
|
|
163
|
+
- `aiTrace` — *registered*. Capture AI traces: `-p aiTrace`, narrow with `on=fail|test|step|file|url`.
|
|
164
|
+
- `heal` — *registered*. Self-heal failing steps: `-p heal`, narrow with `on=file|url`.
|
|
205
165
|
|
|
206
166
|
> `eachElement`, `tryTo`, and `retryTo` are no longer plugins in 4.x — import them from `codeceptjs/effects`.
|
|
207
167
|
|
|
208
168
|
## Profile
|
|
209
169
|
|
|
210
|
-
|
|
211
|
-
It provides value of `--profile` option passed to runner.
|
|
212
|
-
Use its value to change config value on the fly.
|
|
213
|
-
|
|
214
|
-
For instance, with the config above we can change browser value using `profile` option
|
|
170
|
+
`process.env.profile` carries the value of the `--profile` CLI option, so you can branch the config on it:
|
|
215
171
|
|
|
216
172
|
```sh
|
|
217
|
-
codeceptjs run --profile firefox
|
|
173
|
+
npx codeceptjs run --profile firefox
|
|
218
174
|
```
|
|
219
175
|
|
|
220
176
|
```js
|
|
@@ -222,8 +178,7 @@ export const config = {
|
|
|
222
178
|
helpers: {
|
|
223
179
|
WebDriver: {
|
|
224
180
|
url: 'http://localhost:3000',
|
|
225
|
-
|
|
226
|
-
browser: process.env.profile || 'firefox',
|
|
181
|
+
browser: process.env.profile || 'chrome',
|
|
227
182
|
},
|
|
228
183
|
},
|
|
229
184
|
}
|