codeceptjs 2.3.4 → 2.4.1

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 (269) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +28 -6
  3. package/bin/codecept.js +42 -0
  4. package/docs/advanced.md +45 -1
  5. package/docs/angular.md +3 -3
  6. package/docs/basics.md +162 -118
  7. package/docs/bdd.md +30 -5
  8. package/docs/best.md +8 -6
  9. package/docs/books.md +6 -1
  10. package/docs/build/Appium.js +95 -85
  11. package/docs/build/FileSystem.js +48 -3
  12. package/docs/build/GraphQL.js +3 -2
  13. package/docs/build/GraphQLDataFactory.js +1 -0
  14. package/docs/build/Mochawesome.js +3 -2
  15. package/docs/build/MockRequest.js +23 -5
  16. package/docs/build/Nightmare.js +87 -128
  17. package/docs/build/Protractor.js +107 -155
  18. package/docs/build/Puppeteer.js +190 -174
  19. package/docs/build/REST.js +13 -9
  20. package/docs/build/SeleniumWebdriver.js +0 -17
  21. package/docs/build/TestCafe.js +164 -158
  22. package/docs/build/WebDriver.js +236 -211
  23. package/docs/build/WebDriverIO.js +218 -187
  24. package/docs/changelog.md +57 -1
  25. package/docs/commands.md +41 -2
  26. package/docs/community-helpers.md +12 -1
  27. package/docs/configuration.md +5 -2
  28. package/docs/continuous-integration.md +22 -0
  29. package/docs/{helpers.md → custom-helpers.md} +16 -10
  30. package/docs/data.md +7 -6
  31. package/docs/detox.md +6 -6
  32. package/docs/email.md +4 -2
  33. package/docs/examples.md +22 -3
  34. package/docs/helpers/ApiDataFactory.md +15 -13
  35. package/docs/helpers/Appium.md +1011 -468
  36. package/docs/helpers/Detox.md +33 -26
  37. package/docs/helpers/FileSystem.md +43 -13
  38. package/docs/helpers/GraphQL.md +17 -15
  39. package/docs/helpers/GraphQLDataFactory.md +15 -13
  40. package/docs/helpers/Mochawesome.md +3 -1
  41. package/docs/helpers/MockRequest.md +37 -19
  42. package/docs/helpers/Nightmare.md +129 -240
  43. package/docs/helpers/Polly.md +1 -1
  44. package/docs/helpers/Protractor.md +157 -298
  45. package/docs/helpers/Puppeteer.md +216 -335
  46. package/docs/helpers/REST.md +29 -24
  47. package/docs/helpers/TestCafe.md +137 -235
  48. package/docs/helpers/WebDriver.md +250 -347
  49. package/docs/hooks.md +14 -10
  50. package/docs/index.md +112 -0
  51. package/docs/installation.md +3 -1
  52. package/docs/locators.md +19 -8
  53. package/docs/mobile-react-native-locators.md +2 -2
  54. package/docs/mobile.md +5 -3
  55. package/docs/nightmare.md +2 -1
  56. package/docs/pageobjects.md +4 -2
  57. package/docs/parallel.md +4 -2
  58. package/docs/plugins.md +41 -15
  59. package/docs/puppeteer.md +8 -6
  60. package/docs/quickstart.md +130 -0
  61. package/docs/react.md +4 -2
  62. package/docs/reports.md +6 -4
  63. package/docs/testcafe.md +10 -8
  64. package/docs/translation.md +4 -2
  65. package/docs/ui.md +56 -0
  66. package/docs/videos.md +11 -2
  67. package/docs/visual.md +7 -5
  68. package/docs/vue.md +121 -0
  69. package/docs/webapi/appendField.mustache +1 -1
  70. package/docs/webapi/attachFile.mustache +1 -1
  71. package/docs/webapi/checkOption.mustache +2 -2
  72. package/docs/webapi/clearCookie.mustache +1 -1
  73. package/docs/webapi/click.mustache +2 -2
  74. package/docs/webapi/clickLink.mustache +2 -2
  75. package/docs/webapi/dontSee.mustache +1 -2
  76. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +1 -1
  77. package/docs/webapi/dontSeeElement.mustache +1 -1
  78. package/docs/webapi/dontSeeElementInDOM.mustache +1 -1
  79. package/docs/webapi/dontSeeInField.mustache +1 -1
  80. package/docs/webapi/doubleClick.mustache +2 -2
  81. package/docs/webapi/downloadFile.mustache +1 -1
  82. package/docs/webapi/dragSlider.mustache +1 -1
  83. package/docs/webapi/executeAsyncScript.mustache +2 -1
  84. package/docs/webapi/executeScript.mustache +2 -1
  85. package/docs/webapi/fillField.mustache +1 -1
  86. package/docs/webapi/grabAttributeFrom.mustache +1 -1
  87. package/docs/webapi/grabBrowserLogs.mustache +1 -1
  88. package/docs/webapi/grabCookie.mustache +2 -2
  89. package/docs/webapi/grabCssPropertyFrom.mustache +1 -1
  90. package/docs/webapi/grabHTMLFrom.mustache +1 -1
  91. package/docs/webapi/grabNumberOfVisibleElements.mustache +1 -1
  92. package/docs/webapi/grabPageScrollPosition.mustache +1 -1
  93. package/docs/webapi/grabTextFrom.mustache +2 -2
  94. package/docs/webapi/grabValueFrom.mustache +1 -1
  95. package/docs/webapi/moveCursorTo.mustache +3 -3
  96. package/docs/webapi/pressKey.mustache +1 -1
  97. package/docs/webapi/pressKeyWithKeyNormalization.mustache +1 -1
  98. package/docs/webapi/rightClick.mustache +2 -2
  99. package/docs/webapi/saveScreenshot.mustache +1 -1
  100. package/docs/webapi/scrollIntoView.mustache +10 -0
  101. package/docs/webapi/scrollTo.mustache +3 -3
  102. package/docs/webapi/see.mustache +1 -1
  103. package/docs/webapi/seeAttributesOnElements.mustache +1 -1
  104. package/docs/webapi/seeCheckboxIsChecked.mustache +1 -1
  105. package/docs/webapi/seeCssPropertiesOnElements.mustache +1 -1
  106. package/docs/webapi/seeElement.mustache +1 -1
  107. package/docs/webapi/seeElementInDOM.mustache +1 -1
  108. package/docs/webapi/seeInField.mustache +1 -1
  109. package/docs/webapi/seeNumberOfElements.mustache +1 -1
  110. package/docs/webapi/seeNumberOfVisibleElements.mustache +1 -1
  111. package/docs/webapi/seeTextEquals.mustache +8 -0
  112. package/docs/webapi/selectOption.mustache +2 -2
  113. package/docs/webapi/switchTo.mustache +1 -1
  114. package/docs/webapi/uncheckOption.mustache +2 -2
  115. package/docs/webapi/waitForClickable.mustache +10 -0
  116. package/docs/webapi/waitForDetached.mustache +2 -2
  117. package/docs/webapi/waitForElement.mustache +2 -2
  118. package/docs/webapi/waitForEnabled.mustache +2 -2
  119. package/docs/webapi/waitForFunction.mustache +2 -2
  120. package/docs/webapi/waitForInvisible.mustache +2 -2
  121. package/docs/webapi/waitForText.mustache +2 -2
  122. package/docs/webapi/waitForValue.mustache +1 -1
  123. package/docs/webapi/waitForVisible.mustache +2 -2
  124. package/docs/webapi/waitInUrl.mustache +1 -1
  125. package/docs/webapi/waitNumberOfVisibleElements.mustache +2 -2
  126. package/docs/webapi/waitToHide.mustache +2 -2
  127. package/docs/webapi/waitUntil.mustache +3 -2
  128. package/docs/webapi/waitUrlEquals.mustache +1 -1
  129. package/docs/webdriver.md +20 -18
  130. package/docs/wiki/.git/FETCH_HEAD +1 -0
  131. package/docs/wiki/.git/HEAD +1 -0
  132. package/docs/wiki/.git/ORIG_HEAD +1 -0
  133. package/docs/wiki/.git/config +11 -0
  134. package/docs/wiki/.git/description +1 -0
  135. package/docs/wiki/.git/hooks/applypatch-msg.sample +15 -0
  136. package/docs/wiki/.git/hooks/commit-msg.sample +24 -0
  137. package/docs/wiki/.git/hooks/fsmonitor-watchman.sample +114 -0
  138. package/docs/wiki/.git/hooks/post-update.sample +8 -0
  139. package/docs/wiki/.git/hooks/pre-applypatch.sample +14 -0
  140. package/docs/wiki/.git/hooks/pre-commit.sample +49 -0
  141. package/docs/wiki/.git/hooks/pre-push.sample +53 -0
  142. package/docs/wiki/.git/hooks/pre-rebase.sample +169 -0
  143. package/docs/wiki/.git/hooks/pre-receive.sample +24 -0
  144. package/docs/wiki/.git/hooks/prepare-commit-msg.sample +42 -0
  145. package/docs/wiki/.git/hooks/update.sample +128 -0
  146. package/docs/wiki/.git/index +0 -0
  147. package/docs/wiki/.git/info/exclude +6 -0
  148. package/docs/wiki/.git/logs/HEAD +4 -0
  149. package/docs/wiki/.git/logs/refs/heads/master +4 -0
  150. package/docs/wiki/.git/logs/refs/remotes/origin/HEAD +1 -0
  151. package/docs/wiki/.git/logs/refs/remotes/origin/master +3 -0
  152. package/docs/wiki/.git/objects/00/d216b0774d15db2d0a2a0d4ce249b5251acc55 +3 -0
  153. package/docs/wiki/.git/objects/09/01d87c5241905fdfe3493cfe8f04df4a2685ea +0 -0
  154. package/docs/wiki/.git/objects/0d/bdd0c20c4deb6a8cc81dbbf32ecf8c09238983 +2 -0
  155. package/docs/wiki/.git/objects/1a/c29e4fa82422c52392f22f0f2b8d1a759535bf +0 -0
  156. package/docs/wiki/.git/objects/27/12f92898d3e8f68e229b6cda76570d6c66d781 +0 -0
  157. package/docs/wiki/.git/objects/2d/dbe22c257166b648928eeb9460ecfb71ba702d +0 -0
  158. package/docs/wiki/.git/objects/2f/c942ec3773efd2678d9ff98035c61fcded81a1 +0 -0
  159. package/docs/wiki/.git/objects/40/a2856342c67796b48911a256b764fb06888b94 +5 -0
  160. package/docs/wiki/.git/objects/47/53181844fc4dc563cf3aa5e80462243cb58d38 +0 -0
  161. package/docs/wiki/.git/objects/4e/24a95fb2e4f8ffef51f19b694451a205c06f10 +3 -0
  162. package/docs/wiki/.git/objects/73/31ebd96f3c7e08a9f63f05a25f939afa0d4de1 +0 -0
  163. package/docs/wiki/.git/objects/86/19cbb2289caa502e33fccf0ed14eecf6ba2ba0 +0 -0
  164. package/docs/wiki/.git/objects/a4/72f797d9d74b87c9f71a2b1539d75bb07d1e35 +0 -0
  165. package/docs/wiki/.git/objects/c9/9f3e4bd227d6b050b2e416f9876df49583dbf6 +0 -0
  166. package/docs/wiki/.git/objects/ca/e609b4ef3e0ef85fcbe0d68d1a58246584b915 +0 -0
  167. package/docs/wiki/.git/objects/d5/8386ca72f6d550548f3d71d74e3ac73d5ad488 +0 -0
  168. package/docs/wiki/.git/objects/d9/c6874a6de524bdafeb563a20d847f4fdd59a86 +0 -0
  169. package/docs/wiki/.git/objects/f1/c944675bb38b40ae553b0be36c14674c79af54 +0 -0
  170. package/docs/wiki/.git/objects/pack/pack-28da0fc7e6c08d4c5350717bfbb7b1c53e8198ad.idx +0 -0
  171. package/docs/wiki/.git/objects/pack/pack-28da0fc7e6c08d4c5350717bfbb7b1c53e8198ad.pack +0 -0
  172. package/docs/wiki/.git/packed-refs +2 -0
  173. package/docs/wiki/.git/refs/heads/master +1 -0
  174. package/docs/wiki/.git/refs/remotes/origin/HEAD +1 -0
  175. package/docs/wiki/.git/refs/remotes/origin/master +1 -0
  176. package/docs/wiki/Books-&-Posts.md +27 -0
  177. package/docs/wiki/Community-Helpers.md +41 -0
  178. package/docs/wiki/Examples.md +138 -0
  179. package/docs/wiki/Home.md +11 -0
  180. package/docs/wiki/Release-process.md +25 -0
  181. package/docs/wiki/Roadmap.md +23 -0
  182. package/docs/wiki/Videos.md +19 -0
  183. package/lib/actor.js +18 -1
  184. package/lib/assert/error.js +3 -3
  185. package/lib/codecept.js +9 -6
  186. package/lib/command/configMigrate.js +7 -6
  187. package/lib/command/definitions.js +98 -350
  188. package/lib/command/generate.js +22 -17
  189. package/lib/command/gherkin/init.js +2 -1
  190. package/lib/command/gherkin/snippets.js +6 -6
  191. package/lib/command/gherkin/steps.js +0 -1
  192. package/lib/command/info.js +40 -0
  193. package/lib/command/init.js +54 -41
  194. package/lib/command/run-multiple.js +5 -4
  195. package/lib/command/run-rerun.js +39 -0
  196. package/lib/command/run-workers.js +4 -6
  197. package/lib/command/run.js +8 -18
  198. package/lib/command/utils.js +23 -2
  199. package/lib/command/workers/runTests.js +1 -2
  200. package/lib/config.js +10 -4
  201. package/lib/container.js +31 -6
  202. package/lib/data/dataTableArgument.js +31 -0
  203. package/lib/data/table.js +4 -0
  204. package/lib/event.js +65 -1
  205. package/lib/helper/Appium.js +52 -38
  206. package/lib/helper/FileSystem.js +48 -3
  207. package/lib/helper/GraphQL.js +3 -2
  208. package/lib/helper/GraphQLDataFactory.js +1 -0
  209. package/lib/helper/Mochawesome.js +3 -2
  210. package/lib/helper/MockRequest.js +23 -5
  211. package/lib/helper/Nightmare.js +5 -6
  212. package/lib/helper/Protractor.js +7 -8
  213. package/lib/helper/Puppeteer.js +76 -20
  214. package/lib/helper/REST.js +13 -9
  215. package/lib/helper/SeleniumWebdriver.js +0 -17
  216. package/lib/helper/TestCafe.js +84 -36
  217. package/lib/helper/WebDriver.js +113 -59
  218. package/lib/helper/WebDriverIO.js +43 -59
  219. package/lib/helper/clientscripts/nightmare.js +66 -4
  220. package/lib/helper/scripts/isElementClickable.js +24 -0
  221. package/lib/helper.js +34 -10
  222. package/lib/history.js +1 -1
  223. package/lib/hooks.js +2 -1
  224. package/lib/index.js +19 -0
  225. package/lib/interfaces/bdd.js +4 -0
  226. package/lib/interfaces/featureConfig.js +10 -3
  227. package/lib/interfaces/gherkin.js +6 -2
  228. package/lib/interfaces/scenarioConfig.js +17 -6
  229. package/lib/listener/config.js +1 -1
  230. package/lib/listener/exit.js +6 -0
  231. package/lib/listener/steps.js +0 -1
  232. package/lib/listener/trace.js +0 -1
  233. package/lib/locator.js +67 -2
  234. package/lib/output.js +53 -0
  235. package/lib/parser.js +2 -71
  236. package/lib/pause.js +3 -2
  237. package/lib/plugin/allure.js +41 -22
  238. package/lib/plugin/autoLogin.js +4 -1
  239. package/lib/plugin/pauseOnFail.js +38 -0
  240. package/lib/plugin/puppeteerCoverage.js +8 -7
  241. package/lib/plugin/screenshotOnFail.js +13 -8
  242. package/lib/plugin/stepByStepReport.js +7 -6
  243. package/lib/plugin/wdio.js +2 -1
  244. package/lib/recorder.js +85 -7
  245. package/lib/rerun.js +81 -0
  246. package/lib/secret.js +6 -0
  247. package/lib/session.js +9 -2
  248. package/lib/step.js +37 -2
  249. package/lib/store.js +5 -1
  250. package/lib/ui.js +34 -8
  251. package/lib/utils.js +6 -13
  252. package/lib/within.js +5 -0
  253. package/package.json +49 -29
  254. package/typings/Mocha.d.ts +21 -0
  255. package/typings/Protractor.d.ts +16 -0
  256. package/typings/index.d.ts +169 -0
  257. package/typings/jsdoc.conf.js +34 -0
  258. package/typings/jsdoc.namespace.js +29 -0
  259. package/typings/types.d.ts +9827 -0
  260. package/typings/utils.d.ts +7 -0
  261. package/docs/acceptance.md +0 -409
  262. package/docs/api/codecept.md +0 -75
  263. package/docs/api/config.md +0 -49
  264. package/docs/api/container.md +0 -66
  265. package/docs/api/helper.md +0 -116
  266. package/docs/api/output.md +0 -67
  267. package/docs/api/recorder.md +0 -63
  268. package/docs/helpers/SeleniumWebdriver.md +0 -92
  269. package/docs/helpers/WebDriverIO.md +0 -1671
