-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.html
352 lines (338 loc) · 107 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Behavior Driven Development | CodeceptJS</title>
<meta name="generator" content="VuePress 1.9.10">
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png">
<link rel="shortcut icon" type="image/x-icon" href="/favicon/favicon.ico">
<link rel="manifest" href="/favicon/site.webmanifest">
<link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#805ad5">
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-P98R7LQ');</script>
<meta name="description" content="SuperCharged End 2 End Testing with WebDriver & Puppeteer">
<meta name="theme-color" content="#805ad5">
<meta name="msapplication-config" content="/favicon/browserconfig.xml">
<link rel="preload" href="/assets/css/0.styles.1a6b889a.css" as="style"><link rel="preload" href="/assets/js/app.6cba3458.js" as="script"><link rel="preload" href="/assets/js/5.ff420ac6.js" as="script"><link rel="preload" href="/assets/js/1.c70685ea.js" as="script"><link rel="preload" href="/assets/js/36.722e0c70.js" as="script"><link rel="prefetch" href="/assets/js/100.fc075d43.js"><link rel="prefetch" href="/assets/js/101.cae6b813.js"><link rel="prefetch" href="/assets/js/102.8956f5c5.js"><link rel="prefetch" href="/assets/js/103.ce0ce5f0.js"><link rel="prefetch" href="/assets/js/104.bec09b01.js"><link rel="prefetch" href="/assets/js/105.92a77d38.js"><link rel="prefetch" href="/assets/js/106.f2491291.js"><link rel="prefetch" href="/assets/js/107.31d86252.js"><link rel="prefetch" href="/assets/js/108.6c8414a1.js"><link rel="prefetch" href="/assets/js/109.18923d9f.js"><link rel="prefetch" href="/assets/js/110.48ecea85.js"><link rel="prefetch" href="/assets/js/111.2c4c3078.js"><link rel="prefetch" href="/assets/js/112.9c76c571.js"><link rel="prefetch" href="/assets/js/113.5aea4985.js"><link rel="prefetch" href="/assets/js/114.97801e45.js"><link rel="prefetch" href="/assets/js/115.88b021d8.js"><link rel="prefetch" href="/assets/js/116.d0cfbba6.js"><link rel="prefetch" href="/assets/js/117.730543d6.js"><link rel="prefetch" href="/assets/js/12.a1725f6f.js"><link rel="prefetch" href="/assets/js/13.a6782b38.js"><link rel="prefetch" href="/assets/js/14.ea43b50c.js"><link rel="prefetch" href="/assets/js/15.df9825da.js"><link rel="prefetch" href="/assets/js/16.25cbe1cc.js"><link rel="prefetch" href="/assets/js/17.4f8def75.js"><link rel="prefetch" href="/assets/js/18.17f8f9c7.js"><link rel="prefetch" href="/assets/js/19.76e3b2e8.js"><link rel="prefetch" href="/assets/js/2.89a92fa3.js"><link rel="prefetch" href="/assets/js/20.e54653ad.js"><link rel="prefetch" href="/assets/js/21.7d54624c.js"><link rel="prefetch" href="/assets/js/22.e65379f3.js"><link rel="prefetch" href="/assets/js/23.a59d4566.js"><link rel="prefetch" href="/assets/js/24.683f87fe.js"><link rel="prefetch" href="/assets/js/25.97e55767.js"><link rel="prefetch" href="/assets/js/26.52d000b1.js"><link rel="prefetch" href="/assets/js/27.8d189b77.js"><link rel="prefetch" href="/assets/js/28.a0ec19a0.js"><link rel="prefetch" href="/assets/js/29.25166714.js"><link rel="prefetch" href="/assets/js/3.188649f0.js"><link rel="prefetch" href="/assets/js/30.f52df054.js"><link rel="prefetch" href="/assets/js/31.18843188.js"><link rel="prefetch" href="/assets/js/32.d39aa3cb.js"><link rel="prefetch" href="/assets/js/33.5dfd09f2.js"><link rel="prefetch" href="/assets/js/34.ff30141f.js"><link rel="prefetch" href="/assets/js/35.db84cbc0.js"><link rel="prefetch" href="/assets/js/37.f287aa22.js"><link rel="prefetch" href="/assets/js/38.6527e5dc.js"><link rel="prefetch" href="/assets/js/39.cddbef30.js"><link rel="prefetch" href="/assets/js/4.64d49130.js"><link rel="prefetch" href="/assets/js/40.42bb2686.js"><link rel="prefetch" href="/assets/js/41.fa23a2a0.js"><link rel="prefetch" href="/assets/js/42.78eb1abc.js"><link rel="prefetch" href="/assets/js/43.89496a6b.js"><link rel="prefetch" href="/assets/js/44.bc71b893.js"><link rel="prefetch" href="/assets/js/45.c66af0c7.js"><link rel="prefetch" href="/assets/js/46.1dcd8f21.js"><link rel="prefetch" href="/assets/js/47.a0e71afd.js"><link rel="prefetch" href="/assets/js/48.7dbf7c4a.js"><link rel="prefetch" href="/assets/js/49.2c966b62.js"><link rel="prefetch" href="/assets/js/50.577eae98.js"><link rel="prefetch" href="/assets/js/51.226daa48.js"><link rel="prefetch" href="/assets/js/52.b396ae9b.js"><link rel="prefetch" href="/assets/js/53.a5f33c23.js"><link rel="prefetch" href="/assets/js/54.43e74b32.js"><link rel="prefetch" href="/assets/js/55.3c124a47.js"><link rel="prefetch" href="/assets/js/56.8e1e8455.js"><link rel="prefetch" href="/assets/js/57.c18e88f8.js"><link rel="prefetch" href="/assets/js/58.b24af6b8.js"><link rel="prefetch" href="/assets/js/59.8b7ae1ea.js"><link rel="prefetch" href="/assets/js/6.7d4294fe.js"><link rel="prefetch" href="/assets/js/60.0e683874.js"><link rel="prefetch" href="/assets/js/61.43202682.js"><link rel="prefetch" href="/assets/js/62.92fee4c5.js"><link rel="prefetch" href="/assets/js/63.8c60fbef.js"><link rel="prefetch" href="/assets/js/64.51495e96.js"><link rel="prefetch" href="/assets/js/65.91c21c0a.js"><link rel="prefetch" href="/assets/js/66.b4ea49f8.js"><link rel="prefetch" href="/assets/js/67.0455b8bc.js"><link rel="prefetch" href="/assets/js/68.1054e301.js"><link rel="prefetch" href="/assets/js/69.4bfad59e.js"><link rel="prefetch" href="/assets/js/7.f6967540.js"><link rel="prefetch" href="/assets/js/70.40233151.js"><link rel="prefetch" href="/assets/js/71.9fb0ff20.js"><link rel="prefetch" href="/assets/js/72.095a2c59.js"><link rel="prefetch" href="/assets/js/73.3f0e2517.js"><link rel="prefetch" href="/assets/js/74.a6aa0a50.js"><link rel="prefetch" href="/assets/js/75.a5870449.js"><link rel="prefetch" href="/assets/js/76.749e3911.js"><link rel="prefetch" href="/assets/js/77.32b17a1d.js"><link rel="prefetch" href="/assets/js/78.d18fa0ec.js"><link rel="prefetch" href="/assets/js/79.e91b9835.js"><link rel="prefetch" href="/assets/js/8.0aa39b43.js"><link rel="prefetch" href="/assets/js/80.1a88d7fd.js"><link rel="prefetch" href="/assets/js/81.9c7f8280.js"><link rel="prefetch" href="/assets/js/82.00553b67.js"><link rel="prefetch" href="/assets/js/83.f600bcd6.js"><link rel="prefetch" href="/assets/js/84.29322aeb.js"><link rel="prefetch" href="/assets/js/85.6a3d521a.js"><link rel="prefetch" href="/assets/js/86.9379f88e.js"><link rel="prefetch" href="/assets/js/87.4d50fb05.js"><link rel="prefetch" href="/assets/js/88.1d58fa7c.js"><link rel="prefetch" href="/assets/js/89.169e9324.js"><link rel="prefetch" href="/assets/js/9.c74c342b.js"><link rel="prefetch" href="/assets/js/90.ff6adb89.js"><link rel="prefetch" href="/assets/js/91.4b898147.js"><link rel="prefetch" href="/assets/js/92.085c368c.js"><link rel="prefetch" href="/assets/js/93.6261148a.js"><link rel="prefetch" href="/assets/js/94.31bc941b.js"><link rel="prefetch" href="/assets/js/95.6de81df3.js"><link rel="prefetch" href="/assets/js/96.320f2ad2.js"><link rel="prefetch" href="/assets/js/97.933c36a0.js"><link rel="prefetch" href="/assets/js/98.fca57a33.js"><link rel="prefetch" href="/assets/js/99.17da4d4d.js"><link rel="prefetch" href="/assets/js/vendors~docsearch.ea45d38c.js">
<link rel="stylesheet" href="/assets/css/0.styles.1a6b889a.css">
</head>
<body>
<div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" viewBox="0 0 448 512" class="icon"><path fill="#fff" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/" class="home-link router-link-active"><img src="/logo.svg" alt="CodeceptJS" class="logo"> <span class="site-name can-hide">CodeceptJS</span></a> <div class="links"><a target="_blank" rel="nofollow" href="https://opencollective.com/codeceptjs" class="can-hide">💖 Support Us</a>
<form id="search-form" role="search" class="algolia-search-wrapper search-box"><input id="algolia-search-input" class="search-query"></form> <nav class="nav-links can-hide"><div class="nav-item"><a href="/quickstart.html" class="nav-link" data-v-34dbfd23>Quickstart</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Guides" class="dropdown-title"><span class="title">Guides</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/basics.html" class="nav-link" data-v-34dbfd23>Getting Started</a></li><li class="dropdown-subitem"><a href="/tutorial.html" class="nav-link" data-v-34dbfd23>Tutorial</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/playwright.html" class="nav-link" data-v-34dbfd23>Using Playwright</a></li><li class="dropdown-subitem"><a href="/webdriver.html" class="nav-link" data-v-34dbfd23>Using WebDriver</a></li><li class="dropdown-subitem"><a href="/puppeteer.html" class="nav-link" data-v-34dbfd23>Using Puppeteer</a></li><li class="dropdown-subitem"><a href="/api.html" class="nav-link" data-v-34dbfd23>API Testing</a></li><li class="dropdown-subitem"><a href="/testcafe.html" class="nav-link" data-v-34dbfd23>Using TestCafe</a></li><li class="dropdown-subitem"><a href="/mobile.html" class="nav-link" data-v-34dbfd23>Mobile Testing</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/locators.html" class="nav-link" data-v-34dbfd23>Locators</a></li><li class="dropdown-subitem"><a href="/pageobjects.html" class="nav-link" data-v-34dbfd23>Page Objects</a></li><li class="dropdown-subitem"><a href="/bdd.html" class="nav-link" data-v-34dbfd23>Behavior Driven Development</a></li><li class="dropdown-subitem"><a href="/typescript.html" class="nav-link" data-v-34dbfd23>TypeScript</a></li><li class="dropdown-subitem"><a href="/data.html" class="nav-link" data-v-34dbfd23>Data Management</a></li><li class="dropdown-subitem"><a href="/parallel.html" class="nav-link" data-v-34dbfd23>Parallel Execution</a></li><li class="dropdown-subitem"><a href="/heal.html" class="nav-link" data-v-34dbfd23>Self-Healing Tests</a></li><li class="dropdown-subitem"><a href="/ai.html" class="nav-link" data-v-34dbfd23>AI Testing 🪄</a></li><li class="dropdown-subitem"><a href="/reports.html" class="nav-link" data-v-34dbfd23>Reports</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/pageobjects.html" class="nav-link" data-v-34dbfd23>Organizing Tests...</a></li><li class="dropdown-subitem"><a href="/advanced.html" class="nav-link" data-v-34dbfd23>Advanced Usage...</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Helpers" class="dropdown-title"><span class="title">Helpers</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><div class="dropdown-item-title">Web Testing</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/Playwright.html" class="nav-link" data-v-34dbfd23>Playwright</a></li><li class="dropdown-subitem"><a href="/helpers/WebDriver.html" class="nav-link" data-v-34dbfd23>WebDriver</a></li><li class="dropdown-subitem"><a href="/helpers/Puppeteer.html" class="nav-link" data-v-34dbfd23>Puppeteer</a></li><li class="dropdown-subitem"><a href="/helpers/TestCafe.html" class="nav-link" data-v-34dbfd23>TestCafe</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title">Mobile Testing</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/Appium.html" class="nav-link" data-v-34dbfd23>Appium</a></li><li class="dropdown-subitem"><a href="/helpers/Detox.html" class="nav-link" data-v-34dbfd23>Detox</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title">API Helpers</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/REST.html" class="nav-link" data-v-34dbfd23>REST</a></li><li class="dropdown-subitem"><a href="/helpers/ApiDataFactory.html" class="nav-link" data-v-34dbfd23>ApiDataFactory</a></li><li class="dropdown-subitem"><a href="/helpers/GraphQL.html" class="nav-link" data-v-34dbfd23>GraphQL</a></li><li class="dropdown-subitem"><a href="/helpers/GraphQLDataFactory.html" class="nav-link" data-v-34dbfd23>GraphQLDataFactory</a></li><li class="dropdown-subitem"><a href="/helpers/JSONResponse.html" class="nav-link" data-v-34dbfd23>JSONResponse</a></li><li class="dropdown-subitem"><a href="/helpers/MockRequest.html" class="nav-link" data-v-34dbfd23>MockRequest</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title">Other Helpers</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/OpenAI.html" class="nav-link" data-v-34dbfd23>OpenAI</a></li><li class="dropdown-subitem"><a href="/helpers/FileSystem.html" class="nav-link" data-v-34dbfd23>FileSystem</a></li><li class="dropdown-subitem"><a href="/helpers/Expect.html" class="nav-link" data-v-34dbfd23>Expect</a></li><li class="dropdown-subitem"><a href="/helpers/SoftExpectHelper.html" class="nav-link" data-v-34dbfd23>Soft Expect</a></li><li class="dropdown-subitem"><a href="/helpers/MockServer.html" class="nav-link" data-v-34dbfd23>MockServer</a></li><li class="dropdown-subitem"><a href="/community-helpers.html" class="nav-link" data-v-34dbfd23>Community Helpers</a></li></ul></li></ul></div></div><div class="nav-item"><a href="/plugins.html" class="nav-link" data-v-34dbfd23>Plugins</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="API" class="dropdown-title"><span class="title">API</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/installation.html" class="nav-link" data-v-34dbfd23>Installation</a></li><li class="dropdown-item"><!----> <a href="/commands.html" class="nav-link" data-v-34dbfd23>Commands</a></li><li class="dropdown-item"><!----> <a href="/configuration.html" class="nav-link" data-v-34dbfd23>Configuration</a></li><li class="dropdown-item"><!----> <a href="/docker.html" class="nav-link" data-v-34dbfd23>Docker</a></li></ul></div></div><div class="nav-item"><a href="/changelog.html" class="nav-link" data-v-34dbfd23>Releases</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Community" class="dropdown-title"><span class="title">Community</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
GitHub
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/discussions" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Discussions
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://bit.ly/codeceptjs-slack" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Slack Chat
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://codecept.discourse.group/" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Forum
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://twitter.com/codeceptjs" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Twitter
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://stackoverflow.com/questions/tagged/codeceptjs" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Stack Overflow
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/wiki/Community-Helpers-&-Plugins" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Plugins & Helpers
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/wiki/Examples" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Examples
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/wiki/Videos" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Videos
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/Codeception/CodeceptJS/wiki/Books-&-Posts" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Posts
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://sdclabs.com/" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Commercial Support
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=top_menu&utm_term=link&utm_campaign=reference" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Trainings
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://opencollective.com/codeceptjs" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Support us via OpenCollective!
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li></ul></div></div> <!----></nav></div></header> <header class="sub-bar"><div class="message"><a target="_blank" href="https://stand-with-ukraine.pp.ua">🇺🇦 CodeceptJS was created in Ukraine.
#StandWithUkraine</a> <p></p></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/quickstart.html" class="nav-link" data-v-34dbfd23>Quickstart</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Guides" class="dropdown-title"><span class="title">Guides</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/basics.html" class="nav-link" data-v-34dbfd23>Getting Started</a></li><li class="dropdown-subitem"><a href="/tutorial.html" class="nav-link" data-v-34dbfd23>Tutorial</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/playwright.html" class="nav-link" data-v-34dbfd23>Using Playwright</a></li><li class="dropdown-subitem"><a href="/webdriver.html" class="nav-link" data-v-34dbfd23>Using WebDriver</a></li><li class="dropdown-subitem"><a href="/puppeteer.html" class="nav-link" data-v-34dbfd23>Using Puppeteer</a></li><li class="dropdown-subitem"><a href="/api.html" class="nav-link" data-v-34dbfd23>API Testing</a></li><li class="dropdown-subitem"><a href="/testcafe.html" class="nav-link" data-v-34dbfd23>Using TestCafe</a></li><li class="dropdown-subitem"><a href="/mobile.html" class="nav-link" data-v-34dbfd23>Mobile Testing</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/locators.html" class="nav-link" data-v-34dbfd23>Locators</a></li><li class="dropdown-subitem"><a href="/pageobjects.html" class="nav-link" data-v-34dbfd23>Page Objects</a></li><li class="dropdown-subitem"><a href="/bdd.html" class="nav-link" data-v-34dbfd23>Behavior Driven Development</a></li><li class="dropdown-subitem"><a href="/typescript.html" class="nav-link" data-v-34dbfd23>TypeScript</a></li><li class="dropdown-subitem"><a href="/data.html" class="nav-link" data-v-34dbfd23>Data Management</a></li><li class="dropdown-subitem"><a href="/parallel.html" class="nav-link" data-v-34dbfd23>Parallel Execution</a></li><li class="dropdown-subitem"><a href="/heal.html" class="nav-link" data-v-34dbfd23>Self-Healing Tests</a></li><li class="dropdown-subitem"><a href="/ai.html" class="nav-link" data-v-34dbfd23>AI Testing 🪄</a></li><li class="dropdown-subitem"><a href="/reports.html" class="nav-link" data-v-34dbfd23>Reports</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/pageobjects.html" class="nav-link" data-v-34dbfd23>Organizing Tests...</a></li><li class="dropdown-subitem"><a href="/advanced.html" class="nav-link" data-v-34dbfd23>Advanced Usage...</a></li></ul></li></ul></div></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Helpers" class="dropdown-title"><span class="title">Helpers</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><div class="dropdown-item-title">Web Testing</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/Playwright.html" class="nav-link" data-v-34dbfd23>Playwright</a></li><li class="dropdown-subitem"><a href="/helpers/WebDriver.html" class="nav-link" data-v-34dbfd23>WebDriver</a></li><li class="dropdown-subitem"><a href="/helpers/Puppeteer.html" class="nav-link" data-v-34dbfd23>Puppeteer</a></li><li class="dropdown-subitem"><a href="/helpers/TestCafe.html" class="nav-link" data-v-34dbfd23>TestCafe</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title">Mobile Testing</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/Appium.html" class="nav-link" data-v-34dbfd23>Appium</a></li><li class="dropdown-subitem"><a href="/helpers/Detox.html" class="nav-link" data-v-34dbfd23>Detox</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title">API Helpers</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/REST.html" class="nav-link" data-v-34dbfd23>REST</a></li><li class="dropdown-subitem"><a href="/helpers/ApiDataFactory.html" class="nav-link" data-v-34dbfd23>ApiDataFactory</a></li><li class="dropdown-subitem"><a href="/helpers/GraphQL.html" class="nav-link" data-v-34dbfd23>GraphQL</a></li><li class="dropdown-subitem"><a href="/helpers/GraphQLDataFactory.html" class="nav-link" data-v-34dbfd23>GraphQLDataFactory</a></li><li class="dropdown-subitem"><a href="/helpers/JSONResponse.html" class="nav-link" data-v-34dbfd23>JSONResponse</a></li><li class="dropdown-subitem"><a href="/helpers/MockRequest.html" class="nav-link" data-v-34dbfd23>MockRequest</a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title">Other Helpers</div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="/helpers/OpenAI.html" class="nav-link" data-v-34dbfd23>OpenAI</a></li><li class="dropdown-subitem"><a href="/helpers/FileSystem.html" class="nav-link" data-v-34dbfd23>FileSystem</a></li><li class="dropdown-subitem"><a href="/helpers/Expect.html" class="nav-link" data-v-34dbfd23>Expect</a></li><li class="dropdown-subitem"><a href="/helpers/SoftExpectHelper.html" class="nav-link" data-v-34dbfd23>Soft Expect</a></li><li class="dropdown-subitem"><a href="/helpers/MockServer.html" class="nav-link" data-v-34dbfd23>MockServer</a></li><li class="dropdown-subitem"><a href="/community-helpers.html" class="nav-link" data-v-34dbfd23>Community Helpers</a></li></ul></li></ul></div></div><div class="nav-item"><a href="/plugins.html" class="nav-link" data-v-34dbfd23>Plugins</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="API" class="dropdown-title"><span class="title">API</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/installation.html" class="nav-link" data-v-34dbfd23>Installation</a></li><li class="dropdown-item"><!----> <a href="/commands.html" class="nav-link" data-v-34dbfd23>Commands</a></li><li class="dropdown-item"><!----> <a href="/configuration.html" class="nav-link" data-v-34dbfd23>Configuration</a></li><li class="dropdown-item"><!----> <a href="/docker.html" class="nav-link" data-v-34dbfd23>Docker</a></li></ul></div></div><div class="nav-item"><a href="/changelog.html" class="nav-link" data-v-34dbfd23>Releases</a></div><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Community" class="dropdown-title"><span class="title">Community</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
GitHub
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/discussions" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Discussions
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://bit.ly/codeceptjs-slack" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Slack Chat
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://codecept.discourse.group/" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Forum
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://twitter.com/codeceptjs" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Twitter
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://stackoverflow.com/questions/tagged/codeceptjs" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Stack Overflow
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/wiki/Community-Helpers-&-Plugins" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Plugins & Helpers
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/wiki/Examples" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Examples
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/codeceptjs/CodeceptJS/wiki/Videos" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Videos
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://github.com/Codeception/CodeceptJS/wiki/Books-&-Posts" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Posts
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://sdclabs.com/" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Commercial Support
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li><li class="dropdown-subitem"><a href="https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=top_menu&utm_term=link&utm_campaign=reference" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Trainings
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li><li class="dropdown-item"><div class="dropdown-item-title"></div> <ul class="dropdown-subitem-wrapper"><li class="dropdown-subitem"><a href="https://opencollective.com/codeceptjs" target="_blank" rel="noopener noreferrer" class="nav-link external" data-v-34dbfd23>
Support us via OpenCollective!
<span data-v-34dbfd23><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></li></ul></li></ul></div></div> <!----></nav> <ul class="sidebar-links"><li><div class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Web Testing</span> <span class="arrow"></span></p> <!----></div></li><li><div class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Mobile Testing</span> <span class="arrow"></span></p> <!----></div></li><li><div class="sidebar-group collapsable depth-0"><p class="sidebar-heading open"><span>Organizing Tests</span> <span class="arrow open"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/pageobjects/" class="sidebar-link">Page Objects</a></li><li><a href="/typescript/" class="sidebar-link">TypeScript</a></li><li><a href="/data/" class="sidebar-link">Data Management</a></li><li><a href="/bdd/" aria-current="page" class="active sidebar-link">Behavior Driven Development</a><ul class="sidebar-sub-headers" data-v-a68ca4e6><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#what-is-behavior-driven-development" class="sidebar-link">What is Behavior Driven Development</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#gherkin" class="sidebar-link">Gherkin</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#advanced-gherkin" class="sidebar-link">Advanced Gherkin</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#configuration" class="sidebar-link">Configuration</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#before" class="sidebar-link">Before</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#after" class="sidebar-link">After</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/bdd/#tests-vs-features" class="sidebar-link">Tests vs Features</a></li></ul></li><li><a href="/locators/" class="sidebar-link">Locators</a></li><li><a href="/translation/" class="sidebar-link">Translation</a></li><li><a href="/helpers/" class="sidebar-link">Custom Helpers</a></li><li><a href="/best/" class="sidebar-link">Best Practices</a></li></ul></div></li><li><div class="sidebar-group collapsable depth-0"><p class="sidebar-heading"><span>Advanced Usage</span> <span class="arrow"></span></p> <!----></div></li></ul> </aside> <main class="page"><div class="article-title">Behavior Driven Development</div> <div class="post"><article><div class="theme-default-content content__default"><h1 id="behavior-driven-development"><a href="#behavior-driven-development" class="header-anchor">#</a> Behavior Driven Development</h1> <p>Behavior Driven Development (BDD) is a popular software development methodology. BDD is considered an extension of TDD, and is greatly inspired by <a href="https://agilemanifesto.org/" target="_blank" rel="noopener noreferrer">Agile<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> practices. The primary reason to choose BDD as your development process is to break down communication barriers between business and technical teams. BDD encourages the use of automated testing to verify all documented features of a project from the very beginning. This is why it is common to talk about BDD in the context of test frameworks (like CodeceptJS). The BDD approach, however, is about much more than testing - it is a common language for all team members to use during the development process.</p> <h2 id="what-is-behavior-driven-development"><a href="#what-is-behavior-driven-development" class="header-anchor">#</a> What is Behavior Driven Development</h2> <p>BDD was introduced by <a href="https://dannorth.net/introducing-bdd/" target="_blank" rel="noopener noreferrer">Dan North<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a>. He described it as:</p> <blockquote><p>outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.</p></blockquote> <p>BDD has its own evolution from the days it was born, started by replacing "test" to "should" in unit tests, and moving towards powerful tools like Cucumber and Behat, which made user stories (human-readable text) to be executed as an acceptance test.</p> <p>The idea of story BDD can be narrowed to:</p> <ul><li>describe features in a scenario with a formal text</li> <li>use examples to make abstract things concrete</li> <li>implement each step of a scenario for testing</li> <li>write actual code implementing the feature</li></ul> <p>By writing every feature in User Story format that is automatically executable as a test we ensure that: business, developers, QAs and managers are in the same boat.</p> <p>BDD encourages exploration and debate in order to formalize the requirements and the features that needs to be implemented by requesting to write the User Stories in a way that everyone can understand.</p> <p>By making tests to be a part of User Story, BDD allows non-technical personnel to write (or edit) Acceptance tests.</p> <p>With this procedure we also ensure that everyone in a team knows what has been developed, what has not, what has been tested and what has not.</p> <h3 id="ubiquitous-language"><a href="#ubiquitous-language" class="header-anchor">#</a> Ubiquitous Language</h3> <p>The ubiquitous language is always referred as <em>common</em> language. That it is the main benefit. It is not a couple of our business specification's words, and not a couple of developer's technical terms. It is a common words and terms that can be understood by people for whom we are building the software and should be understood by developers. Establishing correct communication between this two groups people is vital for building successful project that will fit the domain and fulfill all business needs.</p> <p>Each feature of a product should be born from a talk between</p> <ul><li>business (analysts, product owner)</li> <li>developers</li> <li>QAs</li></ul> <p>which are known in BDD as "three amigos".</p> <p>Such talks should produce written stories. There should be an actor that doing some things, the feature that should be fulfilled within the story and the result achieved.</p> <p>We can try to write such simple story:</p> <div class="language- extra-class"><pre class="language-text"><code>As a customer I want to buy several products
I put first product with $600 price to my cart
And then another one with $1000 price
When I go to checkout process
I should see that total number of products I want to buy is 2
And my order amount is $1600
</code></pre></div><p>As we can see this simple story highlights core concepts that are called <em>contracts</em>. We should fulfill those contracts to model software correctly. But how we can verify that those contracts are being satisfied? <a href="https://cucumber.io" target="_blank" rel="noopener noreferrer">Cucumber<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> introduced a special language for such stories called <strong>Gherkin</strong>. Same story transformed to Gherkin will look like this:</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code><span class="token feature"><span class="token keyword">Feature:</span><span class="token important"> checkout process</span>
In order to buy products
As a customer
I want to be able to buy several products
</span>
<span class="token scenario"><span class="token keyword">Scenario:</span><span class="token important"></span></span>
<span class="token atrule">Given</span> <span class="token atrule">I</span> have product with $600 price in my cart
<span class="token atrule">And</span> <span class="token atrule">I</span> have product with $1000 price
<span class="token atrule">When</span> <span class="token atrule">I</span> go to checkout process
<span class="token atrule">Then</span> <span class="token atrule">I</span> should see that total number of products is 2
<span class="token atrule">And</span> my order amount is $1600
</code></pre></div><p><strong>CodeceptJS can execute this scenario step by step as an automated test</strong>.
Every step in this scenario requires a code which defines it.</p> <h2 id="gherkin"><a href="#gherkin" class="header-anchor">#</a> Gherkin</h2> <p>Let's learn some more about Gherkin format and then we will see how to execute it with CodeceptJS. We can enable Gherkin for current project by running <code>gherkin:init</code> command on <strong>already initialized project</strong>:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs gherkin:init
</code></pre></div><p>It will add <code>gherkin</code> section to the current config. It will also prepare directories for features and step definition. And it will create the first feature file for you.</p> <h3 id="features"><a href="#features" class="header-anchor">#</a> Features</h3> <p>Whenever you start writing a story you are describing a specific feature of an application, with a set of scenarios and examples describing this feature. Let's open a feature file created by <code>gherkin:init</code> command, which is <code>feature/basic.feature</code>.</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code><span class="token feature"><span class="token keyword">Feature:</span><span class="token important"> Business rules</span>
In order to achieve my goals
As a persona
I want to be able to interact with a system
</span>
<span class="token scenario"><span class="token keyword">Scenario:</span><span class="token important"> do something</span></span>
<span class="token atrule">Given</span> <span class="token atrule">I</span> have a defined step
</code></pre></div><p>This text should be rewritten to follow your buisness rules. Don't think about a web interface for a while.
Think about how user interacts with your system and what goals they want to achieve. Then write interaction scenarios.</p> <h4 id="scenarios"><a href="#scenarios" class="header-anchor">#</a> Scenarios</h4> <p>Scenarios are live examples of feature usage. Inside a feature file it should be written inside a <em>Feature</em> block. Each scenario should contain its title:</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code><span class="token feature"><span class="token keyword">Feature:</span><span class="token important"> checkout</span>
In order to buy product
As a customer
I need to be able to checkout the selected products
</span>
<span class="token scenario"><span class="token keyword">Scenario:</span><span class="token important"> order several products</span></span>
</code></pre></div><p>Scenarios are written in step-by-step manner using Given-When-Then approach. At start, scenario should describe its context with <strong>Given</strong> keyword:</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Given</span> <span class="token atrule">I</span> have product with $600 price in my cart
<span class="token atrule">And</span> <span class="token atrule">I</span> have product with $1000 price in my cart
</code></pre></div><p>Here we also use word <strong>And</strong> to extend the Given and not to repeat it in each line.</p> <p>This is how we described the initial conditions. Next, we perform some action. We use <strong>When</strong> keyword for it:</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">When</span> <span class="token atrule">I</span> go to checkout process
</code></pre></div><p>And in the end we are verifying our expectation using <strong>Then</strong> keyword. The action changed the initial given state, and produced some results. Let's check that those results are what we actually expect.</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Then</span> <span class="token atrule">I</span> should see that total number of products is 2
<span class="token atrule">And</span> my order amount is $1600
</code></pre></div><p>This scenarios are nice as live documentation but they do not test anything yet. What we need next is to define how to run those steps.
Steps can be defined by executing <code>gherkin:snippets</code> command:</p> <div class="language-bash extra-class"><pre class="language-bash"><code>npx codeceptjs gherkin:snippets <span class="token punctuation">[</span>--path<span class="token operator">=</span><span class="token environment constant">PATH</span><span class="token punctuation">]</span> <span class="token punctuation">[</span>--feature<span class="token operator">=</span><span class="token environment constant">PATH</span><span class="token punctuation">]</span>
</code></pre></div><p>This will produce code templates for all undefined steps in the .feature files.
By default, it will scan all of the <code>.feature</code> files specified in the <code>gherkin.features</code> section of the config and produce code templates for all undefined steps. If the <code>--feature</code> option is specified, it will scan the specified .feature file(s).
The stub definitions by default will be placed into the first file specified in the <code>gherkin.steps</code> section of the config. However, you may also use <code>--path</code> to specify a specific file in which to place all undefined steps. This file must exist and be in the `gherkin.steps array of the config.
Our next step will be to define those steps and transforming feature-file into a valid test.</p> <h3 id="step-definitions"><a href="#step-definitions" class="header-anchor">#</a> Step Definitions</h3> <p>Step definitions are placed in JavaScript file with Given/When/Then functions that map strings from feature file to functions:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// use I and productPage via inject() function</span>
<span class="token keyword">const</span> <span class="token punctuation">{</span> <span class="token constant">I</span><span class="token punctuation">,</span> productPage <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">inject</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// you can provide RegEx to match corresponding steps</span>
<span class="token function">Given</span><span class="token punctuation">(</span><span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">I have product with \$(\d+) price</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">price</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">amOnPage</span><span class="token punctuation">(</span><span class="token string">'/products'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
productPage<span class="token punctuation">.</span><span class="token function">create</span><span class="token punctuation">(</span><span class="token punctuation">{</span> price <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token string">'Add to cart'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// or a simple string</span>
<span class="token function">When</span><span class="token punctuation">(</span><span class="token string">'I go to checkout process'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">click</span><span class="token punctuation">(</span><span class="token string">'Checkout'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// parameters are passed in via Cucumber expressions</span>
<span class="token function">Then</span><span class="token punctuation">(</span><span class="token string">'I should see that total number of products is {int}'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">num</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">see</span><span class="token punctuation">(</span>num<span class="token punctuation">,</span> <span class="token string">'.cart'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Then</span><span class="token punctuation">(</span><span class="token string">'my order amount is ${int}'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">sum</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// eslint-disable-line</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">see</span><span class="token punctuation">(</span><span class="token string">'Total: '</span> <span class="token operator">+</span> sum<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Steps can be either strings or regular expressions. Parameters from string are passed as function arguments. To define parameters in a string we use <a href="https://github.com/cucumber/cucumber-expressions#readme" target="_blank" rel="noopener noreferrer">Cucumber expressions<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></p> <p>To list all defined steps run <code>gherkin:steps</code> command:</p> <div class="language-bash extra-class"><pre class="language-bash"><code>npx codeceptjs gherkin:steps
</code></pre></div><p>Use <code>grep</code> to find steps in a list (grep works on Linux & MacOS):</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs gherkin:steps | grep user
</code></pre></div><p>To run tests and see step-by step output use <code>--steps</code> optoin:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --steps
</code></pre></div><p>To see not only business steps but an actual performed steps use <code>--debug</code> flag:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --debug
</code></pre></div><h2 id="advanced-gherkin"><a href="#advanced-gherkin" class="header-anchor">#</a> Advanced Gherkin</h2> <p>Let's improve our BDD suite by using the advanced features of Gherkin language.</p> <h3 id="background"><a href="#background" class="header-anchor">#</a> Background</h3> <p>If a group of scenarios have the same initial steps, let's that for dashboard we need always need to be logged in as administrator. We can use <em>Background</em> section to do the required preparations and not to repeat same steps across scenarios.</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code><span class="token feature"><span class="token keyword">Feature:</span><span class="token important"> Dashboard</span>
In order to view current state of business
As an owner
I need to be able to see reports on dashboard
</span>
<span class="token scenario"><span class="token keyword">Background:</span><span class="token important"></span></span>
<span class="token atrule">Given</span> <span class="token atrule">I</span> am logged in as administrator
<span class="token atrule">And</span> <span class="token atrule">I</span> open dashboard page
</code></pre></div><p>Steps in background are defined the same way as in scenarios.</p> <h3 id="tables"><a href="#tables" class="header-anchor">#</a> Tables</h3> <p>Scenarios can become more descriptive when you represent repeating data as tables. Instead of writing several steps "I have product with :num1 $ price in my cart" we can have one step with multiple values in it.</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Given</span> <span class="token atrule">I</span> have products in my cart<span class="token table-head">
<span class="token punctuation">|</span><span class="token th variable"> name </span><span class="token punctuation">|</span><span class="token th variable"> category </span><span class="token punctuation">|</span><span class="token th variable"> price </span><span class="token punctuation">|</span></span><span class="token table-body">
<span class="token punctuation">|</span><span class="token td string"> Harry Potter </span><span class="token punctuation">|</span><span class="token td string"> Books </span><span class="token punctuation">|</span><span class="token td string"> 5 </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> iPhone 5 </span><span class="token punctuation">|</span><span class="token td string"> Smartphones </span><span class="token punctuation">|</span><span class="token td string"> 1200 </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> Nuclear Bomb </span><span class="token punctuation">|</span><span class="token td string"> Weapons </span><span class="token punctuation">|</span><span class="token td string"> 100000 </span><span class="token punctuation">|</span></span>
</code></pre></div><p>Tables are the recommended way to pass arrays into test scenarios.
Inside a step definition data is stored in argument passed as <code>DataTable</code> JavaScript object.
You can iterate on it like this:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'I have products in my cart'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">table</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// eslint-disable-line</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> id <span class="token keyword">in</span> table<span class="token punctuation">.</span>rows<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">if</span> <span class="token punctuation">(</span>id <span class="token operator"><</span> <span class="token number">1</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">continue</span><span class="token punctuation">;</span> <span class="token comment">// skip a header of a table</span>
<span class="token punctuation">}</span>
<span class="token comment">// go by row cells</span>
<span class="token keyword">const</span> cells <span class="token operator">=</span> table<span class="token punctuation">.</span>rows<span class="token punctuation">[</span>id<span class="token punctuation">]</span><span class="token punctuation">.</span>cells<span class="token punctuation">;</span>
<span class="token comment">// take values</span>
<span class="token keyword">const</span> name <span class="token operator">=</span> cells<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span>
<span class="token keyword">const</span> category <span class="token operator">=</span> cells<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">]</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span>
<span class="token keyword">const</span> price <span class="token operator">=</span> cells<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token punctuation">.</span>value<span class="token punctuation">;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>You can also use the <code>parse()</code> method to obtain an object that allow you to get a simple version of the table parsed by column or row, with header (or not):</p> <ul><li><code>raw()</code> - returns the table as a 2-D array</li> <li><code>rows()</code> - returns the table as a 2-D array, without the first row</li> <li><code>hashes()</code> - returns an array of objects where each row is converted to an object (column header is the key)</li> <li><code>rowsHash()</code> - returns an object where each row corresponds to an entry(first column is the key, second column is the value)</li> <li><code>transpose()</code> - transpose the data, returns nothing. To work with the transposed table use the methods above.</li></ul> <p>If we use hashes() with the previous example :</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'I have products in my cart'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">table</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token comment">// eslint-disable-line</span>
<span class="token comment">//parse the table by header</span>
<span class="token keyword">const</span> tableByHeader <span class="token operator">=</span> table<span class="token punctuation">.</span><span class="token function">parse</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">hashes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">const</span> row <span class="token keyword">of</span> tableByHeader<span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token comment">// take values</span>
<span class="token keyword">const</span> name <span class="token operator">=</span> row<span class="token punctuation">.</span>name<span class="token punctuation">;</span>
<span class="token keyword">const</span> category <span class="token operator">=</span> row<span class="token punctuation">.</span>category<span class="token punctuation">;</span>
<span class="token keyword">const</span> price <span class="token operator">=</span> row<span class="token punctuation">.</span>price<span class="token punctuation">;</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>Examples of tables using:</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Given</span> <span class="token atrule">I</span> have a short employees card<span class="token table-head">
<span class="token punctuation">|</span><span class="token th variable"> Harry </span><span class="token punctuation">|</span><span class="token th variable"> Potter </span><span class="token punctuation">|</span></span><span class="token table-body">
<span class="token punctuation">|</span><span class="token td string"> Chuck </span><span class="token punctuation">|</span><span class="token td string"> Norris </span><span class="token punctuation">|</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token punctuation">{</span> DataTableArgument <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'codeceptjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//...</span>
<span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'I have a short employees card'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">table</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> dataTableArgument <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataTableArgument</span><span class="token punctuation">(</span>table<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> raw <span class="token operator">=</span> dataTableArgument<span class="token punctuation">.</span><span class="token function">raw</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// row = [['Harry', 'Potter'], ['Chuck', 'Norris']]</span>
dataTableArgument<span class="token punctuation">.</span><span class="token function">transpose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> transposedRaw <span class="token operator">=</span> dataTableArgument<span class="token punctuation">.</span><span class="token function">raw</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// transposedRaw = [['Harry', 'Chuck'], ['Potter', 'Norris']];</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Given</span> <span class="token atrule">I</span> have an employee card<span class="token table-head">
<span class="token punctuation">|</span><span class="token th variable"> name </span><span class="token punctuation">|</span><span class="token th variable"> surname </span><span class="token punctuation">|</span><span class="token th variable"> position </span><span class="token punctuation">|</span></span><span class="token table-body">
<span class="token punctuation">|</span><span class="token td string"> Harry </span><span class="token punctuation">|</span><span class="token td string"> Potter </span><span class="token punctuation">|</span><span class="token td string"> Seeker </span><span class="token punctuation">|</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token punctuation">{</span> DataTableArgument <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'codeceptjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//...</span>
<span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'I have an employee card'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">table</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> dataTableArgument <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataTableArgument</span><span class="token punctuation">(</span>table<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> hashes <span class="token operator">=</span> dataTableArgument<span class="token punctuation">.</span><span class="token function">hashes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// hashes = [{ name: 'Harry', surname: 'Potter', position: 'Seeker' }];</span>
<span class="token keyword">const</span> rows <span class="token operator">=</span> dataTableArgument<span class="token punctuation">.</span><span class="token function">rows</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// rows = [['Harry', 'Potter', Seeker]];</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Given</span> <span class="token atrule">I</span> have a formatted employee card<span class="token table-head">
<span class="token punctuation">|</span><span class="token th variable"> name </span><span class="token punctuation">|</span><span class="token th variable"> Harry </span><span class="token punctuation">|</span></span><span class="token table-body">
<span class="token punctuation">|</span><span class="token td string"> surname </span><span class="token punctuation">|</span><span class="token td string"> Potter </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> position </span><span class="token punctuation">|</span><span class="token td string"> Seeker </span><span class="token punctuation">|</span></span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token punctuation">{</span> DataTableArgument <span class="token punctuation">}</span> <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'codeceptjs'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">//...</span>
<span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'I have a formatted employee card'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">table</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> dataTableArgument <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">DataTableArgument</span><span class="token punctuation">(</span>table<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">const</span> rawHash <span class="token operator">=</span> dataTableArgument<span class="token punctuation">.</span><span class="token function">rowsHash</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// rawHash = { name: 'Harry', surname: 'Potter', position: 'Seeker' };</span>
<span class="token punctuation">}</span>
<span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="examples"><a href="#examples" class="header-anchor">#</a> Examples</h3> <p>In case scenarios represent the same logic but differ on data, we can use <em>Scenario Outline</em> to provide different examples for the same behavior. Scenario outline is just like a basic scenario with some values replaced with placeholders, which are filled from a table. Each set of values is executed as a different test.</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token scenario"><span class="token keyword">Scenario Outline:</span><span class="token important"> order discount</span></span>
<span class="token atrule">Given</span> <span class="token atrule">I</span> have product with price <span class="token outline variable"><price></span>$ in my cart
<span class="token atrule">And</span> discount for orders greater than $20 is 10 %
<span class="token atrule">When</span> <span class="token atrule">I</span> go to checkout
<span class="token atrule">Then</span> <span class="token atrule">I</span> should see overall price is <span class="token string">"<span class="token outline variable"><total></span>"</span> $
<span class="token scenario"><span class="token keyword">Examples:</span><span class="token important"></span></span><span class="token table-head">
<span class="token punctuation">|</span><span class="token th variable"> price </span><span class="token punctuation">|</span><span class="token th variable"> total </span><span class="token punctuation">|</span></span><span class="token table-body">
<span class="token punctuation">|</span><span class="token td string"> 10 </span><span class="token punctuation">|</span><span class="token td string"> 10 </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> 20 </span><span class="token punctuation">|</span><span class="token td string"> 20 </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> 21 </span><span class="token punctuation">|</span><span class="token td string"> 18.9 </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> 30 </span><span class="token punctuation">|</span><span class="token td string"> 27 </span><span class="token punctuation">|</span>
<span class="token punctuation">|</span><span class="token td string"> 50 </span><span class="token punctuation">|</span><span class="token td string"> 45 </span><span class="token punctuation">|</span></span>
</code></pre></div><p>It might be the case that the same column value needs to be utilized multiple times in the same step, that also can be possible with scenario outline.</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token scenario"><span class="token keyword">Scenario Outline:</span><span class="token important"> check parameter substitution</span></span>
<span class="token atrule">Given</span> <span class="token atrule">I</span> have a defined step
<span class="token atrule">When</span> <span class="token atrule">I</span> see <span class="token string">"<span class="token outline variable"><text></span>"</span> text and <span class="token string">"<span class="token outline variable"><text></span>"</span> is not <span class="token string">"xyz"</span>
<span class="token scenario"><span class="token keyword">Examples:</span><span class="token important"></span></span><span class="token table-head">
<span class="token punctuation">|</span><span class="token th variable"> text </span><span class="token punctuation">|</span></span><span class="token table-body">
<span class="token punctuation">|</span><span class="token td string"> Google </span><span class="token punctuation">|</span></span>
</code></pre></div><h3 id="long-strings"><a href="#long-strings" class="header-anchor">#</a> Long Strings</h3> <p>Text values inside a scenarios can be set inside a <code>"""</code> block:</p> <div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token atrule">Then</span> i see in file <span class="token string">"codecept.json"</span>
<span class="token pystring string">"""
{
"output": "./output",
"helpers": {
"Puppeteer": {
"url": "http://localhost",
"restart": true,
"windowSize": "1600x1200"
}
"""</span>
</code></pre></div><p>This string can be accessed inside a <code>content</code> property of a last argument:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Then</span><span class="token punctuation">(</span><span class="token string">'Then i see in file {string}'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">file<span class="token punctuation">,</span> text</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// file is a value of {string} from a title</span>
<span class="token keyword">const</span> fileContent <span class="token operator">=</span> fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span>file<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
fileContent<span class="token punctuation">.</span>should<span class="token punctuation">.</span><span class="token function">include</span><span class="token punctuation">(</span>text<span class="token punctuation">.</span>content<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// text.content is a value</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h3 id="tags"><a href="#tags" class="header-anchor">#</a> Tags</h3> <p>Gherkin scenarios and features can contain tags marked with <code>@</code>. Tags are appended to feature titles so you can easily filter by them when running tests:</p> <div class="language-bash extra-class"><pre class="language-bash"><code>npx codeceptjs run <span class="token parameter variable">--grep</span> <span class="token string">"@important"</span>
</code></pre></div><p>Tag should be placed before <em>Scenario:</em> or before <em>Feature:</em> keyword. In the last case all scenarios of that feature will be added to corresponding group.</p> <h3 id="custom-types"><a href="#custom-types" class="header-anchor">#</a> Custom types</h3> <p>If you need parameter text in more advanced way, and you like using <a href="https://github.com/cucumber/cucumber-expressions#readme" target="_blank" rel="noopener noreferrer">Cucumber expressions<span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a> better that regular expressions, use <code>DefineParameterType</code> function. You can extend Cucumber Expressions, so they automatically convert output parameters to your own types or transforms the match from the regexp.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">DefineParameterType</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
<span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'popup_type'</span><span class="token punctuation">,</span>
<span class="token literal-property property">regexp</span><span class="token operator">:</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">critical|non-critical</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">,</span>
<span class="token function-variable function">transformer</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token parameter">match</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">return</span> match <span class="token operator">===</span> <span class="token string">'critical'</span> <span class="token operator">?</span> <span class="token string">'[class$="error"]'</span>
<span class="token operator">:</span> <span class="token string">'[class$="warning"]'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">;</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'I see {popup_type} popup'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter">popup</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span>popup<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><div class="language-gherkin extra-class"><pre class="language-gherkin"><code> <span class="token scenario"><span class="token keyword">Scenario:</span><span class="token important"> Display error message if user doesn't have permissions</span></span>
<span class="token atrule">Given</span> <span class="token atrule">I</span> on <span class="token string">"Main"</span> page without permissons
<span class="token atrule">Then</span> <span class="token atrule">I</span> see error popup
</code></pre></div><h4 id="parameters"><a href="#parameters" class="header-anchor">#</a> Parameters</h4> <ul><li><code>name</code> <strong>[string]</strong> The name the parameter type will be recognised by in output parameters.</li> <li><code>regexp</code> <strong>([string] | [RegExp])</strong> A regexp that will match the parameter. May include capture groups.</li> <li><code>transformer</code> <strong>[function]</strong> A function or method that transforms the match from the regexp.</li> <li><code>useForSnippets</code> <strong>[boolean]</strong> Defaults to <code>true</code>. That means this parameter type will be used to generate snippets for undefined steps.</li> <li><code>preferForRegexpMatch</code> <strong>[boolean]</strong> Defaults to <code>false</code>. Set to true if you have step definitions that use regular expressions, and you want this parameter type to take precedence over others during a match.</li></ul> <h2 id="configuration"><a href="#configuration" class="header-anchor">#</a> Configuration</h2> <ul><li><code>gherkin</code> <ul><li><code>features</code> - path to feature files, or an array of feature file paths</li> <li><code>steps</code> - array of files with step definitions</li> <li><code>avoidDuplicateSteps</code> - attempts to avoid duplicate step definitions by shallow compare</li></ul></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">...</span>
<span class="token string-property property">"gherkin"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"features"</span><span class="token operator">:</span> <span class="token string">"./features/*.feature"</span><span class="token punctuation">,</span>
<span class="token string-property property">"steps"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token string">"./step_definitions/steps.js"</span>
<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token operator">...</span>
</code></pre></div><div class="language-js extra-class"><pre class="language-js"><code><span class="token operator">...</span>
<span class="token string-property property">"gherkin"</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token string-property property">"features"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token string">"./features/*.feature"</span><span class="token punctuation">,</span>
<span class="token string">"./features/api_features/*.feature"</span>
<span class="token punctuation">]</span><span class="token punctuation">,</span>
<span class="token string-property property">"steps"</span><span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token string">"./step_definitions/steps.js"</span>
<span class="token punctuation">]</span>
<span class="token punctuation">}</span>
<span class="token operator">...</span>
</code></pre></div><h2 id="before"><a href="#before" class="header-anchor">#</a> Before</h2> <p>You can set up some before hooks inside step definition files. Use <code>Before</code> function to do that.
This function receives current test as a parameter, so you can apply additional configuration to it.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// inside step_definitions</span>
<span class="token function">Before</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">test</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// perform your code</span>
test<span class="token punctuation">.</span><span class="token function">retries</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">// retry test 3 times</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><p>This can be used to keep state between steps:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">let</span> state <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token comment">// inside step_definitions</span>
<span class="token function">Before</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
state <span class="token operator">=</span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Given</span><span class="token punctuation">(</span><span class="token string">'have a user'</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
state<span class="token punctuation">.</span>user <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">have</span><span class="token punctuation">(</span><span class="token string">'user'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">When</span><span class="token punctuation">(</span><span class="token string">'I open account page'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">amOnPage</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">/user/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>state<span class="token punctuation">.</span>user<span class="token punctuation">.</span>slug<span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="after"><a href="#after" class="header-anchor">#</a> After</h2> <p>Similarly to <code>Before</code> you can use <code>After</code> and <code>Fail</code> inside a scenario. <code>Fail</code> hook is activated on failure and receive two parameters: <code>test</code> and current <code>error</code>.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">After</span><span class="token punctuation">(</span><span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">await</span> someService<span class="token punctuation">.</span><span class="token function">cleanup</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">Fail</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter">test<span class="token punctuation">,</span> err</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// test didn't</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'Failed with'</span><span class="token punctuation">,</span> err<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">pause</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
</code></pre></div><h2 id="tests-vs-features"><a href="#tests-vs-features" class="header-anchor">#</a> Tests vs Features</h2> <p>It is common to think that BDD scenario is equal to test. But it's actually not. Not every test should be described as a feature. Not every test is written to test real business value. For instance, regression tests or negative scenario tests are not bringing any value to business. Business analysts don't care about scenario reproducing bug #13, or what error message is displayed when user tries to enter wrong password on login screen. Writing all the tests inside a feature files creates informational overflow.</p> <p>In CodeceptJS, you can combine tests written in Gherkin format with classical acceptance tests. This way you can keep your feature files compact with minimal set of scenarios, and write regular tests to cover all cases. Please note, feature files will be executed before tests.</p> <p>To run only features use <code>--features</code> option:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --features
</code></pre></div><p>You can run a specific feature file by its filename or by grepping by name or tag.</p> <p>To run only tests without features use <code>--tests</code> option:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --tests
</code></pre></div></div></article></div> <div class="page-edit"><div class="edit-link"><a href="https://github.com/codeceptjs/codeceptjs/edit/3.x/docs/bdd.md" target="_blank" rel="noopener noreferrer">Help us improve this page!</a> <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></div> <div class="last-updated"><span class="prefix">Last Updated:</span> <span class="time">11/7/2023, 6:18:35 PM</span></div></div> <div class="page-nav"><p class="inner"><span class="prev">
←
<a href="/data/" class="prev">Data Management</a></span> <span class="next"><a href="/locators/">Locators</a>
→
</span></p></div> <div class="banner" data-v-436508ca><a href="https://opencollective.com/codeceptjs" data-v-436508ca>CodeceptJS is on OpenCollective! Support us 💖</a></div> <footer data-v-5616cc4e><section data-v-5616cc4e><div class="col" data-v-5616cc4e><h4 data-v-5616cc4e>Docs</h4> <ul data-v-5616cc4e><li data-v-5616cc4e><a href="/quickstart" data-v-5616cc4e>Quickstart</a></li> <li data-v-5616cc4e><a href="/basics" data-v-5616cc4e>Getting Started</a></li> <li data-v-5616cc4e><a href="/playwright" data-v-5616cc4e>CodeceptJS & Playwright</a></li> <li data-v-5616cc4e><a href="/puppeteer" data-v-5616cc4e>CodeceptJS & WebDriver</a></li></ul></div> <div class="col" data-v-5616cc4e><h4 data-v-5616cc4e>Community</h4> <ul data-v-5616cc4e><li data-v-5616cc4e><a href="https://github.com/codeceptjs/CodeceptJS" data-v-5616cc4e>GitHub</a></li> <li data-v-5616cc4e><a href="https://github.com/codeceptjs/CodeceptJS/discussions" data-v-5616cc4e>GitHub discussions</a></li> <li data-v-5616cc4e><a href="https://bit.ly/chat-codeceptjs" data-v-5616cc4e>Slack Chat</a></li> <li data-v-5616cc4e><a href="https://codecept.discourse.group/" data-v-5616cc4e>Forum</a></li> <li data-v-5616cc4e><a href="https://twitter.com/codeceptjs" data-v-5616cc4e>Twitter</a></li></ul></div> <div class="col" data-v-5616cc4e><h4 class="important" data-v-5616cc4e>Commercial Support</h4> <ul data-v-5616cc4e><li data-v-5616cc4e><a href="https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=footer&utm_term=link&utm_campaign=reference" data-v-5616cc4e>Consulting</a></li> <li data-v-5616cc4e><a href="https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=top_menu&utm_term=link&utm_campaign=reference" data-v-5616cc4e>Trainings</a></li> <li data-v-5616cc4e><a href="https://sdclabs.com/#services" data-v-5616cc4e>Hire Engineers</a></li></ul></div> <div class="col" data-v-5616cc4e><a href="https://testomat.io" data-v-5616cc4e><h4 data-v-5616cc4e>Try Testomat.io →</h4> <p data-v-5616cc4e>Powerful <b data-v-5616cc4e>Test Case Management</b> for CodeceptJS from its authors</p></a></div></section> <div class="copyright" data-v-5616cc4e><h5 data-v-5616cc4e>CodeceptJS - supercharged end 2 end testing framework for NodeJS</h5>
© 2025
</div></footer></main> <div class="sidebar" data-v-0dc4070a><div class="sidebar-wrapper" data-v-0dc4070a><h4 data-v-0dc4070a>More Information</h4> <p data-v-0dc4070a><a href="/videos" data-v-0dc4070a>Videos</a></p> <p data-v-0dc4070a><a href="/books" data-v-0dc4070a>Books & Posts</a></p> <p data-v-0dc4070a><a href="/examples" data-v-0dc4070a>Examples</a></p> <p data-v-0dc4070a><a href="https://codecept.discourse.group/c/cookbook" data-v-0dc4070a>Cookbook →</a></p> <hr data-v-0dc4070a> <p class="border" data-v-0dc4070a><a href="https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=right&utm_term=link&utm_campaign=reference" class="dashed" data-v-0dc4070a>
Commercial Services →
</a></p> <p class="border" data-v-0dc4070a><a href="https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=rigth&utm_term=link&utm_campaign=reference" class="dashed" data-v-0dc4070a>
Trainings →
</a></p> <p class="border" data-v-0dc4070a><a href="https://testomat.io" class="dashed" data-v-0dc4070a>
Testomat.io →
</a><br data-v-0dc4070a> <small data-v-0dc4070a><b data-v-0dc4070a>Plan your end 2 end tests</b>, collaborate, synchronize with code & get reports!<br data-v-0dc4070a>
Join Testomat.io while it is in beta and get a huge discount!</small></p> <p class="border" data-v-0dc4070a><a href="https://opencollective.com/codeceptjs" class="dashed" data-v-0dc4070a>
Support us via OpenCollective!
</a></p></div></div></div><div class="global-ui"></div></div>
<script src="/assets/js/app.6cba3458.js" defer></script><script src="/assets/js/5.ff420ac6.js" defer></script><script src="/assets/js/1.c70685ea.js" defer></script><script src="/assets/js/36.722e0c70.js" defer></script>
</body>
</html>