codeceptjs 4.0.0-beta.4 → 4.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/README.md +134 -119
  2. package/bin/codecept.js +12 -2
  3. package/bin/test-server.js +53 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/lib/actor.js +66 -102
  6. package/lib/ai.js +130 -121
  7. package/lib/assert/empty.js +3 -5
  8. package/lib/assert/equal.js +4 -7
  9. package/lib/assert/include.js +4 -6
  10. package/lib/assert/throws.js +2 -4
  11. package/lib/assert/truth.js +2 -2
  12. package/lib/codecept.js +139 -87
  13. package/lib/command/check.js +201 -0
  14. package/lib/command/configMigrate.js +2 -4
  15. package/lib/command/definitions.js +8 -26
  16. package/lib/command/generate.js +10 -14
  17. package/lib/command/gherkin/snippets.js +75 -73
  18. package/lib/command/gherkin/steps.js +1 -1
  19. package/lib/command/info.js +42 -8
  20. package/lib/command/init.js +13 -12
  21. package/lib/command/interactive.js +10 -2
  22. package/lib/command/list.js +1 -1
  23. package/lib/command/run-multiple/chunk.js +48 -45
  24. package/lib/command/run-multiple.js +12 -35
  25. package/lib/command/run-workers.js +21 -58
  26. package/lib/command/utils.js +5 -6
  27. package/lib/command/workers/runTests.js +262 -220
  28. package/lib/container.js +386 -238
  29. package/lib/data/context.js +10 -13
  30. package/lib/data/dataScenarioConfig.js +8 -8
  31. package/lib/data/dataTableArgument.js +6 -6
  32. package/lib/data/table.js +5 -11
  33. package/lib/effects.js +223 -0
  34. package/lib/element/WebElement.js +327 -0
  35. package/lib/els.js +158 -0
  36. package/lib/event.js +21 -17
  37. package/lib/heal.js +88 -80
  38. package/lib/helper/AI.js +2 -1
  39. package/lib/helper/ApiDataFactory.js +3 -6
  40. package/lib/helper/Appium.js +47 -51
  41. package/lib/helper/FileSystem.js +3 -3
  42. package/lib/helper/GraphQLDataFactory.js +3 -3
  43. package/lib/helper/JSONResponse.js +75 -37
  44. package/lib/helper/Mochawesome.js +31 -9
  45. package/lib/helper/Nightmare.js +35 -53
  46. package/lib/helper/Playwright.js +262 -267
  47. package/lib/helper/Protractor.js +54 -77
  48. package/lib/helper/Puppeteer.js +246 -260
  49. package/lib/helper/REST.js +5 -17
  50. package/lib/helper/TestCafe.js +21 -44
  51. package/lib/helper/WebDriver.js +151 -170
  52. package/lib/helper/extras/Popup.js +22 -22
  53. package/lib/helper/testcafe/testcafe-utils.js +26 -27
  54. package/lib/listener/emptyRun.js +55 -0
  55. package/lib/listener/exit.js +7 -10
  56. package/lib/listener/{retry.js → globalRetry.js} +5 -5
  57. package/lib/listener/globalTimeout.js +165 -0
  58. package/lib/listener/helpers.js +15 -15
  59. package/lib/listener/mocha.js +1 -1
  60. package/lib/listener/result.js +12 -0
  61. package/lib/listener/retryEnhancer.js +85 -0
  62. package/lib/listener/steps.js +32 -18
  63. package/lib/listener/store.js +20 -0
  64. package/lib/mocha/asyncWrapper.js +231 -0
  65. package/lib/{interfaces → mocha}/bdd.js +3 -3
  66. package/lib/mocha/cli.js +308 -0
  67. package/lib/mocha/factory.js +104 -0
  68. package/lib/{interfaces → mocha}/featureConfig.js +32 -12
  69. package/lib/{interfaces → mocha}/gherkin.js +26 -28
  70. package/lib/mocha/hooks.js +112 -0
  71. package/lib/mocha/index.js +12 -0
  72. package/lib/mocha/inject.js +29 -0
  73. package/lib/{interfaces → mocha}/scenarioConfig.js +31 -7
  74. package/lib/mocha/suite.js +82 -0
  75. package/lib/mocha/test.js +181 -0
  76. package/lib/mocha/types.d.ts +42 -0
  77. package/lib/mocha/ui.js +232 -0
  78. package/lib/output.js +82 -62
  79. package/lib/pause.js +160 -138
  80. package/lib/plugin/analyze.js +396 -0
  81. package/lib/plugin/auth.js +435 -0
  82. package/lib/plugin/autoDelay.js +8 -8
  83. package/lib/plugin/autoLogin.js +3 -338
  84. package/lib/plugin/commentStep.js +6 -1
  85. package/lib/plugin/coverage.js +10 -19
  86. package/lib/plugin/customLocator.js +3 -3
  87. package/lib/plugin/customReporter.js +52 -0
  88. package/lib/plugin/eachElement.js +1 -1
  89. package/lib/plugin/fakerTransform.js +1 -1
  90. package/lib/plugin/heal.js +36 -9
  91. package/lib/plugin/htmlReporter.js +1947 -0
  92. package/lib/plugin/pageInfo.js +140 -0
  93. package/lib/plugin/retryFailedStep.js +17 -18
  94. package/lib/plugin/retryTo.js +2 -113
  95. package/lib/plugin/screenshotOnFail.js +17 -58
  96. package/lib/plugin/selenoid.js +15 -35
  97. package/lib/plugin/standardActingHelpers.js +4 -1
  98. package/lib/plugin/stepByStepReport.js +56 -17
  99. package/lib/plugin/stepTimeout.js +5 -12
  100. package/lib/plugin/subtitles.js +4 -4
  101. package/lib/plugin/tryTo.js +3 -102
  102. package/lib/plugin/wdio.js +8 -10
  103. package/lib/recorder.js +155 -124
  104. package/lib/rerun.js +43 -42
  105. package/lib/result.js +161 -0
  106. package/lib/secret.js +1 -1
  107. package/lib/step/base.js +239 -0
  108. package/lib/step/comment.js +10 -0
  109. package/lib/step/config.js +50 -0
  110. package/lib/step/func.js +46 -0
  111. package/lib/step/helper.js +50 -0
  112. package/lib/step/meta.js +99 -0
  113. package/lib/step/record.js +74 -0
  114. package/lib/step/retry.js +11 -0
  115. package/lib/step/section.js +55 -0
  116. package/lib/step.js +21 -332
  117. package/lib/steps.js +50 -0
  118. package/lib/store.js +37 -5
  119. package/lib/template/heal.js +2 -11
  120. package/lib/test-server.js +323 -0
  121. package/lib/timeout.js +66 -0
  122. package/lib/utils.js +351 -218
  123. package/lib/within.js +75 -55
  124. package/lib/workerStorage.js +2 -1
  125. package/lib/workers.js +386 -276
  126. package/package.json +76 -70
  127. package/translations/de-DE.js +4 -3
  128. package/translations/fr-FR.js +4 -3
  129. package/translations/index.js +1 -0
  130. package/translations/it-IT.js +4 -3
  131. package/translations/ja-JP.js +4 -3
  132. package/translations/nl-NL.js +76 -0
  133. package/translations/pl-PL.js +4 -3
  134. package/translations/pt-BR.js +4 -3
  135. package/translations/ru-RU.js +4 -3
  136. package/translations/utils.js +9 -0
  137. package/translations/zh-CN.js +4 -3
  138. package/translations/zh-TW.js +4 -3
  139. package/typings/index.d.ts +188 -186
  140. package/typings/promiseBasedTypes.d.ts +18 -705
  141. package/typings/types.d.ts +301 -804
  142. package/lib/cli.js +0 -256
  143. package/lib/helper/ExpectHelper.js +0 -391
  144. package/lib/helper/SoftExpectHelper.js +0 -381
  145. package/lib/listener/artifacts.js +0 -19
  146. package/lib/listener/timeout.js +0 -109
  147. package/lib/mochaFactory.js +0 -113
  148. package/lib/plugin/debugErrors.js +0 -67
  149. package/lib/scenario.js +0 -224
  150. package/lib/ui.js +0 -236