package/docs/basics.md CHANGED
@@ -1,9 +1,11 @@
1
1
  ---
2
- id: basics
3
- title: Basics
2
+ permalink: /basics
3
+ title: Getting Started
4
4
  ---
5
5
 
6
- CodeceptJS is a modern end to end testing framework with a special BDD-style syntax. The test is written as a linear scenario of user's action on a site.
6
+ # Getting Started
7
+
8
+ 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.
7
9
 
8
10
  ```js
9
11
  Feature('CodeceptJS demo');
@@ -16,41 +18,41 @@ Scenario('check Welcome page on site', (I) => {
16
18
 
17
19
  Tests are expected to be written in **ECMAScript 7**.
18
20
 
19
- Each test is described inside a `Scenario` function with `I` object passed into it.
20
- I object is an **actor**, an abstraction for a testing user. I is a proxy object for currently enabled **Helpers**.
21
+ Each test is described inside a `Scenario` function with the `I` object passed into it.
22
+ The `I` object is an **actor**, an abstraction for a testing user. The `I` is a proxy object for currently enabled **Helpers**.
21
23
 
22
24
  ## Architecture
23
25
 
24
- CodeceptJS bypasses execution commands to helpers. Depending on helper enabled your tests will be executed differently. If you need cross-browser support you should choose Selenium-based WebDriver or Protractor, if you are interested in speed - use Chrome-based Puppeteer, or Electron-based Nightmare. Those engines can run tests in window mode or headlessly and doesn't require additional tools to be installed.
26
+ CodeceptJS bypasses execution commands to helpers. Depending on the helper enabled, your tests will be executed differently. If you need cross-browser support you should choose Selenium-based WebDriver or TestCafé. If you are interested in speed - you should use Chrome-based Puppeteer.
25
27
 
26
- Here is the diagram of CodeceptJS architecture
28
+ The following is a diagram of the CodeceptJS architecture:
27
29
 
28
- ![architecture](https://codecept.io/img/architecture.svg)
30
+ ![architecture](/img/architecture.svg)
29
31
 
30
- All helpers share the same API so it's easy to migrate tests from one backend to other.
31
- However, because of 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 or Protractor, but you can do so in Puppteer or Nightmare.
32
+ All helpers share the same API, so it's easy to migrate tests from one backend to another.
33
+ 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 or Protractor, but you can do so in Puppteer or Nightmare.
32
34
 
33
- **Pick one helper, as it defines how tests are executed.** If requirements change it's easy to migrate to another, but don't use few helpers of same kind at once.
35
+ **Pick one helper, as it defines how tests are executed.** If requirements change it's easy to migrate to another.
34
36
 
35
37
  ---
36
38
 
37
39
  Refer to following guides to more information on:
38
40
 
39
- * [▶ WebDriver](https://codecept.io/webdriver)
40
- * [▶ Protractor](https://codecept.io/angular)
41
- * [▶ Puppeteer](https://codecept.io/puppeteer)
42
- * [▶ Nightmare](https://codecept.io/nightmare)
43
- * [▶ TestCafe](https://codecept.io/testcafe)
41
+ * [▶ WebDriver](/webdriver)
42
+ * [▶ Protractor](/angular)
43
+ * [▶ Puppeteer](/puppeteer)
44
+ * [▶ Nightmare](/nightmare)
45
+ * [▶ TestCafe](/testcafe)
44
46
 
45
47
  > ℹ Depending on a helper selected a list of available actions may change.
46
48
 
47
- To list all available commands for current configuration run `codeceptjs list`
49
+ To list all available commands for the current configuration run `codeceptjs list`
48
50
  or enable [auto-completion by generating TypeScript definitions](#intellisense).
49
51
 
50
52
 
51
53
  ## Writing Tests
52
54
 
53
- Tests are written from a user's perspective. There is an actor (represented as `I`) which contains actions taken from helpers. A test is written as a sequence of actions performed by actor:
55
+ Tests are written from a user's perspective. There is an actor (represented as `I`) which contains actions taken from helpers. A test is written as a sequence of actions performed by an actor:
54
56
 
55
57
  ```js
