-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.html
470 lines (454 loc) · 165 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
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Getting Started | 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/35.db84cbc0.js" as="script"><link rel="preload" href="/assets/js/7.f6967540.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/36.722e0c70.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/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 open"><span>Web Testing</span> <span class="arrow open"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/basics/" aria-current="page" class="active sidebar-link">Getting Started</a><ul class="sidebar-sub-headers" data-v-a68ca4e6><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#architecture" class="sidebar-link">Architecture</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#writing-tests" class="sidebar-link">Writing Tests</a><ul class="sidebar-sub-headers" data-v-a68ca4e6><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#opening-a-page" class="sidebar-link">Opening a Page</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#locating-element" class="sidebar-link">Locating Element</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#clicking" class="sidebar-link">Clicking</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#filling-fields" class="sidebar-link">Filling Fields</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#assertions" class="sidebar-link">Assertions</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#grabbing" class="sidebar-link">Grabbing</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#waiting" class="sidebar-link">Waiting</a></li></ul></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#how-it-works" class="sidebar-link">How It Works</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#running-tests" class="sidebar-link">Running Tests</a><ul class="sidebar-sub-headers" data-v-a68ca4e6><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#level-of-detail" class="sidebar-link">Level of Detail</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#filter" class="sidebar-link">Filter</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#parallel-run" class="sidebar-link">Parallel Run</a></li></ul></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#configuration" class="sidebar-link">Configuration</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#debug" class="sidebar-link">Debug</a><ul class="sidebar-sub-headers" data-v-a68ca4e6><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#pause" class="sidebar-link">Pause</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#pause-on-fail" class="sidebar-link">Pause on Fail</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#screenshot-on-failure" class="sidebar-link">Screenshot on Failure</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#step-by-step-report" class="sidebar-link">Step By Step Report</a></li></ul></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#before" class="sidebar-link">Before</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#beforesuite" class="sidebar-link">BeforeSuite</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retries" class="sidebar-link">Retries</a><ul class="sidebar-sub-headers" data-v-a68ca4e6><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#auto-retry" class="sidebar-link">Auto Retry</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-step" class="sidebar-link">Retry Step</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-multiple-steps" class="sidebar-link">Retry Multiple Steps</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-scenario" class="sidebar-link">Retry Scenario</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-before" class="sidebar-link">Retry Before</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-feature" class="sidebar-link">Retry Feature</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-configuration" class="sidebar-link">Retry Configuration</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#retry-run" class="sidebar-link">Retry Run</a></li></ul></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#within" class="sidebar-link">Within</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#conditional-actions" class="sidebar-link">Conditional Actions</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#comments" class="sidebar-link">Comments</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#intellisense" class="sidebar-link">IntelliSense</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#multiple-sessions" class="sidebar-link">Multiple Sessions</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#skipping" class="sidebar-link">Skipping</a></li><li class="sidebar-sub-header" data-v-a68ca4e6><a href="/basics/#todo-test" class="sidebar-link">Todo Test</a></li></ul></li><li><a href="/ui/" class="sidebar-link">CodeceptUI</a></li><li><a href="/playwright/" class="sidebar-link">Testing with Playwright</a></li><li><a href="/webdriver/" class="sidebar-link">Testing with WebDriver</a></li><li><a href="/puppeteer/" class="sidebar-link">Testing with Puppeteer</a></li><li><a href="/api/" class="sidebar-link">API Testing</a></li><li><a href="/testcafe/" class="sidebar-link">Testing with TestCafe</a></li></ul></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"><span>Organizing Tests</span> <span class="arrow"></span></p> <!----></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">Getting Started</div> <div class="post"><article><div class="theme-default-content content__default"><h1 id="getting-started"><a href="#getting-started" class="header-anchor">#</a> Getting Started</h1> <p>CodeceptJS is a modern end to end testing framework with a special BDD-style syntax. The tests are written as a linear scenario of the user's action on a site.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Feature</span><span class="token punctuation">(</span><span class="token string">'CodeceptJS demo'</span><span class="token punctuation">)</span>
<span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'check Welcome page on site'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">'/'</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><span class="token string">'Welcome'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Tests are expected to be written in <strong>ECMAScript 7</strong>.</p> <p>Each test is described inside a <code>Scenario</code> function with the <code>I</code> object passed into it.
The <code>I</code> object is an <strong>actor</strong>, an abstraction for a testing user. The <code>I</code> is a proxy object for currently enabled <strong>Helpers</strong>.</p> <h2 id="architecture"><a href="#architecture" class="header-anchor">#</a> Architecture</h2> <p>CodeceptJS bypasses execution commands to helpers. Depending on the helper enabled, your tests will be executed differently.</p> <p>The following is a diagram of the CodeceptJS architecture:</p> <p><img src="/img/architecture.png" alt="architecture"></p> <p>All helpers share the same API, so it's easy to migrate tests from one backend to another.
However, because of the difference in backends and their limitations, they are not guaranteed to be compatible with each other. For instance, you can't set request headers in WebDriver but you can do so in Playwright or Puppeteer.</p> <p><strong>Pick one helper, as it defines how tests are executed.</strong> If requirements change it's easy to migrate to another.</p> <hr> <p>Refer to following guides to more information on:</p> <ul><li><a href="/playwright">▶ Playwright</a></li> <li><a href="/webdriver">▶ WebDriver</a></li> <li><a href="/puppeteer">▶ Puppeteer</a></li> <li><a href="/testcafe">▶ TestCafe</a></li></ul> <blockquote><p>ℹ Depending on a helper selected a list of available actions may change.</p></blockquote> <p>To list all available commands for the current configuration run <code>codeceptjs list</code>
or enable <a href="#intellisense">auto-completion by generating TypeScript definitions</a>.</p> <blockquote><p>🤔 It is possible to access API of a backend you use inside a test or a <a href="/helpers/">custom helper</a>. For instance, to use Puppeteer API inside a test use <a href="/helpers/Puppeteer/#usepuppeteerto"><code>I.usePuppeteerTo</code></a> inside a test. Similar methods exist for each helper.</p></blockquote> <h2 id="writing-tests"><a href="#writing-tests" class="header-anchor">#</a> Writing Tests</h2> <p>Tests are written from a user's perspective. There is an actor (represented as <code>I</code>) which contains actions taken from helpers. A test is written as a sequence of actions performed by an actor:</p> <div class="language-js extra-class"><pre class="language-js"><code><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">'/'</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">'Login'</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><span class="token string">'Please Login'</span><span class="token punctuation">,</span> <span class="token string">'h1'</span><span class="token punctuation">)</span>
<span class="token comment">// ...</span>
</code></pre></div><h3 id="opening-a-page"><a href="#opening-a-page" class="header-anchor">#</a> Opening a Page</h3> <p>A test should usually start by navigating the browser to a website.</p> <p>Start a test by opening a page. Use the <code>I.amOnPage()</code> command for this:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// When "http://site.com" is url in config</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">'/'</span><span class="token punctuation">)</span> <span class="token comment">// -> opens http://site.com/</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">'/about'</span><span class="token punctuation">)</span> <span class="token comment">// -> opens http://site.com/about</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">'https://google.com'</span><span class="token punctuation">)</span> <span class="token comment">// -> https://google.com</span>
</code></pre></div><p>When an URL doesn't start with a protocol (http:// or https://) it is considered to be a relative URL and will be appended to the URL which was initially set-up in the config.</p> <blockquote><p>It is recommended to use a relative URL and keep the base URL in the config file, so you can easily switch between development, stage, and production environments.</p></blockquote> <h3 id="locating-element"><a href="#locating-element" class="header-anchor">#</a> Locating Element</h3> <p>Element can be found by CSS or XPath locators.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span><span class="token string">'.user'</span><span class="token punctuation">)</span> <span class="token comment">// element with CSS class user</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span><span class="token string">'//button[contains(., "press me")]'</span><span class="token punctuation">)</span> <span class="token comment">// button</span>
</code></pre></div><p>By default CodeceptJS tries to guess the locator type.
In order to specify the exact locator type you can pass an object called <strong>strict locator</strong>.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">css</span><span class="token operator">:</span> <span class="token string">'div.user'</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">seeElement</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">xpath</span><span class="token operator">:</span> <span class="token string">'//div[@class=user]'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Strict locators allow to specify additional locator types:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// locate form element by name</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</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">'password'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// locate element by React component and props</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">react</span><span class="token operator">:</span> <span class="token string">'user-profile'</span><span class="token punctuation">,</span> <span class="token literal-property property">props</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token literal-property property">name</span><span class="token operator">:</span> <span class="token string">'davert'</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>In <a href="https://codecept.io/mobile/#locating-elements" target="_blank" rel="noopener noreferrer">mobile testing<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> you can use <code>~</code> to specify the accessibility id to locate an element. In web application you can locate elements by their <code>aria-label</code> value.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// locate element by [aria-label] attribute in web</span>
<span class="token comment">// or by accessibility id in mobile</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span><span class="token string">'~username'</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p><a href="/locators">▶ Learn more about using locators in CodeceptJS</a>.</p></blockquote> <h3 id="clicking"><a href="#clicking" class="header-anchor">#</a> Clicking</h3> <p>CodeceptJS provides a flexible syntax to specify an element to click.</p> <p>By default CodeceptJS tries to find the button or link with the exact text on it</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// search for link or button</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">'Login'</span><span class="token punctuation">)</span>
</code></pre></div><p>If none was found, CodeceptJS tries to find a link or button containing that text. In case an image is clickable its <code>alt</code> attribute will be checked for text inclusion. Form buttons will also be searched by name.</p> <p>To narrow down the results you can specify a context in the second parameter.</p> <div class="language-js extra-class"><pre class="language-js"><code><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">'Login'</span><span class="token punctuation">,</span> <span class="token string">'.nav'</span><span class="token punctuation">)</span> <span class="token comment">// search only in .nav</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">'Login'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">css</span><span class="token operator">:</span> <span class="token string">'footer'</span> <span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token comment">// search only in footer</span>
</code></pre></div><blockquote><p>To skip guessing the locator type, pass in a strict locator - A locator starting with '#' or '.' is considered to be CSS. Locators starting with '//' or './/' are considered to be XPath.</p></blockquote> <p>You are not limited to buttons and links. Any element can be found by passing in valid CSS or XPath:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// click element by CSS</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">'#signup'</span><span class="token punctuation">)</span>
<span class="token comment">// click element located by special test-id attribute</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">'//dev[@test-id="myid"]'</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>ℹ If click doesn't work in a test but works for user, it is possible that frontend application is not designed for automated testing. To overcome limitation of standard click in this edgecase use <code>forceClick</code> method. It will emulate click instead of sending native event. This command will click an element no matter if this element is visible or animating. It will send JavaScript "click" event to it.</p></blockquote> <h3 id="filling-fields"><a href="#filling-fields" class="header-anchor">#</a> Filling Fields</h3> <p>Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.</p> <p>Let's submit this sample form for a test:</p> <p><img src="https://user-images.githubusercontent.com/220264/80355863-494a8280-8881-11ea-9b41-ba1f07abf094.png" alt=""></p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>form</span> <span class="token attr-name">method</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>post<span class="token punctuation">"</span></span> <span class="token attr-name">action</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>/update<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>update_form<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_name<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Name<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user[name]<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_name<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>br</span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_email<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Email<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>text<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user[email]<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_email<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>br</span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_role<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Role<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>select</span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user_role<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>user[role]<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>option</span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>0<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Admin<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>option</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>option</span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>1<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>User<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>option</span><span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"></</span>select</span>
<span class="token punctuation">></span></span><span class="token tag"><span class="token tag"><span class="token punctuation"><</span>br</span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>checkbox<span class="token punctuation">"</span></span> <span class="token attr-name">id</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>accept<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span>label</span> <span class="token attr-name">for</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>accept<span class="token punctuation">"</span></span><span class="token punctuation">></span></span>Accept changes<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>label</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"><</span>input</span> <span class="token attr-name">type</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submit<span class="token punctuation">"</span></span> <span class="token attr-name">name</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>submitButton<span class="token punctuation">"</span></span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>btn btn-primary<span class="token punctuation">"</span></span> <span class="token attr-name">value</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">"</span>Save<span class="token punctuation">"</span></span> <span class="token punctuation">/></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>div</span><span class="token punctuation">></span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation"></</span>form</span><span class="token punctuation">></span></span>
</code></pre></div><p>We need to fill in all those fields and click the "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// we are using label to match user_name field</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'Name'</span><span class="token punctuation">,</span> <span class="token string">'Miles'</span><span class="token punctuation">)</span>
<span class="token comment">// we can use input name</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'user[email]'</span><span class="token punctuation">,</span> <span class="token string">'[email protected]'</span><span class="token punctuation">)</span>
<span class="token comment">// select element by label, choose option by text</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">selectOption</span><span class="token punctuation">(</span><span class="token string">'Role'</span><span class="token punctuation">,</span> <span class="token string">'Admin'</span><span class="token punctuation">)</span>
<span class="token comment">// click 'Save' button, found by text</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">checkOption</span><span class="token punctuation">(</span><span class="token string">'Accept'</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">'Save'</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>ℹ <code>selectOption</code> works only with standard <code><select></code> <select></select> HTML elements. If your selectbox is created by React, Vue, or as a component of any other framework, this method potentially won't work with it. Use <code>click</code> to manipulate it.</p></blockquote> <blockquote><p>ℹ <code>checkOption</code> also works only with standard <code><input type="checkbox"></code> <input type="checkbox"> HTML elements. If your checkbox is created by React, Vue, or as a component of any other framework, this method potentially won't work with it. Use <code>click</code> to manipulate it.</p></blockquote> <p>Alternative scenario:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// we are using CSS</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'#user_name'</span><span class="token punctuation">,</span> <span class="token string">'Miles'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'#user_email'</span><span class="token punctuation">,</span> <span class="token string">'[email protected]'</span><span class="token punctuation">)</span>
<span class="token comment">// select element by label, option by value</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">selectOption</span><span class="token punctuation">(</span><span class="token string">'#user_role'</span><span class="token punctuation">,</span> <span class="token string">'1'</span><span class="token punctuation">)</span>
<span class="token comment">// click 'Update' button, found by name</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">'submitButton'</span><span class="token punctuation">,</span> <span class="token string">'#update_form'</span><span class="token punctuation">)</span>
</code></pre></div><p>To fill in sensitive data use the <code>secret</code> function, it won't expose actual value in logs.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'password'</span><span class="token punctuation">,</span> <span class="token function">secret</span><span class="token punctuation">(</span><span class="token string">'123456'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>ℹ️ Learn more about <a href="/secrets/">masking secret</a> output</p></blockquote> <h3 id="assertions"><a href="#assertions" class="header-anchor">#</a> Assertions</h3> <p>In order to verify the expected behavior of a web application, its content should be checked.
CodeceptJS provides built-in assertions for that. They start with a <code>see</code> (or <code>dontSee</code>) prefix.</p> <p>The most general and common assertion is <code>see</code>, which checks visilibility of a text on a page:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// Just a visible text on a page</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">'Hello'</span><span class="token punctuation">)</span>
<span class="token comment">// text inside .msg element</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">'Hello'</span><span class="token punctuation">,</span> <span class="token string">'.msg'</span><span class="token punctuation">)</span>
<span class="token comment">// opposite</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">dontSee</span><span class="token punctuation">(</span><span class="token string">'Bye'</span><span class="token punctuation">)</span>
</code></pre></div><p>You should provide a text as first argument and, optionally, a locator to search for a text in a context.</p> <p>You can check that specific element exists (or not) on a page, as it was described in <a href="#locating-element">Locating Element</a> section.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeElement</span><span class="token punctuation">(</span><span class="token string">'.notice'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">dontSeeElement</span><span class="token punctuation">(</span><span class="token string">'.error'</span><span class="token punctuation">)</span>
</code></pre></div><p>Additional assertions:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeInCurrentUrl</span><span class="token punctuation">(</span><span class="token string">'/user/miles'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeInField</span><span class="token punctuation">(</span><span class="token string">'user[name]'</span><span class="token punctuation">,</span> <span class="token string">'Miles'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">seeInTitle</span><span class="token punctuation">(</span><span class="token string">'My Website'</span><span class="token punctuation">)</span>
</code></pre></div><p>To see all possible assertions, check the helper's reference.</p> <blockquote><p>ℹ If you need custom assertions, you can install an assertion libarary like <code>chai</code>, use grabbers to obtain information from a browser and perform assertions. However, it is recommended to put custom assertions into a helper for further reuse.</p></blockquote> <h3 id="grabbing"><a href="#grabbing" class="header-anchor">#</a> Grabbing</h3> <p>Sometimes you need to retrieve data from a page to use it in the following steps of a scenario.
Imagine the application generates a password, and you want to ensure that user can login using this password.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'login with generated password'</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">fillField</span><span class="token punctuation">(</span><span class="token string">'email'</span><span class="token punctuation">,</span> <span class="token string">'[email protected]'</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">'Generate Password'</span><span class="token punctuation">)</span>
<span class="token keyword">const</span> password <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">grabTextFrom</span><span class="token punctuation">(</span><span class="token string">'#password'</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">'Login'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'email'</span><span class="token punctuation">,</span> <span class="token string">'[email protected]'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'password'</span><span class="token punctuation">,</span> password<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">'Log in!'</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><span class="token string">'Hello, Miles'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>The <code>grabTextFrom</code> action is used to retrieve the text from an element. All actions starting with the <code>grab</code> prefix are expected to return data. In order to synchronize this step with a scenario you should pause the test execution with the <code>await</code> keyword of ES6. To make it work, your test should be written inside a async function (notice <code>async</code> in its definition).</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'use page title'</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token keyword">const</span> password <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">grabTextFrom</span><span class="token punctuation">(</span><span class="token string">'#password'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'password'</span><span class="token punctuation">,</span> password<span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="waiting"><a href="#waiting" class="header-anchor">#</a> Waiting</h3> <p>In modern web applications, rendering is done on the client-side.
Sometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet.
To handle these cases, the <code>wait*</code> methods has been introduced.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">waitForElement</span><span class="token punctuation">(</span><span class="token string">'#agree_button'</span><span class="token punctuation">,</span> <span class="token number">30</span><span class="token punctuation">)</span> <span class="token comment">// secs</span>
<span class="token comment">// clicks a button only when it is visible</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">'#agree_button'</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="how-it-works"><a href="#how-it-works" class="header-anchor">#</a> How It Works</h2> <p>Tests are written in a synchronous way. This improves the readability and maintainability of tests.
While writing tests you should not think about promises, and instead should focus on the test scenario.</p> <p>However, behind the scenes <strong>all actions are wrapped in promises</strong>, inside of the <code>I</code> object.
<a href="https://github.com/codeceptjs/CodeceptJS/blob/master/lib/recorder.js" target="_blank" rel="noopener noreferrer">Global promise<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> chain is initialized before each test and all <code>I.*</code> calls will be appended to it, as well as setup and teardown.</p> <blockquote><p>📺 <a href="https://www.youtube.com/watch?v=MDLLpHAwy_s" target="_blank" rel="noopener noreferrer">Learn how CodeceptJS<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> works with promises by watching video on YouTube</p></blockquote> <p>If you want to get information from a running test you can use <code>await</code> inside the <strong>async function</strong>, and utilize special methods of helpers started with the <code>grab</code> prefix.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'try grabbers'</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token keyword">let</span> title <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">grabTitle</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>then you can use those variables in assertions:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> title <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">grabTitle</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
<span class="token keyword">var</span> assert <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'assert'</span><span class="token punctuation">)</span>
assert<span class="token punctuation">.</span><span class="token function">equal</span><span class="token punctuation">(</span>title<span class="token punctuation">,</span> <span class="token string">'CodeceptJS'</span><span class="token punctuation">)</span>
</code></pre></div><p>It is important to understand the usage of <strong>async</strong> functions in CodeceptJS. While non-returning actions can be called without await, if an async function uses <code>grab*</code> action it must be called with <code>await</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// a helper function</span>
<span class="token keyword">async</span> <span class="token keyword">function</span> <span class="token function">getAllUsers</span><span class="token punctuation">(</span><span class="token parameter"><span class="token constant">I</span></span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
<span class="token keyword">const</span> users <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">grabTextFrom</span><span class="token punctuation">(</span><span class="token string">'.users'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> users<span class="token punctuation">.</span><span class="token function">filter</span><span class="token punctuation">(</span><span class="token parameter">u</span> <span class="token operator">=></span> u<span class="token punctuation">.</span><span class="token function">includes</span><span class="token punctuation">(</span><span class="token string">'active'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span>
<span class="token comment">// a test</span>
<span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'try helper functions'</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// we call function with await because it includes `grab`</span>
<span class="token keyword">const</span> users <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">getAllUsers</span><span class="token punctuation">(</span><span class="token constant">I</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>If you miss <code>await</code> you get commands unsynchrhonized. And this will result to an error like this:</p> <div class="language- extra-class"><pre class="language-text"><code>(node:446390) UnhandledPromiseRejectionWarning: ...
at processTicksAndRejections (internal/process/task_queues.js:95:5)
(node:446390) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
</code></pre></div><p>If you face that error please make sure that all async functions are called with <code>await</code>.</p> <h2 id="running-tests"><a href="#running-tests" class="header-anchor">#</a> Running Tests</h2> <p>To launch tests use the <code>run</code> command, and to execute tests in <a href="/advanced/parallel">multiple threads</a> using <code>run-workers</code> command.</p> <h3 id="level-of-detail"><a href="#level-of-detail" class="header-anchor">#</a> Level of Detail</h3> <p>To see the step-by-step output of running tests, add the <code>--steps</code> flag:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --steps
</code></pre></div><p>To see a more detailed output add the <code>--debug</code> flag:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --debug
</code></pre></div><p>To see very detailed output informations use the <code>--verbose</code> flag:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --verbose
</code></pre></div><h3 id="filter"><a href="#filter" class="header-anchor">#</a> Filter</h3> <p>A single test file can be executed if you provide a relative path to such a file:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run github_test.js
# or
npx codeceptjs run admin/login_test.js
</code></pre></div><p>To filter a test by name use the <code>--grep</code> parameter, which will execute all tests with names matching the regex pattern.</p> <p>To run all tests with the <code>slow</code> word in it:</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run --grep "slow"
</code></pre></div><p>It is recommended to <a href="/advanced/#tags">filter tests by tags</a>.</p> <blockquote><p>For more options see <a href="/commands/#run">full reference of <code>run</code> command</a>.</p></blockquote> <h3 id="parallel-run"><a href="#parallel-run" class="header-anchor">#</a> Parallel Run</h3> <p>Tests can be executed in parallel mode by using <a href="https://nodejs.org/api/worker_threads.html" target="_blank" rel="noopener noreferrer">NodeJS workers<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>. Use <code>run-workers</code> command with the number of workers (threads) to split tests into different workers.</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run-workers 3
</code></pre></div><p>Tests are split by scenarios, not by files. Results are aggregated and shown up in the main process.</p> <h2 id="configuration"><a href="#configuration" class="header-anchor">#</a> Configuration</h2> <p>Configuration is set in the <code>codecept.conf.js</code> file which was created during the <code>init</code> process.
Inside the config file you can enable and configure helpers and plugins, and set bootstrap and teardown scripts.</p> <div class="language-js extra-class"><pre class="language-js"><code>exports<span class="token punctuation">.</span>config <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token literal-property property">helpers</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token comment">// enabled helpers with their configs</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token literal-property property">plugins</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token comment">// list of used plugins</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token literal-property property">include</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token comment">// current actor and page objects</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>▶ See complete <a href="/configuration">configuration reference</a>.</p></blockquote> <p>You can have multiple configuration files for a the same project, in this case you can specify a config file to be used with <code>-c</code> when running.</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run -c codecept.ci.conf.js
</code></pre></div><p>Tuning configuration for helpers like WebDriver, Puppeteer can be hard, as it requires good understanding of how these technologies work. Use the <a href="https://github.com/codeceptjs/configure" target="_blank" rel="noopener noreferrer"><code>@codeceptjs/configure</code><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> package with common configuration recipes.</p> <p>For instance, you can set the window size or toggle headless mode, no matter of which helpers are actually used.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">const</span> <span class="token punctuation">{</span> setHeadlessWhen<span class="token punctuation">,</span> setWindowSize <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/configure'</span><span class="token punctuation">)</span>
<span class="token comment">// run headless when CI environment variable set</span>
<span class="token function">setHeadlessWhen</span><span class="token punctuation">(</span>process<span class="token punctuation">.</span>env<span class="token punctuation">.</span><span class="token constant">CI</span><span class="token punctuation">)</span>
<span class="token comment">// set window size for any helper: Puppeteer, WebDriver, TestCafe</span>
<span class="token function">setWindowSize</span><span class="token punctuation">(</span><span class="token number">1600</span><span class="token punctuation">,</span> <span class="token number">1200</span><span class="token punctuation">)</span>
exports<span class="token punctuation">.</span>config <span class="token operator">=</span> <span class="token punctuation">{</span>
<span class="token comment">// ...</span>
<span class="token punctuation">}</span>
</code></pre></div><blockquote><p>▶ See more <a href="https://github.com/codeceptjs/configure" target="_blank" rel="noopener noreferrer">configuration recipes<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></blockquote> <h2 id="debug"><a href="#debug" class="header-anchor">#</a> Debug</h2> <p>CodeceptJS allows to write and debug tests on the fly while keeping your browser opened.
By using the interactive shell you can stop execution at any point and type in any CodeceptJS commands.</p> <p>This is especially useful while writing a new scratch. After opening a page call <code>pause()</code> to start interacting with a page:</p> <div class="language-js extra-class"><pre class="language-js"><code><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">'/'</span><span class="token punctuation">)</span>
<span class="token function">pause</span><span class="token punctuation">(</span><span class="token punctuation">)</span>
</code></pre></div><p>Try to perform your scenario step by step. Then copy succesful commands and insert them into a test.</p> <h3 id="pause"><a href="#pause" class="header-anchor">#</a> Pause</h3> <p>Test execution can be paused in any place of a test with <code>pause()</code> call.
Variables can also be passed to <code>pause({data: 'hi', func: () => console.log('hello')})</code> which can be accessed in Interactive shell.</p> <p>This launches the interactive console where you can call any action from the <code>I</code> object.</p> <div class="language- extra-class"><pre class="language-text"><code> Interactive shell started
Press ENTER to resume test
Use JavaScript syntax to try steps in action
- Press ENTER to run the next step
- Press TAB twice to see all available commands
- Type exit + Enter to exit the interactive shell
- Prefix => to run js commands
I.
</code></pre></div><p>Type in different actions to try them, copy and paste successful ones into the test file.</p> <p>Press <code>ENTER</code> to resume test execution.</p> <p>To <strong>debug test step-by-step</strong> press Enter, the next step will be executed and interactive shell will be shown again.</p> <p>To see all available commands, press TAB two times to see list of all actions included in the <code>I</code> object.</p> <blockquote><p>The interactive shell can be started outside of test context by running <code>npx codeceptjs shell</code></p></blockquote> <p>PageObjects and other variables can also be passed to as object:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">pause</span><span class="token punctuation">(</span><span class="token punctuation">{</span> loginPage<span class="token punctuation">,</span> <span class="token literal-property property">data</span><span class="token operator">:</span> <span class="token string">'hi'</span><span class="token punctuation">,</span> <span class="token function-variable function">func</span><span class="token operator">:</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></span> console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'hello'</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Inside a pause mode you can use <code>loginPage</code>, <code>data</code>, <code>func</code> variables.
Arbitrary JavaScript code can be executed when used <code>=></code> prefix:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token operator">=></span> loginPage<span class="token punctuation">.</span><span class="token function">open</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 operator">=></span> <span class="token function">func</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 operator">=></span> <span class="token number">2</span> <span class="token operator">+</span> <span class="token number">5</span>
</code></pre></div><h3 id="pause-on-fail"><a href="#pause-on-fail" class="header-anchor">#</a> Pause on Fail</h3> <p>To start interactive pause automatically for a failing test you can run tests with <a href="/plugins/#pauseonfail">pauseOnFail Plugin</a>.
When a test fails, the pause mode will be activated, so you can inspect current browser session before it is closed.</p> <blockquote><p><strong><a href="/plugins/#pauseOnFail">pauseOnFail plugin</a> can be used</strong> for new setups</p></blockquote> <p>To run tests with pause on fail enabled use <code>-p pauseOnFail</code> option</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run -p pauseOnFail
</code></pre></div><blockquote><p>To enable pause after a test without a plugin you can use <code>After(pause)</code> inside a test file.</p></blockquote> <h3 id="screenshot-on-failure"><a href="#screenshot-on-failure" class="header-anchor">#</a> Screenshot on Failure</h3> <p>By default CodeceptJS saves a screenshot of a failed test.
This can be configured in <a href="/plugins/#screenshotonfail">screenshotOnFail Plugin</a></p> <blockquote><p><strong><a href="/plugins/#screenshotonfail">screenshotOnFail plugin</a> is enabled by default</strong> for new setups</p></blockquote> <h3 id="step-by-step-report"><a href="#step-by-step-report" class="header-anchor">#</a> Step By Step Report</h3> <p>To see how the test was executed, use <a href="/plugins/#stepbystepreport">stepByStepReport Plugin</a>. It saves a screenshot of each passed step and shows them in a nice slideshow.</p> <h2 id="before"><a href="#before" class="header-anchor">#</a> Before</h2> <p>Common preparation steps like opening a web page or logging in a user, can be placed in the <code>Before</code> or <code>Background</code> hooks:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Feature</span><span class="token punctuation">(</span><span class="token string">'CodeceptJS Demonstration'</span><span class="token punctuation">)</span>
<span class="token function">Before</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// or Background</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">'/documentation'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'test some forms'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">'Create User'</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><span class="token string">'User is valid'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">dontSeeInCurrentUrl</span><span class="token punctuation">(</span><span class="token string">'/documentation'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'test title'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">seeInTitle</span><span class="token punctuation">(</span><span class="token string">'Example application'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Same as <code>Before</code> you can use <code>After</code> to run teardown for each scenario.</p> <h2 id="beforesuite"><a href="#beforesuite" class="header-anchor">#</a> BeforeSuite</h2> <p>If you need to run complex a setup before all tests and have to teardown this afterwards, you can use the <code>BeforeSuite</code> and <code>AfterSuite</code> functions.
<code>BeforeSuite</code> and <code>AfterSuite</code> have access to the <code>I</code> object, but <code>BeforeSuite/AfterSuite</code> don't have any access to the browser, because it's not running at this moment.
You can use them to execute handlers that will setup your environment. <code>BeforeSuite/AfterSuite</code> will work only for the file it was declared in (so you can declare different setups for files)</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">BeforeSuite</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">syncDown</span><span class="token punctuation">(</span><span class="token string">'testfolder'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token function">AfterSuite</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">syncUp</span><span class="token punctuation">(</span><span class="token string">'testfolder'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">clearDir</span><span class="token punctuation">(</span><span class="token string">'testfolder'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h2 id="retries"><a href="#retries" class="header-anchor">#</a> Retries</h2> <h3 id="auto-retry"><a href="#auto-retry" class="header-anchor">#</a> Auto Retry</h3> <p>Each failed step is auto-retried by default via <a href="/plugins/#retryfailedstep">retryFailedStep Plugin</a>.
If this is not expected, this plugin can be disabled in a config.</p> <blockquote><p><strong><a href="/plugins/#retryfailedstep">retryFailedStep plugin</a> is enabled by default</strong> incide global configuration</p></blockquote> <h3 id="retry-step"><a href="#retry-step" class="header-anchor">#</a> Retry Step</h3> <p>Unless you use retryFailedStep plugin you can manually control retries in your project.</p> <p>If you have a step which often fails, you can retry execution for this single step.
Use the <code>retry()</code> function before an action to ask CodeceptJS to retry it on failure:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">see</span><span class="token punctuation">(</span><span class="token string">'Welcome'</span><span class="token punctuation">)</span>
</code></pre></div><p>If you'd like to retry a step more than once, pass the amount as a parameter:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">retry</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 function">see</span><span class="token punctuation">(</span><span class="token string">'Welcome'</span><span class="token punctuation">)</span>
</code></pre></div><p>Additional options can be provided to <code>retry</code>, so you can set the additional options (defined in <a href="https://www.npmjs.com/package/promise-retry" target="_blank" rel="noopener noreferrer">promise-retry<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> library).</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// retry action 3 times waiting for 0.1 second before next try</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">retries</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">minTimeout</span><span class="token operator">:</span> <span class="token number">100</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">see</span><span class="token punctuation">(</span><span class="token string">'Hello'</span><span class="token punctuation">)</span>
<span class="token comment">// retry action 3 times waiting no more than 3 seconds for last retry</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">retries</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span> <span class="token literal-property property">maxTimeout</span><span class="token operator">:</span> <span class="token number">3000</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">see</span><span class="token punctuation">(</span><span class="token string">'Hello'</span><span class="token punctuation">)</span>
<span class="token comment">// retry 2 times if error with message 'Node not visible' happens</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
<span class="token literal-property property">retries</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token function-variable function">when</span><span class="token operator">:</span> <span class="token parameter">err</span> <span class="token operator">=></span> err<span class="token punctuation">.</span>message <span class="token operator">===</span> <span class="token string">'Node not visible'</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">seeElement</span><span class="token punctuation">(</span><span class="token string">'#user'</span><span class="token punctuation">)</span>
</code></pre></div><p>Pass a function to the <code>when</code> option to retry only when an error matches the expected one.</p> <h3 id="retry-multiple-steps"><a href="#retry-multiple-steps" class="header-anchor">#</a> Retry Multiple Steps</h3> <p>To retry a group of steps enable <a href="/plugins/#retryto">retryTo plugin</a>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// retry these steps 5 times before failing</span>
<span class="token keyword">await</span> <span class="token function">retryTo</span><span class="token punctuation">(</span><span class="token parameter">tryNum</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">switchTo</span><span class="token punctuation">(</span><span class="token string">'#editor frame'</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">'Open'</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><span class="token string">'Opened'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="retry-scenario"><a href="#retry-scenario" class="header-anchor">#</a> Retry Scenario</h3> <p>When you need to rerun scenarios a few times, add the <code>retries</code> option to the <code>Scenario</code> declaration.</p> <p>CodeceptJS implements retries the same way <a href="https://mochajs.org#retry-tests" target="_blank" rel="noopener noreferrer">Mocha does<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>;
You can set the number of a retries for a feature:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'Really complex'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// test goes here</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span>
<span class="token comment">// alternative</span>
<span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'Really complex'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">retries</span><span class="token operator">:</span> <span class="token number">2</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span><span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>This scenario will be restarted two times on a failure.
Unlike retry step, there is no <code>when</code> condition supported for retries on a scenario level.</p> <h3 id="retry-before"><a href="#retry-before" class="header-anchor">#</a> Retry Before</h3> <p>To retry <code>Before</code>, <code>BeforeSuite</code>, <code>After</code>, <code>AfterSuite</code> hooks, call <code>retry()</code> after declaring the hook.</p> <ul><li><code>Before().retry()</code></li> <li><code>BeforeSuite().retry()</code></li> <li><code>After().retry()</code></li> <li><code>AfterSuite().retry()</code></li></ul> <p>For instance, to retry Before hook 3 times before failing:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Before</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">'/'</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">retry</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span>
</code></pre></div><p>Same applied for <code>BeforeSuite</code>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">BeforeSuite</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 comment">// do some prepreations</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span>
</code></pre></div><p>Alternatively, retry options can be set on Feature level:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Feature</span><span class="token punctuation">(</span><span class="token string">'my tests'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token literal-property property">retryBefore</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
<span class="token literal-property property">retryBeforeSuite</span><span class="token operator">:</span> <span class="token number">2</span><span class="token punctuation">,</span>
<span class="token literal-property property">retryAfter</span><span class="token operator">:</span> <span class="token number">1</span><span class="token punctuation">,</span>
<span class="token literal-property property">retryAfterSuite</span><span class="token operator">:</span> <span class="token number">3</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><h3 id="retry-feature"><a href="#retry-feature" class="header-anchor">#</a> Retry Feature</h3> <p>To set this option for all scenarios in a file, add <code>retry</code> to a feature:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Feature</span><span class="token punctuation">(</span><span class="token string">'Complex JS Stuff'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">retry</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">)</span>
<span class="token comment">// or</span>
<span class="token function">Feature</span><span class="token punctuation">(</span><span class="token string">'Complex JS Stuff'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">retries</span><span class="token operator">:</span> <span class="token number">3</span> <span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Every Scenario inside this feature will be rerun 3 times.
You can make an exception for a specific scenario by passing the <code>retries</code> option to a Scenario.</p> <h3 id="retry-configuration"><a href="#retry-configuration" class="header-anchor">#</a> Retry Configuration <span class="badge warning" style="vertical-align:top;" data-v-76652c5d>Since 3.4</span></h3> <p>It is possible to set retry rules globally via <code>retry</code> config option. The configuration is flexible and allows multiple formats.
The simplest config would be:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// inside codecept.conf.js</span>
<span class="token literal-property property">retry</span><span class="token operator">:</span> <span class="token number">3</span>
</code></pre></div><p>This will enable Feature Retry for all executed feature, retrying failing tests 3 times.</p> <p>An object can be used to tune retries of a Before/After hook, Scenario or Feature</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// inside codecept.conf.js</span>
<span class="token literal-property property">retry</span><span class="token operator">:</span> <span class="token punctuation">{</span>
<span class="token literal-property property">Feature</span><span class="token operator">:</span> <span class="token operator">...</span><span class="token punctuation">,</span>
<span class="token literal-property property">Scenario</span><span class="token operator">:</span> <span class="token operator">...</span><span class="token punctuation">,</span>
<span class="token literal-property property">Before</span><span class="token operator">:</span> <span class="token operator">...</span><span class="token punctuation">,</span>
<span class="token literal-property property">BeforeSuite</span><span class="token operator">:</span> <span class="token operator">...</span><span class="token punctuation">,</span>
<span class="token literal-property property">After</span><span class="token operator">:</span> <span class="token operator">...</span><span class="token punctuation">,</span>
<span class="token literal-property property">AfterSuite</span><span class="token operator">:</span> <span class="token operator">...</span><span class="token punctuation">,</span>
<span class="token punctuation">}</span>
</code></pre></div><p>Multiple retry configs can be added via array. To use different retry configs for different subset of tests use <code>grep</code> option inside a retry config:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// inside codecept.conf.js</span>
<span class="token literal-property property">retry</span><span class="token operator">:</span> <span class="token punctuation">[</span>
<span class="token punctuation">{</span>
<span class="token comment">// enable this config only for flaky tests</span>
<span class="token literal-property property">grep</span><span class="token operator">:</span> <span class="token string">'@flaky'</span><span class="token punctuation">,</span>
<span class="token literal-property property">Before</span><span class="token operator">:</span> <span class="token number">3</span>
<span class="token literal-property property">Scenario</span><span class="token operator">:</span> <span class="token number">3</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span>
<span class="token punctuation">{</span>
<span class="token comment">// retry less when running slow tests</span>
<span class="token literal-property property">grep</span><span class="token operator">:</span> <span class="token string">'@slow'</span>
<span class="token literal-property property">Scenario</span><span class="token operator">:</span> <span class="token number">1</span>
<span class="token literal-property property">Before</span><span class="token operator">:</span> <span class="token number">1</span>
<span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token punctuation">{</span>
<span class="token comment">// retry all BeforeSuite</span>
<span class="token literal-property property">BeforeSuite</span><span class="token operator">:</span> <span class="token number">3</span>
<span class="token punctuation">}</span>
<span class="token punctuation">]</span>
</code></pre></div><p>When using <code>grep</code> with <code>Before</code>, <code>After</code>, <code>BeforeSuite</code>, <code>AfterSuite</code>, a suite title will be checked for included value.</p> <blockquote><p>ℹ️ <code>grep</code> value can be string or regexp</p></blockquote> <p>Rules are applied in the order of array element, so the last option will override a previous one. Global retries config can be overridden in a file as described previously.</p> <h3 id="retry-run"><a href="#retry-run" class="header-anchor">#</a> Retry Run</h3> <p>On the highest level of the "retry pyramid" there is an option to retry a complete run multiple times.
Even this is the slowest option of all, it can be helpful to detect flaky tests.</p> <p><a href="https://codecept.io/commands/#run-rerun" target="_blank" rel="noopener noreferrer"><code>run-rerun</code><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> command will restart the run multiple times to values you provide. You can set minimal and maximal number of restarts in configuration file.</p> <div class="language- extra-class"><pre class="language-text"><code>npx codeceptjs run-rerun
</code></pre></div><p><a href="https://github.com/codeceptjs/CodeceptJS/pull/231#issuecomment-249554933" target="_blank" rel="noopener noreferrer">Here are some ideas<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> on where to use BeforeSuite hooks.</p> <h2 id="within"><a href="#within" class="header-anchor">#</a> Within</h2> <p>To specify the exact area on a page where actions can be performed you can use the <code>within</code> function.
Everything executed in its context will be narrowed to context specified by locator:</p> <p>Usage: <code>within('section', ()=>{})</code></p> <div class="language-js extra-class"><pre class="language-js"><code><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">'https://github.com'</span><span class="token punctuation">)</span>
<span class="token function">within</span><span class="token punctuation">(</span><span class="token string">'.js-signup-form'</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">fillField</span><span class="token punctuation">(</span><span class="token string">'user[login]'</span><span class="token punctuation">,</span> <span class="token string">'User'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'user[email]'</span><span class="token punctuation">,</span> <span class="token string">'[email protected]'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'user[password]'</span><span class="token punctuation">,</span> <span class="token string">'[email protected]'</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">'button'</span><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">see</span><span class="token punctuation">(</span><span class="token string">'There were problems creating your account.'</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>⚠ <code>within</code> can cause problems when used incorrectly. If you see a weird behavior of a test try to refactor it to not use <code>within</code>. It is recommended to keep within for simplest cases when possible.
Since <code>within</code> returns a Promise, it may be necessary to <code>await</code> the result even when you're not intending to use the return value.</p></blockquote> <p><code>within</code> can also work with IFrames. A special <code>frame</code> locator is required to locate the iframe and get into its context.</p> <p>See example:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">within</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">frame</span><span class="token operator">:</span> <span class="token string">'#editor'</span> <span class="token punctuation">}</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">see</span><span class="token punctuation">(</span><span class="token string">'Page'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><blockquote><p>ℹ IFrames can also be accessed via <code>I.switchTo</code> command of a corresponding helper.</p></blockquote> <p>Nested IFrames can be set by passing an array <em>(WebDriver & Puppeteer only)</em>:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">within</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">frame</span><span class="token operator">:</span> <span class="token punctuation">[</span><span class="token string">'.content'</span><span class="token punctuation">,</span> <span class="token string">'#editor'</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 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><span class="token string">'Page'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>When running steps inside, a within block will be shown with a shift:</p> <p><img src="/img/within.png" alt="within"></p> <p>Within can return a value, which can be used in a scenario:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// inside async function</span>
<span class="token keyword">const</span> val <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">within</span><span class="token punctuation">(</span><span class="token string">'#sidebar'</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 keyword">return</span> <span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">grabTextFrom</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">css</span><span class="token operator">:</span> <span class="token string">'h1'</span> <span class="token punctuation">}</span><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">fillField</span><span class="token punctuation">(</span><span class="token string">'Description'</span><span class="token punctuation">,</span> val<span class="token punctuation">)</span>
</code></pre></div><h2 id="conditional-actions"><a href="#conditional-actions" class="header-anchor">#</a> Conditional Actions</h2> <p>There is a way to execute unsuccessful actions to without failing a test.
This might be useful when you might need to click "Accept cookie" button but probably cookies were already accepted.
To handle these cases <code>tryTo</code> function was introduced:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">tryTo</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=></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">'Accept'</span><span class="token punctuation">,</span> <span class="token string">'.cookies'</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
</code></pre></div><p>You may also use <code>tryTo</code> for cases when you deal with uncertainty on page:</p> <ul><li>A/B testing</li> <li>soft assertions</li> <li>cookies & gdpr</li></ul> <p><code>tryTo</code> function is enabled by default via <a href="/plugins/#tryto">tryTo plugin</a></p> <h2 id="comments"><a href="#comments" class="header-anchor">#</a> Comments</h2> <p>There is a simple way to add additional comments to your test scenario:
Use the <code>say</code> command to print information to screen:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">'I am going to publish post'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">'I enter title and body'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">'I expect post is visible on site'</span><span class="token punctuation">)</span>
</code></pre></div><p>Use the second parameter to pass in a color value (ASCII).</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">'This is red'</span><span class="token punctuation">,</span> <span class="token string">'red'</span><span class="token punctuation">)</span> <span class="token comment">//red is used</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">'This is blue'</span><span class="token punctuation">,</span> <span class="token string">'blue'</span><span class="token punctuation">)</span> <span class="token comment">//blue is used</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">say</span><span class="token punctuation">(</span><span class="token string">'This is by default'</span><span class="token punctuation">)</span> <span class="token comment">//cyan is used</span>
</code></pre></div><h2 id="intellisense"><a href="#intellisense" class="header-anchor">#</a> IntelliSense</h2> <p><img src="/img/edit.gif" alt="Edit"></p> <p>To get autocompletion when working with CodeceptJS, use Visual Studio Code or another IDE that supports TypeScript Definitions.</p> <p>Generate step definitions with:</p> <div class="language-sh extra-class"><pre class="language-sh"><code>npx codeceptjs def
</code></pre></div><p>Create a file called <code>jsconfig.json</code> in your project root directory, unless you already have one.</p> <div class="language-jsconfig.json extra-class"><pre class="language-text"><code>{
"compilerOptions": {
"allowJs": true,
}
}
</code></pre></div><p>Alternatively, you can include <code>/// <reference path="./steps.d.ts" /></code> into your test files
to get method autocompletion while writing tests.</p> <h2 id="multiple-sessions"><a href="#multiple-sessions" class="header-anchor">#</a> Multiple Sessions</h2> <p>CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a chat or other systems. To open another browser use the <code>session()</code> function as shown in the example:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'test app'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></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">'/chat'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">,</span> <span class="token string">'davert'</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">'Sign In'</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><span class="token string">'Hello, davert'</span><span class="token punctuation">)</span>
<span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'john'</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 comment">// another session started</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">'/chat'</span><span class="token punctuation">)</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">,</span> <span class="token string">'john'</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">'Sign In'</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><span class="token string">'Hello, john'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token comment">// switching back to default session</span>
<span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">fillField</span><span class="token punctuation">(</span><span class="token string">'message'</span><span class="token punctuation">,</span> <span class="token string">'Hi, john'</span><span class="token punctuation">)</span>
<span class="token comment">// there is a message from current user</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">'me: Hi, john'</span><span class="token punctuation">,</span> <span class="token string">'.messages'</span><span class="token punctuation">)</span>
<span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'john'</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 comment">// let's check if john received it</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">'davert: Hi, john'</span><span class="token punctuation">,</span> <span class="token string">'.messages'</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><p>The <code>session</code> function expects the first parameter to be the name of the session. You can switch back to this session by using the same name.</p> <p>You can override the configuration for the session by passing a second parameter:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'john'</span><span class="token punctuation">,</span> <span class="token punctuation">{</span> <span class="token literal-property property">browser</span><span class="token operator">:</span> <span class="token string">'firefox'</span> <span class="token punctuation">}</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 comment">// run this steps in firefox</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">'/'</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>or just start the session without switching to it. Call <code>session</code> passing only its name:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token function">Scenario</span><span class="token punctuation">(</span><span class="token string">'test'</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token parameter"><span class="token punctuation">{</span> <span class="token constant">I</span> <span class="token punctuation">}</span></span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">// opens 3 additional browsers</span>
<span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'john'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'mary'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'jane'</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">amOnPage</span><span class="token punctuation">(</span><span class="token string">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token comment">// switch to session by its name</span>
<span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'mary'</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 string">'/login'</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><p><code>session</code> can return a value which can be used in a scenario:</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token comment">// inside async function</span>
<span class="token keyword">const</span> val <span class="token operator">=</span> <span class="token keyword">await</span> <span class="token function">session</span><span class="token punctuation">(</span><span class="token string">'john'</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 string">'/info'</span><span class="token punctuation">)</span>
<span class="token keyword">return</span> <span class="token constant">I</span><span class="token punctuation">.</span><span class="token function">grabTextFrom</span><span class="token punctuation">(</span><span class="token punctuation">{</span> <span class="token literal-property property">css</span><span class="token operator">:</span> <span class="token string">'h1'</span> <span class="token punctuation">}</span><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">fillField</span><span class="token punctuation">(</span><span class="token string">'Description'</span><span class="token punctuation">,</span> val<span class="token punctuation">)</span>
</code></pre></div><p>Functions passed into a session can use the <code>I</code> object, page objects, and any other objects declared for the scenario.
This function can also be declared as async (but doesn't work as generator).</p> <p>Also, you can use <code>within</code> inside a session, but you can't call session from inside <code>within</code>.</p> <h2 id="skipping"><a href="#skipping" class="header-anchor">#</a> Skipping</h2> <p>Like in Mocha you can use <code>x</code> and <code>only</code> to skip tests or to run a single test.</p> <ul><li><code>xScenario</code> - skips current test</li> <li><code>Scenario.skip</code> - skips current test</li> <li><code>Scenario.only</code> - executes only the current test</li> <li><code>xFeature</code> - skips current suite <span class="badge warning" style="vertical-align:top;" data-v-76652c5d>Since 2.6.6</span></li> <li><code>Feature.skip</code> - skips the current suite <span class="badge warning" style="vertical-align:top;" data-v-76652c5d>Since 2.6.6</span></li></ul> <h2 id="todo-test"><a href="#todo-test" class="header-anchor">#</a> Todo Test</h2> <p>You can use <code>Scenario.todo</code> when you are planning on writing tests.</p> <p>This test will be skipped like with regular <code>Scenario.skip</code> but with additional message "Test not implemented!":</p> <p>Use it with a test body as a test plan:</p> <div class="language-js extra-class"><pre class="language-js"><code>Scenario<span class="token punctuation">.</span><span class="token function">todo</span><span class="token punctuation">(</span><span class="token string">'Test'</span><span class="token punctuation">,</span> <span class="token parameter"><span class="token constant">I</span></span> <span class="token operator">=></span> <span class="token punctuation">{</span>
<span class="token comment">/**
* 1. Click to field
* 2. Fill field
*
* Result:
* 3. Field contains text
*/</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Or even without a test body:</p> <div class="language-js extra-class"><pre class="language-js"><code>Scenario<span class="token punctuation">.</span><span class="token function">todo</span><span class="token punctuation">(</span><span class="token string">'Test'</span><span class="token punctuation">)</span>
</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/basics.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">2/10/2025, 4:33:39 AM</span></div></div> <div class="page-nav"><p class="inner"><!----> <span class="next"><a href="/ui/">CodeceptUI</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" aria-current="page" class="router-link-exact-active router-link-active" 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/35.db84cbc0.js" defer></script><script src="/assets/js/7.f6967540.js" defer></script>
</body>
</html>