package/README.md CHANGED
@@ -1,20 +1,17 @@
1
1
  [![Stand With Ukraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/banner-direct-single.svg)](https://stand-with-ukraine.pp.ua)
2
2
 
3
-
4
-
5
3
  [<img src="https://img.shields.io/badge/slack-@codeceptjs-purple.svg?logo=slack">](https://join.slack.com/t/codeceptjs/shared_invite/enQtMzA5OTM4NDM2MzA4LWE4MThhN2NmYTgxNTU5MTc4YzAyYWMwY2JkMmZlYWI5MWQ2MDM5MmRmYzZmYmNiNmY5NTAzM2EwMGIwOTNhOGQ) [<img src="https://img.shields.io/badge/discourse-codeceptjs-purple">](https://codecept.discourse.group) [![NPM version][npm-image]][npm-url] [<img src="https://img.shields.io/badge/dockerhub-images-blue.svg?logo=codeceptjs">](https://hub.docker.com/r/codeceptjs/codeceptjs)
6
- [![AI features](https://img.shields.io/badge/AI-features?logo=openai&logoColor=white)](https://github.com/codeceptjs/CodeceptJS/edit/3.x/docs/ai.md) [![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)
4
+ [![AI features](https://img.shields.io/badge/AI-features?logo=openai&logoColor=white)](https://github.com/codeceptjs/CodeceptJS/edit/3.x/docs/ai.md) [![StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://github.com/vshymanskyy/StandWithUkraine/blob/main/docs/README.md)
7
5
 
8
- Build Status:
6
+ ## Build Status
9
7
 
10
- Appium Helper:
11
- [![Appium V2 Tests - Android](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appiumV2_Android.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appiumV2_Android.yml)
12
-
13
- Web Helper:
14
- [![Playwright Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/playwright.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/playwright.yml)
15
- [![Puppeteer Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/puppeteer.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/puppeteer.yml)
16
- [![WebDriver Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/webdriver.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/webdriver.yml)
17
- [![TestCafe Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/testcafe.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/testcafe.yml)
8
+ | Type | Engine | Status |
9
+ | --------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
10
+ | 🌐 Web | Playwright | [![Playwright Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/playwright.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/playwright.yml) |
11
+ | 🌐 Web | Puppeteer | [![Puppeteer Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/puppeteer.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/puppeteer.yml) |
12
+ | 🌐 Web | WebDriver | [![WebDriver Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/webdriver.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/webdriver.yml) |
13
+ | 🌐 Web | TestCafe | [![TestCafe Tests](https://github.com/codeceptjs/CodeceptJS/actions/workflows/testcafe.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/testcafe.yml) |
14
+ | 📱 Mobile | Appium | [![Appium Tests - Android](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appium_Android.yml/badge.svg)](https://github.com/codeceptjs/CodeceptJS/actions/workflows/appium_Android.yml) |
18
15
 
19
16
  # CodeceptJS [![Made in Ukraine](https://img.shields.io/badge/made_in-ukraine-ffd700.svg?labelColor=0057b7)](https://stand-with-ukraine.pp.ua)
20
17
 
@@ -27,28 +24,28 @@ It abstracts browser interaction to simple steps that are written from a user's
27
24
  A simple test that verifies the "Welcome" text is present on a main page of a site will look like:
28
25
 
29
26
  ```js
30
- Feature('CodeceptJS demo');
27
+ Feature('CodeceptJS demo')
31
28
 
32
29
  Scenario('check Welcome page on site', ({ I }) => {
33
- I.amOnPage('/');
34
- I.see('Welcome');
35
- });
30
+ I.amOnPage('/')
31
+ I.see('Welcome')
32
+ })
36
33
  ```
37
34
 
38
35
  CodeceptJS tests are:
39
36
 
40
- * **Synchronous**. You don't need to care about callbacks or promises or test scenarios which are linear. But, your tests should be linear.
41
- * Written from **user's perspective**. Every action is a method of `I`. That makes test easy to read, write and maintain even for non-tech persons.
42
- * Backend **API agnostic**. We don't know which WebDriver implementation is running this test.
37
+ - **Synchronous**. You don't need to care about callbacks or promises or test scenarios which are linear. But, your tests should be linear.
38
+ - Written from **user's perspective**. Every action is a method of `I`. That makes test easy to read, write and maintain even for non-tech persons.
39
+ - Backend **API agnostic**. We don't know which WebDriver implementation is running this test.
43
40
 
44
41
  CodeceptJS uses **Helper** modules to provide actions to `I` object. Currently, CodeceptJS has these helpers:
45
42
 
46
- * [**Playwright**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Playwright.md) - is a Node library to automate the Chromium, WebKit and Firefox browsers with a single API.
47
- * [**Puppeteer**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Puppeteer.md) - uses Google Chrome's Puppeteer for fast headless testing.
48
- * [**WebDriver**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) - uses [webdriverio](http://webdriver.io/) to run tests via WebDriver or Devtools protocol.
49
- * [**TestCafe**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/TestCafe.md) - cheap and fast cross-browser test automation.
50
- * [**Appium**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Appium.md) - for **mobile testing** with Appium
51
- * [**Detox**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Detox.md) - This is a wrapper on top of Detox library, aimed to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially well for React Native apps.
43
+ - [**Playwright**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Playwright.md) - is a Node library to automate the Chromium, WebKit and Firefox browsers with a single API.
44
+ - [**Puppeteer**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Puppeteer.md) - uses Google Chrome's Puppeteer for fast headless testing.
45
+ - [**WebDriver**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/WebDriver.md) - uses [webdriverio](http://webdriver.io/) to run tests via WebDriver or Devtools protocol.
46
+ - [**TestCafe**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/TestCafe.md) - cheap and fast cross-browser test automation.
47
+ - [**Appium**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Appium.md) - for **mobile testing** with Appium
48
+ - [**Detox**](https://github.com/codeceptjs/CodeceptJS/blob/master/docs/helpers/Detox.md) - This is a wrapper on top of Detox library, aimed to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially well for React Native apps.
52
49
 
53
50
  And more to come...
54
51
 
@@ -58,17 +55,18 @@ CodeceptJS is a successor of [Codeception](http://codeception.com), a popular fu
58
55
  With CodeceptJS your scenario-driven functional and acceptance tests will be as simple and clean as they can be.
59
56
  You don't need to worry about asynchronous nature of NodeJS or about various APIs of Playwright, Selenium, Puppeteer, TestCafe, etc. as CodeceptJS unifies them and makes them work as they are synchronous.
60
57
 
61
-
62
58
  ## Features
63
-
64
- * 🪄 **AI-powered** with GPT features to assist and heal failing tests.
65
- * ☕ Based on [Mocha](https://mochajs.org/) testing framework.
66
- * 💼 Designed for scenario driven acceptance testing in BDD-style.
67
- * 💻 Uses ES6 natively without transpiler.
68
- * Also plays nice with TypeScript.
69
- * </> Smart locators: use names, labels, matching text, CSS or XPath to locate elements.
70
- * 🌐 Interactive debugging shell: pause test at any point and try different commands in a browser.
71
- * Easily create tests, pageobjects, stepobjects with CLI generators.
59
+
60
+ - 🪄 **AI-powered** with GPT features to assist and heal failing tests.
61
+ - ☕ Based on [Mocha](https://mochajs.org/) testing framework.
62
+ - 💼 Designed for scenario driven acceptance testing in BDD-style.
63
+ - 💻 Uses ES6 natively without transpiler.
64
+ - Also plays nice with TypeScript.
65
+ - </> Smart locators: use names, labels, matching text, CSS or XPath to locate elements.
66
+ - 🌐 Interactive debugging shell: pause test at any point and try different commands in a browser.
67
+ - **Parallel testing** with dynamic test pooling for optimal load balancing and performance.
68
+ - 📊 **Built-in HTML Reporter** with interactive dashboard, step-by-step execution details, and comprehensive test analytics.
69
+ - Easily create tests, pageobjects, stepobjects with CLI generators.
72
70
 
73
71
  ## Installation
74
72
 
@@ -105,7 +103,8 @@ npx codeceptjs def .
105
103
  Later you can even automagically update Type Definitions to include your own custom [helpers methods](docs/helpers.md).
106
104
 
107
105
  Note:
108
- - CodeceptJS requires Node.js version `12+` or later.
106
+
107
+ - CodeceptJS requires Node.js version `12+` or later.
109
108
 
110
109
  ## Usage
111
110
 
@@ -116,18 +115,18 @@ Learn CodeceptJS by examples. Let's assume we have CodeceptJS installed and WebD
116
115
  Let's see how we can handle basic form testing:
117
116
 
118
117
  ```js
119
- Feature('CodeceptJS Demonstration');
118
+ Feature('CodeceptJS Demonstration')
120
119
 
121
120
  Scenario('test some forms', ({ I }) => {
122
- I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation');
123
- I.fillField('Email', 'hello@world.com');
124
- I.fillField('Password', secret('123456'));
125
- I.checkOption('Active');
126
- I.checkOption('Male');
127
- I.click('Create User');
128
- I.see('User is valid');
129
- I.dontSeeInCurrentUrl('/documentation');
130
- });
121
+ I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
122
+ I.fillField('Email', 'hello@world.com')
123
+ I.fillField('Password', secret('123456'))
124
+ I.checkOption('Active')
125
+ I.checkOption('Male')
126
+ I.click('Create User')
127
+ I.see('User is valid')
128
+ I.dontSeeInCurrentUrl('/documentation')
129
+ })
131
130
  ```
132
131
 
133
132
  All actions are performed by `I` object; assertions functions start with `see` function.
@@ -172,11 +171,11 @@ The same way you can locate element by name, `CSS` or `XPath` locators in tests:
172
171
 
173
172
  ```js
174
173
  // by name
175
- I.fillField('user_basic[email]', 'hello@world.com');
174
+ I.fillField('user_basic[email]', 'hello@world.com')
176
175
  // by CSS
177
- I.fillField('#user_basic_email', 'hello@world.com');
176
+ I.fillField('#user_basic_email', 'hello@world.com')
178
177
  // don't make us guess locator type, specify it
179
- I.fillField({css: '#user_basic_email'}, 'hello@world.com');
178
+ I.fillField({ css: '#user_basic_email' }, 'hello@world.com')
180
179
  ```
181
180
 
182
181
  Other methods like `checkOption`, and `click` work in a similar manner. They can take labels or CSS or XPath locators to find elements to interact.
@@ -187,9 +186,9 @@ Assertions start with `see` or `dontSee` prefix. In our case we are asserting th
187
186
  However, we can narrow the search to particular element by providing a second parameter:
188
187
 
189
188
  ```js
190
- I.see('User is valid');
189
+ I.see('User is valid')
191
190
  // better to specify context:
192
- I.see('User is valid', '.alert-success');
191
+ I.see('User is valid', '.alert-success')
193
192
  ```
194
193
 
195
194
  In this case 'User is valid' string will be searched only inside elements located by CSS `.alert-success`.
@@ -200,13 +199,13 @@ In case you need to return a value from a webpage and use it directly in test, y
200
199
  They are expected to be used inside `async/await` functions, and their results will be available in test:
201
200
 
202
201
  ```js
203
- Feature('CodeceptJS Demonstration');
202
+ Feature('CodeceptJS Demonstration')
204
203
 
205
204
  Scenario('test page title', async ({ I }) => {
206
- I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation');
207
- const title = await I.grabTitle();
208
- I.expectEqual(title, 'Example application with SimpleForm and Twitter Bootstrap'); // Avaiable with Expect helper. -> https://codecept.io/helpers/Expect/
209
- });
205
+ I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
206
+ const title = await I.grabTitle()
207
+ I.expectEqual(title, 'Example application with SimpleForm and Twitter Bootstrap') // Avaiable with Expect helper. -> https://codecept.io/helpers/Expect/
208
+ })
210
209
  ```
211
210
 
212
211
  The same way you can grab text, attributes, or form values and use them in next test steps.
@@ -216,25 +215,69 @@ The same way you can grab text, attributes, or form values and use them in next
216
215
  Common preparation steps like opening a web page, logging in a user, can be placed in `Before` or `Background`:
217
216
 
218
217
  ```js
219
- const { I } = inject();
218
+ const { I } = inject()
220
219
 
221
- Feature('CodeceptJS Demonstration');
220
+ Feature('CodeceptJS Demonstration')
222
221
 
223
- Before(() => { // or Background
224
- I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation');
225
- });
222
+ Before(() => {
223
+ // or Background
224
+ I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
225
+ })
226
226
 
227
227
  Scenario('test some forms', () => {
228
- I.click('Create User');
229
- I.see('User is valid');
230
- I.dontSeeInCurrentUrl('/documentation');
231
- });
228
+ I.click('Create User')
229
+ I.see('User is valid')
230
+ I.dontSeeInCurrentUrl('/documentation')
231
+ })
232
232
 
233
233
  Scenario('test title', () => {
234
- I.seeInTitle('Example application');
235
- });
234
+ I.seeInTitle('Example application')
235
+ })
236
236
  ```
237
237
 
238
+ ## HTML Reporter
239
+
240
+ CodeceptJS includes a powerful built-in HTML Reporter that generates comprehensive, interactive test reports with detailed information about your test runs. The HTML reporter is **enabled by default** for all new projects and provides:
241
+
242
+ ### Features
243
+
244
+ - **Interactive Dashboard**: Visual statistics, pie charts, and expandable test details
245
+ - **Step-by-Step Execution**: Shows individual test steps with timing and status indicators
246
+ - **BDD/Gherkin Support**: Full support for feature files with proper scenario formatting
247
+ - **System Information**: Comprehensive environment details including browser versions
248
+ - **Advanced Filtering**: Real-time filtering by status, tags, features, and test types
249
+ - **History Tracking**: Multi-run history with trend visualization
250
+ - **Error Details**: Clean formatting of error messages and stack traces
251
+ - **Artifacts Support**: Display screenshots and other test artifacts
252
+
253
+ ### Visual Examples
254
+
255
+ #### Interactive Test Dashboard
256
+
257
+ The main dashboard provides a complete overview with interactive statistics and pie charts:
258
+
259
+ ![HTML Reporter Dashboard](docs/shared/html-reporter-main-dashboard.png)
260
+
261
+ #### Detailed Test Results
262
+
263
+ Each test shows comprehensive execution details with expandable step information:
264
+
265
+ ![HTML Reporter Test Details](docs/shared/html-reporter-test-details.png)
266
+
267
+ #### Advanced Filtering Capabilities
268
+
269
+ Real-time filtering allows quick navigation through test results:
270
+
271
+ ![HTML Reporter Filtering](docs/shared/html-reporter-filtering.png)
272
+
273
+ #### BDD/Gherkin Support
274
+
275
+ Full support for Gherkin scenarios with proper feature formatting:
276
+
277
+ ![HTML Reporter BDD Details](docs/shared/html-reporter-bdd-details.png)
278
+
279
+ The HTML reporter generates self-contained reports that can be easily shared with your team. Learn more about configuration and features in the [HTML Reporter documentation](https://codecept.io/plugins/#htmlreporter).
280
+
238
281
  ## PageObjects
239
282
 
240
283
  CodeceptJS provides the most simple way to create and use page objects in your test.
@@ -248,83 +291,55 @@ It will create a page object file for you and add it to the config.
248
291
  Let's assume we created one named `docsPage`:
249
292
 
250
293
  ```js
251
- const { I } = inject();
294
+ const { I } = inject()
252
295
 
253
296
  module.exports = {
254
297
  fields: {
255
298
  email: '#user_basic_email',
256
- password: '#user_basic_password'
299
+ password: '#user_basic_password',
257
300
  },
258
- submitButton: {css: '#new_user_basic input[type=submit]'},
301
+ submitButton: { css: '#new_user_basic input[type=submit]' },
259
302
 
260
303
  sendForm(email, password) {
261
- I.fillField(this.fields.email, email);
262
- I.fillField(this.fields.password, password);
263
- I.click(this.submitButton);
264
- }
304
+ I.fillField(this.fields.email, email)
305
+ I.fillField(this.fields.password, password)
306
+ I.click(this.submitButton)
307
+ },
265
308
  }
266
309
  ```
267
310
 
268
311
  You can easily inject it to test by providing its name in test arguments:
269
312
 
270
313
  ```js
271
- Feature('CodeceptJS Demonstration');
314
+ Feature('CodeceptJS Demonstration')
272
315
 
273
- Before(({ I }) => { // or Background
274
- I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation');
275
- });
316
+ Before(({ I }) => {
317
+ // or Background
318
+ I.amOnPage('http://simple-form-bootstrap.plataformatec.com.br/documentation')
319
+ })
276
320
 
277
321
  Scenario('test some forms', ({ I, docsPage }) => {
278
- docsPage.sendForm('hello@world.com','123456');
279
- I.see('User is valid');
280
- I.dontSeeInCurrentUrl('/documentation');
281
- });
322
+ docsPage.sendForm('hello@world.com', '123456')
323
+ I.see('User is valid')
324
+ I.dontSeeInCurrentUrl('/documentation')
325
+ })
282
326
  ```
283
327
 
284
328
  When using Typescript, replace `module.exports` with `export` for autocompletion.
285
329
 
286
-
287
330
  ## Contributing
288
331
 
289
- - ### [Contributing Guide](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CONTRIBUTING.md)
290
- - ### [Code of conduct](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CODE_OF_CONDUCT.md)
291
-
332
+ - ### [Contributing Guide](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CONTRIBUTING.md)
333
+ - ### [Code of conduct](https://github.com/codeceptjs/CodeceptJS/blob/master/.github/CODE_OF_CONDUCT.md)
292
334
 
293
335
  ## Contributors
294
336
 
295
- Thanks all to those who are and will have contributing to this awesome project!
296
-
297
- [//]: contributor-faces
298
- <a href="https://github.com/DavertMik"><img src="https://avatars.githubusercontent.com/u/220264?v=4" title="DavertMik" width="80" height="80"></a>
299
- <a href="https://github.com/kobenguyent"><img src="https://avatars.githubusercontent.com/u/7845001?v=4" title="kobenguyent" width="80" height="80"></a>
300
- <a href="https://github.com/Vorobeyko"><img src="https://avatars.githubusercontent.com/u/11293201?v=4" title="Vorobeyko" width="80" height="80"></a>
301
- <a href="https://github.com/reubenmiller"><img src="https://avatars.githubusercontent.com/u/3029781?v=4" title="reubenmiller" width="80" height="80"></a>
302
- <a href="https://github.com/Arhell"><img src="https://avatars.githubusercontent.com/u/26163841?v=4" title="Arhell" width="80" height="80"></a>
303
- <a href="https://github.com/APshenkin"><img src="https://avatars.githubusercontent.com/u/14344430?v=4" title="APshenkin" width="80" height="80"></a>
304
- <a href="https://github.com/fabioel"><img src="https://avatars.githubusercontent.com/u/9824235?v=4" title="fabioel" width="80" height="80"></a>
305
- <a href="https://github.com/pablopaul"><img src="https://avatars.githubusercontent.com/u/635526?v=4" title="pablopaul" width="80" height="80"></a>
306
- <a href="https://github.com/mirao"><img src="https://avatars.githubusercontent.com/u/12584138?v=4" title="mirao" width="80" height="80"></a>
307
- <a href="https://github.com/Georgegriff"><img src="https://avatars.githubusercontent.com/u/9056958?v=4" title="Georgegriff" width="80" height="80"></a>
308
- <a href="https://github.com/KMKoushik"><img src="https://avatars.githubusercontent.com/u/24666922?v=4" title="KMKoushik" width="80" height="80"></a>
309
- <a href="https://github.com/nikocanvacom"><img src="https://avatars.githubusercontent.com/u/83254493?v=4" title="nikocanvacom" width="80" height="80"></a>
310
- <a href="https://github.com/elukoyanov"><img src="https://avatars.githubusercontent.com/u/11647141?v=4" title="elukoyanov" width="80" height="80"></a>
311
- <a href="https://github.com/gkushang"><img src="https://avatars.githubusercontent.com/u/3663389?v=4" title="gkushang" width="80" height="80"></a>
312
- <a href="https://github.com/tsuemura"><img src="https://avatars.githubusercontent.com/u/17092259?v=4" title="tsuemura" width="80" height="80"></a>
313
- <a href="https://github.com/EgorBodnar"><img src="https://avatars.githubusercontent.com/u/63167966?v=4" title="EgorBodnar" width="80" height="80"></a>
314
- <a href="https://github.com/VikalpP"><img src="https://avatars.githubusercontent.com/u/11846339?v=4" title="VikalpP" width="80" height="80"></a>
315
- <a href="https://github.com/thomashohn"><img src="https://avatars.githubusercontent.com/u/3414869?v=4" title="thomashohn" width="80" height="80"></a>
316
- <a href="https://github.com/elaichenkov"><img src="https://avatars.githubusercontent.com/u/29764053?v=4" title="elaichenkov" width="80" height="80"></a>
317
- <a href="https://github.com/BorisOsipov"><img src="https://avatars.githubusercontent.com/u/6514276?v=4" title="BorisOsipov" width="80" height="80"></a>
318
- <a href="https://github.com/ngraf"><img src="https://avatars.githubusercontent.com/u/7094389?v=4" title="ngraf" width="80" height="80"></a>
319
- <a href="https://github.com/nitschSB"><img src="https://avatars.githubusercontent.com/u/39341455?v=4" title="nitschSB" width="80" height="80"></a>
320
- <a href="https://github.com/hubidu"><img src="https://avatars.githubusercontent.com/u/13134082?v=4" title="hubidu" width="80" height="80"></a>
321
- <a href="https://github.com/jploskonka"><img src="https://avatars.githubusercontent.com/u/669483?v=4" title="jploskonka" width="80" height="80"></a>
322
- <a href="https://github.com/maojunxyz"><img src="https://avatars.githubusercontent.com/u/28778042?v=4" title="maojunxyz" width="80" height="80"></a>
323
- <a href="https://github.com/abhimanyupandian"><img src="https://avatars.githubusercontent.com/u/36107381?v=4" title="abhimanyupandian" width="80" height="80"></a>
324
- <a href="https://github.com/martomo"><img src="https://avatars.githubusercontent.com/u/1850135?v=4" title="martomo" width="80" height="80"></a>
325
- <a href="https://github.com/hatufacci"><img src="https://avatars.githubusercontent.com/u/4963181?v=4" title="hatufacci" width="80" height="80"></a>
326
-
327
- [//]: contributor-faces
337
+ Thanks to our awesome contributors! 🎉
338
+ <a href="https://github.com/codeceptjs/codeceptjs/graphs/contributors">
339
+ <img src="https://contrib.rocks/image?repo=codeceptjs/codeceptjs" />
340
+ </a>
341
+
342
+ Made with [contrib.rocks](https://contrib.rocks).
328
343
 
329
344
  ## License
330
345
 
package/bin/codecept.js CHANGED
@@ -32,7 +32,7 @@ const commandFlags = {
32
32
  }
33
33
 
34
34
  const errorHandler =
35
- (fn) =>
35
+ fn =>
36
36
  async (...args) => {
37
37
  try {
38
38
  await fn(...args)
@@ -58,6 +58,13 @@ program
58
58
  .description('Creates dummy config in current dir or [path]')
59
59
  .action(errorHandler(require('../lib/command/init')))
60
60
 
61
+ program
62
+ .command('check')
63
+ .option(commandFlags.config.flag, commandFlags.config.description)
64
+ .description('Checks configuration and environment before running tests')
65
+ .option('-t, --timeout [ms]', 'timeout for checks in ms, 50000 by default')
66
+ .action(errorHandler(require('../lib/command/check')))
67
+
61
68
  program
62
69
  .command('migrate [path]')
63
70
  .description('Migrate json config to js config in current dir or [path]')
@@ -157,6 +164,8 @@ program
157
164
  .option('--tests', 'run only JS test files and skip features')
158
165
  .option('--no-timeouts', 'disable all timeouts')
159
166
  .option('-p, --plugins <k=v,k2=v2,...>', 'enable plugins, comma-separated')
167
+ .option('--shuffle', 'Shuffle the order in which test files run')
168
+ .option('--shard <index/total>', 'run only a fraction of tests (e.g., --shard 1/4)')
160
169
 
161
170
  // mocha options
162
171
  .option('--colors', 'force enabling of colors')
@@ -188,6 +197,7 @@ program
188
197
  .option('-i, --invert', 'inverts --grep matches')
189
198
  .option('-o, --override [value]', 'override current config options')
190
199
  .option('--suites', 'parallel execution of suites not single tests')
200
+ .option('--by <strategy>', 'test distribution strategy: "test" (pre-assign individual tests), "suite" (pre-assign test suites), or "pool" (dynamic distribution for optimal load balancing, recommended)')
191
201
  .option(commandFlags.debug.flag, commandFlags.debug.description)
192
202
  .option(commandFlags.verbose.flag, commandFlags.verbose.description)
193
203
  .option('--features', 'run only *.feature files and skip tests')
@@ -286,7 +296,7 @@ program
286
296
 
287
297
  .action(require('../lib/command/run-rerun'))
288
298
 
289
- program.on('command:*', (cmd) => {
299
+ program.on('command:*', cmd => {
290
300
  console.log(`\nUnknown command ${cmd}\n`)
291
301
  program.outputHelp()
292
302
  })
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Standalone test server script to replace json-server
5
+ */
6
+
7
+ const path = require('path')
8
+ const TestServer = require('../lib/test-server')
9
+
10
+ // Parse command line arguments
11
+ const args = process.argv.slice(2)
12
+ let dbFile = path.join(__dirname, '../test/data/rest/db.json')
13
+ let port = 8010
14
+ let host = '0.0.0.0'
15
+
16
+ // Simple argument parsing
17
+ for (let i = 0; i < args.length; i++) {
18
+ const arg = args[i]
19
+
20
+ if (arg === '-p' || arg === '--port') {
21
+ port = parseInt(args[++i])
22
+ } else if (arg === '--host') {
23
+ host = args[++i]
24
+ } else if (!arg.startsWith('-')) {
25
+ dbFile = path.resolve(arg)
26
+ }
27
+ }
28
+
29
+ // Create and start server
30
+ const server = new TestServer({ port, host, dbFile })
31
+
32
+ console.log(`Starting test server with db file: ${dbFile}`)
33
+
34
+ server
35
+ .start()
36
+ .then(() => {
37
+ console.log(`Test server is ready and listening on http://${host}:${port}`)
38
+ })
39
+ .catch(err => {
40
+ console.error('Failed to start test server:', err)
41
+ process.exit(1)
42
+ })
43
+
44
+ // Graceful shutdown
45
+ process.on('SIGINT', () => {
46
+ console.log('\nShutting down test server...')
47
+ server.stop().then(() => process.exit(0))
48
+ })
49
+
50
+ process.on('SIGTERM', () => {
51
+ console.log('\nShutting down test server...')
52
+ server.stop().then(() => process.exit(0))
53
+ })
@@ -3,7 +3,7 @@ if none provided clears all cookies.
3
3
 
4
4
  ```js
5
5
  I.clearCookie();
6
- I.clearCookie('test'); // Playwright currently doesn't support clear a particular cookie name
6
+ I.clearCookie('test');
7
7
  ```
8
8
 
9
9
  @param {?string} [cookie=null] (optional, `null` by default) cookie name