56
58
  I.amOnPage('/');
@@ -61,9 +63,9 @@ I.see('Please Login', 'h1');
61
63
 
62
64
  ### Opening a Page
63
65
 
64
- A test should usually start with navigating browser to the website.
66
+ A test should usually start by navigating the browser to a website.
65
67
 
66
- Start a test by opening a page. Use `I.amOnPage()` command for this:
68
+ Start a test by opening a page. Use the `I.amOnPage()` command for this:
67
69
 
68
70
  ```js
69
71
  // When "http://site.com" is url in config
@@ -72,9 +74,9 @@ I.amOnPage('/about'); // -> opens http://site.com/about
72
74
  I.amOnPage('https://google.com'); // -> https://google.com
73
75
  ```
74
76
 
75
- When URL doesn't start with a protocol (http:// or https://) it is considered to be a relative URL and appended to URL which was initially set in the config.
77
+ 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.
76
78
 
77
- > It is recommended to use relative URLs and keep base URL in config file, so you could easily switch between development, staging, and production environments.
79
+ > 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.
78
80
 
79
81
 
80
82
  ### Locating Element
@@ -87,7 +89,7 @@ I.seeElement('//button[contains(., "press me")]'); // button
87
89
  ```
88
90
 
89
91
  By default CodeceptJS tries to guess the locator type.
90
- In order to specify exact locator type you can pass an object called **strict locator**.
92
+ In order to specify the exact locator type you can pass an object called **strict locator**.
91
93
 
92
94
  ```js
