Skip to content

Commit cb436bb

Browse files
author
DavertMik
committed
improved docs about store
1 parent 54bd14e commit cb436bb

3 files changed

Lines changed: 121 additions & 1 deletion

File tree

docs/architecture.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { recorder, event, output, container, config } from 'codeceptjs'
3535
| [`recorder`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/recorder.js) | the global promise chain that orders every step |
3636
| [`event`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/event.js) | the event dispatcher and the names of all lifecycle events |
3737
| [`output`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/output.js) | the printer used for all console output |
38+
| [`store`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/store.js) | global state of the run — current test/step, run modes, directories |
3839
| [`helper`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/helper.js) | the base class every helper extends |
3940
| [`actor`](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/actor.js) | the base class behind the `I` object |
4041

@@ -183,6 +184,21 @@ output.log('verbose logging information')
183184

184185
Use these instead of `console.log` so messages respect the chosen verbosity.
185186

187+
## Store
188+
189+
`store` holds the state of the current run — the executing test, suite, and step, the active run modes (`dryRun`, `debugMode`, `workerMode`, …), and the project directories. Listeners, plugins, and helpers read it to know where in the [lifecycle](#events) they are without that information being passed to them:
190+
191+
```js
192+
import { store } from 'codeceptjs'
193+
194+
event.dispatcher.on(event.step.before, () => {
195+
if (store.dryRun) return // no side effects on a dry run
196+
output.debug(`in ${store.currentTest?.title}`)
197+
})
198+
```
199+
200+
CodeceptJS keeps the state fields up to date for you. See the [Store reference](/store) for every field and when to write to it.
201+
186202
## Helpers and the Actor
187203
188204
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).

docs/hooks.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,17 @@ event.dispatcher.on(event.test.before, () => {
4040
})
4141
```
4242

43-
See [Architecture › Events](/architecture#events) for the full event list and the test and step object fields.
43+
A listener often needs to know *where* in the run it is — which test is active, or whether this is a dry run. Read that from [`store`](/store) instead of tracking it yourself:
44+
45+
```js
46+
import { event, store } from 'codeceptjs'
47+
48+
event.dispatcher.on(event.step.before, () => {
49+
if (store.dryRun) return // skip side effects on a dry run
50+
})
51+
```
52+
53+
See [Architecture › Events](/architecture#events) for the full event list and the test and step object fields, and the [Store reference](/store) for every state field.
4454

4555
## Plugins
4656

docs/store.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
---
2+
permalink: /store
3+
title: Store
4+
---
5+
6+
# Store
7+
8+
`store` is a global object that holds the state of the current run — which test and step are executing, which modes are enabled, and where the project lives on disk. Listeners, plugins, and helpers read it to find out *where in the lifecycle* they are without threading that information through every call.
9+
10+
```js
11+
import { store } from 'codeceptjs'
12+
13+
event.dispatcher.on(event.step.before, () => {
14+
if (store.dryRun) return // skip side effects on a dry run
15+
console.log(`running ${store.currentTest?.title}`)
16+
})
17+
```
18+
19+
It is a single shared object for the whole process. Read from it freely; write to it only if you are deliberately driving execution state (see [Writing to the store](#writing-to-the-store)).
20+
21+
## Fields
22+
23+
### Required
24+
25+
Set once when the runner starts and immutable afterwards. Resolved from the test root, falling back to the legacy `global.codecept_dir` / `global.output_dir`.
26+
27+
| Field | Type | What it is |
28+
| --- | --- | --- |
29+
| `store.codeceptDir` | `string` | root directory of the tests |
30+
| `store.outputDir` | `string` | resolved output directory for artifacts |
31+
| `store.workerMode` | `boolean` | `true` when running inside a [parallel](/parallel) worker |
32+
33+
### Session config
34+
35+
Set at session start and stable for that session. They reflect how the run was invoked.
36+
37+
| Field | Type | What it is |
38+
| --- | --- | --- |
39+
| `store.debugMode` | `boolean` | run started with `--debug` |
40+
| `store.timeouts` | `boolean` | [timeouts](/timeouts) are enabled |
41+
| `store.autoRetries` | `boolean` | step auto-retries are active (the `tryTo` [effect](/effects) turns this off while it runs) |
42+
| `store.dryRun` | `boolean` | run is a `--dry-run`; steps must not cause side effects |
43+
| `store.featureOnly` | `boolean` | a `Feature.only()` was used |
44+
| `store.scenarioOnly` | `boolean` | a `Scenario.only()` was used |
45+
| `store.maskSensitiveData` | `boolean \| object` | mask [secret](/secrets) values in output |
46+
| `store.noGlobals` | `boolean` | `noGlobals` mode — the user imports everything instead of relying on globals |
47+
48+
### State
49+
50+
Changes constantly as the run progresses. The most useful fields for plugins and listeners:
51+
52+
| Field | Type | What it is |
53+
| --- | --- | --- |
54+
| `store.onPause` | `boolean` | execution is paused inside [`pause()`](/basics#pause) |
55+
| `store.currentTest` | `Test \| null` | the running test, or `null` between tests |
56+
| `store.currentStep` | `Step \| null` | the running step, or `null` |
57+
| `store.currentSuite` | `Suite \| null` | the running suite, or `null` between suites |
58+
| `store.tsFileMapping` | `Map \| null` | TypeScript source-map lookup, when running `.ts` tests |
59+
60+
`currentTest`, `currentStep`, and `currentSuite` carry the same objects passed to lifecycle events — see the [test and step object](/architecture#test-object) fields.
61+
62+
## Reading the store
63+
64+
A typical use is gating expensive or unsafe work by run mode:
65+
66+
```js
67+
import { store, recorder } from 'codeceptjs'
68+
69+
event.dispatcher.on(event.test.before, () => {
70+
if (store.dryRun || store.workerMode) return
71+
72+
recorder.add('seed fixture data', async () => {
73+
await api.post('/users', { name: 'john' })
74+
})
75+
})
76+
```
77+
78+
`store.currentTest` is the simplest way to attach context to the current test from anywhere — for example tagging an artifact:
79+
80+
```js
81+
import { store } from 'codeceptjs'
82+
83+
store.currentTest?.artifacts.push({ name: 'log', path: '/tmp/run.log' })
84+
```
85+
86+
## Writing to the store
87+
88+
CodeceptJS keeps the state fields current for you — the built-in [`store` listener](https://github.com/codeceptjs/CodeceptJS/blob/master/lib/listener/store.js) sets `currentSuite` and `currentTest` around each suite and test. You rarely need to write to it.
89+
90+
Write only when you are deliberately driving execution — for example, a tool that opens `pause()` sets `store.onPause`. The required fields (`codeceptDir`, `outputDir`) are locked after `store.initialize()` and cannot be reassigned.
91+
92+
---
93+
94+
**See also:** [Architecture](/architecture) · [Extending CodeceptJS](/hooks) · [Events](/architecture#events)

0 commit comments

Comments
 (0)