93
95
  I.seeElement({css: 'div.user'});
@@ -99,13 +101,11 @@ Strict locators allow to specify additional locator types:
99
101
  ```js
100
102
  // locate form element by name
101
103
  I.seeElement({name: 'password'});
102
- // locate element by id
103
- I.seeElement({id: 'users'});
104
104
  // locate element by React component and props
105
105
  I.seeElement({react: 'user-profile', props: {name: 'davert'}});
106
106
  ```
107
107
 
108
- In [mobile testing](http://codecept.io/mobile/#locating-elements) you can use `~` to specify accessibility id to locate an element. In web application you can locate element by their `aria-label` value.
108
+ In [mobile testing](http://codecept.io/mobile/#locating-elements) you can use `~` to specify the accessibility id to locate an element. In web application you can locate elements by their `aria-label` value.
109
109
 
110
110
  ```js
111
111
  // locate element by [aria-label] attribute in web
@@ -113,29 +113,29 @@ In [mobile testing](http://codecept.io/mobile/#locating-elements) you can use `~
113
113
  I.seeElement('~username');
114
114
  ```
115
115
 
116
- > [▶ Learn more about using locators in CodeceptJS](https://codecept.io/locators).
116
+ > [▶ Learn more about using locators in CodeceptJS](/locators).
117
117
 
118
118
  ### Clicking
119
119
 
120
120
  CodeceptJS provides a flexible syntax to specify an element to click.
121
121
 
122
- By default CodeceptJS tries to find button or link with exact text on it
122
+ By default CodeceptJS tries to find the button or link with the exact text on it
123
123
 
124
124
  ```js
125
125
  // search for link or button
126
126
  I.click('Login');
127
127
  ```
128
128
 
129
- If none found, CodeceptJS tries to find link or button containing that text. In case an image is clickable its `alt` attribute will be checked for text inclusion. Form buttons will also be searched by name.
129
+ If none was found, CodeceptJS tries to find a link or button containing that text. In case an image is clickable its `alt` attribute will be checked for text inclusion. Form buttons will also be searched by name.
130
130
 
131
- To narrow down the results you can specify a context in second parameter.
131
+ To narrow down the results you can specify a context in the second parameter.
132
132
 
133
133
  ```js
134
134
  I.click('Login', '.nav'); // search only in .nav
135
135
  I.click('Login', {css: 'footer'}); // search only in footer
136
136
  ```
137
137
 
138
- > To skip guessing locator type pass in a strict locator. A locator starting with '#' or '.' is considered to be CSS. Locator starting with '//' or './/' is considered to be XPath.
138
+ > 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.
139
139
 
140
140
  You are not limited to buttons and links. Any element can be found by passing in valid CSS or XPath:
141
141
 
@@ -148,7 +148,7 @@ I.click('//dev[@test-id="myid"]');
148
148
 
149
149
  ### Filling Fields
150
150
 
151
- 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 routine waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.
151
+ 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.
152
152
 
153
153
  Let's submit this sample form for a test:
154
154
 
@@ -167,7 +167,7 @@ Let's submit this sample form for a test:
167
167
  </form>
168
168
  ```
169
169
 
170
- We need to fill in all those fields and click "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.
170
+ 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.
171
171
 
172
172
  ```js
173
173
  // we are using label to match user_name field
@@ -192,7 +192,7 @@ I.selectOption('#user_gender','m');
192
192
  I.click('submitButton', '#update_form');
193
193
  ```
194
194
 
195
- To fill in sensitive data use `secret` function:
195
+ To fill in sensitive data use the `secret` function:
196
196
 
197
197
  ```js
198
198
  I.fillField('password', secret('123456'));
@@ -200,8 +200,8 @@ I.fillField('password', secret('123456'));
200
200
 
201
201
  ### Assertions
202
202
 
203
- In order to verify the expected behavior of a web application, a content should be checked.
204
- CodeceptJS provides built-in assertions for that. They start with `see` (or `dontSee`) prefix.
203
+ In order to verify the expected behavior of a web application, it's content should be checked.
204
+ CodeceptJS provides built-in assertions for that. They start with a `see` (or `dontSee`) prefix.
205
205
 
206
206
  The most general and common assertion is `see`, which checks visilibility of a text on a page:
207
207
 
@@ -214,7 +214,7 @@ I.see('Hello', '.msg');
214
214
  I.dontSee('Bye');
215
215
  ```
216
216
 
217
- You should provide a text as first argument and optionally a locator to search for a text in a context.
217
+ You should provide a text as first argument and, optionally, a locator to search for a text in a context.
218
218
 
219
219
  You can check that specific element exists (or not) on a page, as it was described in [Locating Element](#locating-element) section.
220
220
 
@@ -231,12 +231,12 @@ I.seeInField('user[name]', 'Miles');
231
231
  I.seeInTitle('My Website');
232
232
  ```
233
233
 
234
- To see all possible assertions see the helper's reference.
234
+ To see all possible assertions, check the helper's reference.
235
235
 
236
236
  ### Grabbing
237
237
 
238
- Sometimes you need to retrieve a data from a page to use it in next steps of a scenario.
239
- Imagine, application generates a password and you want to ensure that user can login using this password.
238
+ Sometimes you need to retrieve data from a page to use it in the following steps of a scenario.
239
+ Imagine the application generates a password, and you want to ensure that user can login using this password.
240
240
 
241
241
  ```js
242
242
  Scenario('login with generated password', async (I) => {
@@ -251,7 +251,7 @@ Scenario('login with generated password', async (I) => {
251
251
  });
252
252
  ```
253
253
 
254
- `grabTextFrom` action is used here to retrieve text from an element. All actions starting with `grab` prefix are expected to return data. In order to synchronize this step with a scenario you should pause test execution with `await` keyword of ES6. To make it work your test should be written inside a async function (notice `async` in its definition).
254
+ The `grabTextFrom` action is used to retrieve the text from an element. All actions starting with the `grab` prefix are expected to return data. In order to synchronize this step with a scenario you should pause the test execution with the `await` keyword of ES6. To make it work, your test should be written inside a async function (notice `async` in its definition).
255
255
 
256
256
  ```js
257
257
  Scenario('use page title', async (I) => {
@@ -263,9 +263,9 @@ Scenario('use page title', async (I) => {
263
263
 
264
264
  ### Waiting
265
265
 
266
- In modern web applications rendering is happen on client side.
266
+ In modern web applications, rendering is done on the client-side.
267
267
  Sometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet.
268
- To handle this cases `wait*` methods introduced.
268
+ To handle these cases, the `wait*` methods has been introduced.
269
269
 
270
270
  ```js
271
271
  I.waitForElement('#agree_button', 30); // secs
@@ -273,17 +273,19 @@ I.waitForElement('#agree_button', 30); // secs
273
273
  I.click('#agree_button');
274
274
  ```
275
275
 
276
- > ℹ See [helpers reference](https://codecept.io/reference) for a complete list of all available commands for a helper you use.
276
+ > ℹ See [helpers reference](/reference) for a complete list of all available commands for the helper you use.
277
277
 
278
278
  ## How It Works
279
279
 
280
280
  Tests are written in a synchronous way. This improves the readability and maintainability of tests.
281
- While writing tests you should not think about promises. You should focus on the test scenario.
281
+ While writing tests you should not think about promises, and instead should focus on the test scenario.
282
+
283
+ However, behind the scenes **all actions are wrapped in promises**, inside of the `I` object.
284
+ [Global promise](https://github.com/Codeception/CodeceptJS/blob/master/lib/recorder.js) chain is initialized before each test and all `I.*` calls will be appended to it, as well as setup and teardown.
282
285
 
283
- However, behind the scenes **all actions are wrapped in promises** inside of the `I` object.
284
- [Global promise](https://github.com/Codeception/CodeceptJS/blob/master/lib/recorder.js) chain is initialized before each test and all `I.*` calls will be appended to it as well as setup and teardown.
286
+ > 📺 [Learn how CodeceptJS](https://www.youtube.com/watch?v=MDLLpHAwy_s) works with promises by watching video on YouTube
285
287
 
286
- If you want to get information from a running test you can use `await` inside **async function** and special methods of helpers started with `grab` prefix.
288
+ If you want to get information from a running test you can use `await` inside the **async function**, and utilize special methods of helpers started with the `grab` prefix.
287
289
 
288
290
  ```js
289
291
  Scenario('try grabbers', async (I) => {
@@ -301,23 +303,23 @@ assert.equal(title, 'CodeceptJS');
301
303
 
302
304
  ## Running Tests
303
305
 
304
- To launch tests use `run` command. To execute tests in [multiple browsers](https://codecept.io/advanced/#multiple-browsers-execution) or [multiple threads](https://codecept.io/advanced/#parallel-execution) use `run-multiple`.
306
+ To launch tests use the `run` command, and to execute tests in [multiple browsers](/advanced/#multiple-browsers-execution) or [multiple threads](/advanced/#parallel-execution) use the `run-multiple` command.
305
307
 
306
308
  ### Level of Detail
307
309
 
308
- To see step-by-step output of running tests, add `--steps` flag:
310
+ To see the step-by-step output of running tests, add the `--steps` flag:
309
311
 
310
312
  ```
311
313
  npx codeceptjs run --steps
312
314
  ```
313
315
 
314
- To see more detailed output add `--debug` flag:
316
+ To see a more detailed output add the `--debug` flag:
315
317
 
316
318
  ```
317
319
  npx codeceptjs run --debug
318
320
  ```
319
321
 
320
- To see very detailed output system use `--verbose` flag:
322
+ To see very detailed output informations use the `--verbose` flag:
321
323
 
322
324
  ```
323
325
  npx codeceptjs run --verbose
@@ -325,7 +327,7 @@ npx codeceptjs run --verbose
325
327
 
326
328
  ### Filter
327
329
 
328
- A single test file can be executed if you provide a relative path to such file:
330
+ A single test file can be executed if you provide a relative path to such a file:
329
331
 
330
332
  ```
331
333
  npx codeceptjs run github_test.js
@@ -335,33 +337,33 @@ npx codeceptjs run github_test.js
335
337
  npx codeceptjs run admin/login_test.js
336
338
  ```
337
339
 
338
- To filter a test by name use `--grep` parameter. Which will execute all tests with names matching the regex pattern.
340
+ To filter a test by name use the `--grep` parameter, which will execute all tests with names matching the regex pattern.
339
341
 
340
- To run all tests with `slow` word in it
342
+ To run all tests with the `slow` word in it:
341
343
 
342
344
  ```
343
345
  npx codeceptjs run --grep "slow"
344
346
  ```
345
347
 
346
- It is recommended to [filter tests by tags](https://codecept.io/advanced/#tags).
348
+ It is recommended to [filter tests by tags](/advanced/#tags).
347
349
 
348
350
 
349
- > For more options see [full reference of `run` command](https://codecept.io/commands/#run).
351
+ > For more options see [full reference of `run` command](/commands/#run).
350
352
 
351
353
  ### Parallel Run
352
354
 
353
- Since CodeceptJS 2.3 you can run tests in parallel by using NodeJS workers. This feature requires NodeJS >= 11.6. Use `run-workers` command with the number of workers (threads) to split tests.
355
+ Since CodeceptJS 2.3, you can run tests in parallel by using NodeJS workers. This feature requires NodeJS >= 11.6. Use `run-workers` command with the number of workers (threads) to split tests.
354
356
 
355
357
  ```
356
358
  npx codeceptjs run-workers 3
357
359
  ```
358
360
 
359
- Tests are split by scenarios, not by files. Results are aggregated and shown in the main process.
361
+ Tests are split by scenarios, not by files. Results are aggregated and shown up in the main process.
360
362
 
361
363
  ## Configuration
362
364
 
363
- Configuration is set in `codecept.conf.js` file which was created during `init` process.
364
- Inside config file you can enable and configure helpers, plugins, set bootstrap and teardown scripts.
365
+ Configuration is set in the `codecept.conf.js` file which was created during the `init` process.
366
+ Inside the config file you can enable and configure helpers and plugins, and set bootstrap and teardown scripts.
365
367
 
366
368
  ```js
367
369
  exports.config = {
@@ -377,17 +379,17 @@ exports.config = {
377
379
  }
378
380
  ```
379
381
 
380
- > ▶ See complete [configuration reference](https://codecept.io/configuration).
382
+ > ▶ See complete [configuration reference](/configuration).
381
383
 
382
- You can have multiple configuration files for a one project. In this case specify a config file to be used with `-c` when running.
384
+ You can have multiple configuration files for a the same project, in this case you can specify a config file to be used with `-c` when running.
383
385
 
384
386
  ```
385
387
  npx codeceptjs run -c codecept.ci.conf.js
386
388
  ```
387
389
 
388
- Tuning configuration for helpers like WebDriver, Puppeteer can be hard, as it requires good understanding of how those technologies work. Use [`@codeceptjs/configure`](https://github.com/codecept-js/configure) package with common configuration recipes.
390
+ Tuning configuration for helpers like WebDriver, Puppeteer can be hard, as it requires good understanding of how these technologies work. Use the [`@codeceptjs/configure`](https://github.com/codecept-js/configure) package with common configuration recipes.
389
391
 
390
- For instance, you can set window size or toggle headless mode no matter of which helpers are actually used.
392
+ For instance, you can set the window size or toggle headless mode, no matter of which helpers are actually used.
391
393
 
392
394
  ```js
393
395
  const { setHeadlessWhen, setWindowSize } = require('@codeceptjs/configure');
@@ -407,7 +409,7 @@ exports.config = {
407
409
  ## Debug
408
410
 
409
411
  CodeceptJS allows to write and debug tests on the fly while keeping your browser opened.
410
- By using interactive shell you can stop execution at any point and type in CodeceptJS commands.
412
+ By using the interactive shell you can stop execution at any point and type in any CodeceptJS commands.
411
413
 
412
414
  This is especially useful while writing a new scratch. After opening a page call `pause()` to start interacting with a page:
413
415
 
@@ -422,7 +424,7 @@ Try to perform your scenario step by step. Then copy succesful commands and inse
422
424
 
423
425
  Test execution can be paused in any place of a test with `pause()` call.
424
426
 
425
- This launches interactive console where you can call actions of `I` object.
427
+ This launches the interactive console where you can call any action from the `I` object.
426
428
 
427
429
  ```
428
430
  Interactive shell started
@@ -434,54 +436,67 @@ This launches interactive console where you can call actions of `I` object.
434
436
 
435
437
  ```
436
438
 
437
- Type in different actions to try them, copy valid successful ones to test, update the test file.
439
+ Type in different actions to try them, copy and paste successful ones into the test file.
438
440
 
439
441
  Press `ENTER` to resume test execution.
440
442
 
441
- To **debug test step-by-step** type press Enter. The next step will be executed and interactive shell will be shown again.
443
+ To **debug test step-by-step** press Enter, the next step will be executed and interactive shell will be shown again.
442
444
 
443
- To see all available commands press TAB two times to see list of all actions included in I.
445
+ To see all available commands, press TAB two times to see list of all actions included in the `I` object.
444
446
 
445
- If a test is failing you can prevent browser from closing by putting `pause()` command into `After()` hook. This is very helpful to debug failing tests. This way you can keep the same session and try different actions on a page to get the idea what went wrong.
447
+ The interactive shell can be started outside of test context by running
446
448
 
447
- ```js
448
- After(pause);
449
+ ```bash
450
+ npx codeceptjs shell
449
451
  ```
450
452
 
451
- Interactive shell can be started outside the test context by running
453
+ ### Pause on Failure <Badge text="Since 2.4" type="warning"/>
452
454
 
453
- ```bash
454
- codeceptjs shell
455
- ```
455
+ To start interactive pause automatically for a failing test you can run tests with [pauseOnFail Plugin](/plugins/#pauseonfail).
456
+ When a test fails, the pause mode will be activated, so you can inspect current browser session before it is closed.
457
+
458
+ This is an **essential feature to debug flaky tests**, as you can analyze them in the moment of failure.
459
+
460
+ > ℹ To enable pause after a test without a plugin use `After(pause)` inside a test file.
456
461
 
457
462
 
458
- ### Screenshot on failure
463
+ ### Screenshot on Failure
459
464
 
460
465
  By default CodeceptJS saves a screenshot of a failed test.
461
- This can be configured in [screenshotOnFail Plugin](https://codecept.io/plugins/#screenshotonfail)
466
+ This can be configured in [screenshotOnFail Plugin](/plugins/#screenshotonfail)
467
+
468
+ > **screenshotOnFail plugin is enabled by default** for new setups
462
469
 
463
470
  ### Step By Step Report
464
471
 
465
- To see how the test was executed, use [stepByStepReport Plugin](https://codecept.io/plugins/#stepbystepreport). It saves a screenshot of each passed step and shows them in a nice slideshow.
472
+ To see how the test was executed, use [stepByStepReport Plugin](/plugins/#stepbystepreport). It saves a screenshot of each passed step and shows them in a nice slideshow.
466
473
 
467
474
  ## Retries
468
475
 
476
+ ### Auto Retry
477
+
478
+ You can auto-retry a failed step by enabling [retryFailedStep Plugin](/plugins/#retryfailedstep).
479
+
480
+ > **autoRetry plugin is enabled by default** for new setups since CodeceptJS 2.4
481
+
469
482
  ### Retry Step
470
483
 
471
- If you have a step which often fails you can retry execution for this single step.
472
- Use `retry()` function before an action to ask CodeceptJS to retry this step on failure:
484
+ Unless you use retryFailedStep plugin you can manually control retries in your project.
485
+
486
+ If you have a step which often fails, you can retry execution for this single step.
487
+ Use the `retry()` function before an action to ask CodeceptJS to retry it on failure:
473
488
 
474
489
  ```js
475
490
  I.retry().see('Welcome');
476
491
  ```
477
492
 
478
- If you'd like to retry step more than once pass the amount as parameter:
493
+ If you'd like to retry a step more than once, pass the amount as a parameter:
479
494
 
480
495
  ```js
481
496
  I.retry(3).see('Welcome');
482
497
  ```
483
498
 
484
- Additional options can be provided to retry so you can set the additional options (defined in [promise-retry](https://www.npmjs.com/package/promise-retry) library).
499
+ Additional options can be provided to `retry`, so you can set the additional options (defined in [promise-retry](https://www.npmjs.com/package/promise-retry) library).
485
500
 
486
501
 
487
502
  ```js
@@ -498,18 +513,15 @@ I.retry({
498
513
  }).seeElement('#user');
499
514
  ```
500
515
 
501
- Pass a function to `when` option to retry only when error matches the expected one.
502
-
503
- ### Auto Retry
516
+ Pass a function to the `when` option to retry only when an error matches the expected one.
504
517
 
505
- You can auto-retry a failed step by enabling [retryFailedStep Plugin](https://codecept.io/plugins/#retryfailedstep).
506
518
 
507
519
  ### Retry Scenario
508
520
 
509
- When you need to rerun scenarios few times just add `retries` option added to `Scenario` declaration.
521
+ When you need to rerun scenarios a few times, add the `retries` option to the `Scenario` declaration.
510
522
 
511
- CodeceptJS implements retries the same way [Mocha do](https://mochajs.org#retry-tests);
512
- You can set number of a retries for a feature:
523
+ CodeceptJS implements retries the same way [Mocha does](https://mochajs.org#retry-tests);
524
+ You can set the number of a retries for a feature:
513
525
 
514
526
  ```js
515
527
  Scenario('Really complex', (I) => {
@@ -521,22 +533,23 @@ Scenario('Really complex', { retries: 2 }, (I) => {});
521
533
  ```
522
534
 
523
535
  This scenario will be restarted two times on a failure.
536
+ Unlike retry step, there is no `when` condition supported for retries on a scenario level.
524
537
 
525
538
  ### Retry Feature
526
539
 
527
- To set this option for all scenarios in a file, add retry to a feature:
540
+ To set this option for all scenarios in a file, add `retry` to a feature:
528
541
 
529
542
  ```js
530
543
  Feature('Complex JS Stuff').retry(3);
531
544
  ```
532
545
 
533
546
  Every Scenario inside this feature will be rerun 3 times.
534
- You can make an exception for a specific scenario by passing `retries` option to a Scenario.
547
+ You can make an exception for a specific scenario by passing the `retries` option to a Scenario.
535
548
 
536
549
 
537
550
  ## Before
538
551
 
539
- Common preparation steps like opening a web page, logging in a user, can be placed in `Before` or `Background` hook:
552
+ Common preparation steps like opening a web page or logging in a user, can be placed in the `Before` or `Background` hooks:
540
553
 
541
554
  ```js
542
555
  Feature('CodeceptJS Demonstration');
@@ -560,9 +573,9 @@ Same as `Before` you can use `After` to run teardown for each scenario.
560
573
 
561
574
  ## BeforeSuite
562
575
 
563
- If you need to run complex setup before all tests and teardown this afterwards you can use `BeforeSuite` and `AfterSuite`
564
- functions. `BeforeSuite` and `AfterSuite` have access to `I` object, but `BeforeSuite/AfterSuite` don't have an access to the browser because it's not running at this moment.
565
- You can use them to execute handlers that will setup your environment. `BeforeSuite/AfterSuite` will work only for a file where it was declared (so you can declare different setups for files)
576
+ If you need to run complex a setup before all tests and have to teardown this afterwards, you can use the `BeforeSuite` and `AfterSuite` functions.
577
+ `BeforeSuite` and `AfterSuite` have access to the `I` object, but `BeforeSuite/AfterSuite` don't have any access to the browser, because it's not running at this moment.
578
+ You can use them to execute handlers that will setup your environment. `BeforeSuite/AfterSuite` will work only for the file it was declared in (so you can declare different setups for files)
566
579
 
567
580
  ```js
568
581
  BeforeSuite((I) => {
@@ -575,11 +588,11 @@ AfterSuite((I) => {
575
588
  });
576
589
  ```
577
590
 
578
- [Here are some ideas](https://github.com/Codeception/CodeceptJS/pull/231#issuecomment-249554933) where to use BeforeSuite hooks.
591
+ [Here are some ideas](https://github.com/Codeception/CodeceptJS/pull/231#issuecomment-249554933) on where to use BeforeSuite hooks.
579
592
 
580
593
  ## Within
581
594
 
582
- To specify the exact area on a page where actions can be performed you can use `within` function.
595
+ To specify the exact area on a page where actions can be performed you can use the `within` function.
583
596
  Everything executed in its context will be narrowed to context specified by locator:
584
597
 
585
598
  Usage: `within('section', ()=>{})`
@@ -595,7 +608,10 @@ within('.js-signup-form', () => {
595
608
  I.see('There were problems creating your account.');
596
609
  ```
597
610
 
598
- `within` can also work with IFrames. Special `frame` locator is required to locate the iframe and get into its context.
611
+ > ⚠ `within` can cause problems when used incorrectly. If you see a weired behavior of a test try to refactor it to not use `within`. It is recommended to keep within for simplest cases when possible.
612
+
613
+ `within` can also work with IFrames. A special `frame` locator is required to locate the iframe and get into its context.
614
+
599
615
 
600
616
  See example:
601
617
 
@@ -605,7 +621,9 @@ within({frame: "#editor"}, () => {
605
621
  });
606
622
  ```
607
623
 
608
- Nested IFrames can be set by passing array *(WebDriver, Nightmare & Puppeteer only)*:
624
+ > IFrames can also be accessed via `I.switchTo` command of a corresponding helper.
625
+
626
+ Nested IFrames can be set by passing an array *(WebDriver, Nightmare & Puppeteer only)*:
609
627
 
610
628
  ```js
611
629
  within({frame: [".content", "#editor"]}, () => {
@@ -613,11 +631,11 @@ within({frame: [".content", "#editor"]}, () => {
613
631
  });
614
632
  ```
615
633
 
616
- When running steps inside a within block will be shown with a shift:
634
+ When running steps inside, a within block will be shown with a shift:
617
635
 
618
- ![within](https://codecept.io/img/within.png)
636
+ ![within](/img/within.png)
619
637
 
620
- Within can return a value which can be used in a scenario:
638
+ Within can return a value, which can be used in a scenario:
621
639
 
622
640
  ```js
623
641
  // inside async function
@@ -629,8 +647,8 @@ I.fillField('Description', val);
629
647
 
630
648
  ## Comments
631
649
 
632
- There is a simple way to add additional comments to your test scenario.
633
- Use `say` command to print information to screen:
650
+ There is a simple way to add additional comments to your test scenario:
651
+ Use the `say` command to print information to screen:
634
652
 
635
653
  ```js
636
654
  I.say('I am going to publish post');
@@ -638,7 +656,7 @@ I.say('I enter title and body');
638
656
  I.say('I expect post is visible on site');
639
657
  ```
640
658
 
641
- Use second parameter to pass in color value (ASCII).
659
+ Use the second parameter to pass in a color value (ASCII).
642
660
 
643
661
  ```js
644
662
  I.say('This is red', 'red'); //red is used
@@ -651,15 +669,15 @@ I.say('This is by default'); //cyan is used
651
669
 
652
670
  ![](/img/edit.gif)
653
671
 
654
- To get autocompletion when working with CodeceptJS use Visual Studio Code or other IDE that supports TypeScript Definitions.
672
+ To get autocompletion when working with CodeceptJS, use Visual Studio Code or another IDE that supports TypeScript Definitions.
655
673
 
656
- Generate step definitions with
674
+ Generate step definitions with:
657
675
 
658
676
  ```sh
659
677
  npx codeceptjs def
660
678
  ```
661
679
 
662
- Create `jsconfig.json` in your project root directory unless it is already there.
680
+ Create a file called `jsconfig.json` in your project root directory, unless you already have one.
663
681
 
664
682
  ```jsconfig.json
665
683
  {
@@ -675,7 +693,7 @@ to get method autocompletion while writing tests.
675
693
 
676
694
  ## Multiple Sessions
677
695
 
678
- CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a system, for instance in chats. To open another browser use `session()` function as shown in example:
696
+ 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 `session()` function as shown in the example:
679
697
 
680
698
  ```js
681
699
  Scenario('test app', (I) => {
@@ -701,9 +719,9 @@ Scenario('test app', (I) => {
701
719
  });
702
720
  ```
703
721
 
704
- `session` function expects a first parameter to be a name of a session. You can switch back to session by using the same name.
722
+ The `session` function expects the first parameter to be the name of the session. You can switch back to this session by using the same name.
705
723
 
706
- You can override config for session by passing second parameter:
724
+ You can override the configuration for the session by passing a second parameter:
707
725
 
708
726
  ```js
709
727
  session('john', { browser: 'firefox' } , () => {
@@ -712,7 +730,7 @@ session('john', { browser: 'firefox' } , () => {
712
730
  });
713
731
  ```
714
732
 
715
- or just start session without switching to it. Call `session` passing only its name:
733
+ or just start the session without switching to it. Call `session` passing only its name:
716
734
 
717
735
  ```js
718
736
  Scenario('test', (I) => {
@@ -729,7 +747,7 @@ Scenario('test', (I) => {
729
747
  });
730
748
  }
731
749
  ```
732
- `session` can return value which can be used in scenario:
750
+ `session` can return a value which can be used in a scenario:
733
751
 
734
752
  ```js
735
753
  // inside async function
@@ -740,15 +758,41 @@ const val = await session('john', () => {
740
758
  I.fillField('Description', val);
741
759
  ```
742
760
 
743
- Function passed into session can use `I`, page objects, and any objects declared for the scenario.
761
+ Functions passed into a session can use the `I` object, page objects, and any other objects declared for the scenario.
744
762
  This function can also be declared as async (but doesn't work as generator).
745
763
 
746
- Also, you can use `within` inside a session but you can't call session from inside `within`.
764
+ Also, you can use `within` inside a session, but you can't call session from inside `within`.
747
765
 
748
766
 
749
767
  ## Skipping
750
768
 
751
- Like in Mocha you can use `x` and `only` to skip tests or making a single test to run.
769
+ Like in Mocha you can use `x` and `only` to skip tests or to run a single test.
752
770
 
753
771
  * `xScenario` - skips current test
754
772
  * `Scenario.only` - executes only the current test
773
+
774
+ ## Todo Test <Badge text="Since 2.4" type="warning"/>
775
+
776
+ You can use `Scenario.todo` when you are planning on writing tests.
777
+
778
+ This test will be skipped like with regular `Scenario.skip` but with additional message "Test not implemented!":
779
+
780
+ Use it with a test body as a test plan:
781
+
782
+ ```js
783
+ Scenario.todo('Test', I => {
784
+ /**
785
+ * 1. Click to field
786
+ * 2. Fill field
787
+ *
788
+ * Result:
789
+ * 3. Field contains text
790
+ */
791
+ });
792
+ ```
793
+
794
+ Or even without a test body:
795
+
796
+ ```js
797
+ Scenario.todo('Test');
798
+ ```