codeceptjs 3.5.0 → 3.5.1-2.beta.7

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 (273) hide show
  1. package/README.md +24 -25
  2. package/lib/actor.js +6 -3
  3. package/lib/ai.js +12 -3
  4. package/lib/cli.js +12 -2
  5. package/lib/codecept.js +4 -0
  6. package/lib/colorUtils.js +10 -0
  7. package/lib/command/definitions.js +2 -7
  8. package/lib/command/dryRun.js +2 -1
  9. package/lib/command/info.js +24 -0
  10. package/lib/command/init.js +51 -5
  11. package/lib/command/run-multiple/collection.js +17 -5
  12. package/lib/command/run-multiple.js +4 -2
  13. package/lib/command/run-workers.js +66 -4
  14. package/lib/command/run.js +7 -0
  15. package/lib/command/workers/runTests.js +39 -0
  16. package/lib/data/context.js +14 -6
  17. package/lib/event.js +4 -0
  18. package/lib/helper/ApiDataFactory.js +2 -1
  19. package/lib/helper/Appium.js +73 -24
  20. package/lib/helper/Expect.js +422 -0
  21. package/lib/helper/FileSystem.js +1 -1
  22. package/lib/helper/GraphQL.js +25 -0
  23. package/lib/helper/Nightmare.js +9 -4
  24. package/lib/helper/OpenAI.js +14 -10
  25. package/lib/helper/Playwright.js +1205 -288
  26. package/lib/helper/Protractor.js +11 -6
  27. package/lib/helper/Puppeteer.js +173 -61
  28. package/lib/helper/TestCafe.js +44 -9
  29. package/lib/helper/WebDriver.js +231 -82
  30. package/lib/helper/errors/ElementNotFound.js +2 -1
  31. package/lib/helper/extras/PlaywrightReactVueLocator.js +38 -0
  32. package/lib/helper/scripts/blurElement.js +17 -0
  33. package/lib/helper/scripts/focusElement.js +17 -0
  34. package/lib/helper/scripts/highlightElement.js +2 -2
  35. package/lib/html.js +3 -3
  36. package/lib/interfaces/bdd.js +1 -1
  37. package/lib/interfaces/gherkin.js +37 -3
  38. package/lib/interfaces/scenarioConfig.js +1 -0
  39. package/lib/locator.js +17 -4
  40. package/lib/mochaFactory.js +2 -1
  41. package/lib/output.js +1 -1
  42. package/lib/pause.js +12 -9
  43. package/lib/plugin/autoLogin.js +45 -10
  44. package/lib/plugin/heal.js +47 -17
  45. package/lib/plugin/retryFailedStep.js +10 -1
  46. package/lib/plugin/retryTo.js +2 -4
  47. package/lib/plugin/selenoid.js +6 -1
  48. package/lib/plugin/standardActingHelpers.js +0 -2
  49. package/lib/plugin/stepByStepReport.js +2 -2
  50. package/lib/plugin/tryTo.js +5 -7
  51. package/lib/plugin/wdio.js +0 -1
  52. package/lib/recorder.js +20 -9
  53. package/lib/session.js +1 -1
  54. package/lib/step.js +30 -11
  55. package/lib/ui.js +1 -0
  56. package/lib/utils.js +18 -1
  57. package/lib/workers.js +28 -3
  58. package/package.json +108 -98
  59. package/translations/de-DE.js +5 -0
  60. package/translations/fr-FR.js +14 -1
  61. package/translations/it-IT.js +1 -0
  62. package/translations/ja-JP.js +5 -0
  63. package/translations/pl-PL.js +5 -0
  64. package/translations/pt-BR.js +1 -0
  65. package/translations/ru-RU.js +1 -0
  66. package/translations/zh-CN.js +5 -0
  67. package/translations/zh-TW.js +5 -0
  68. package/typings/index.d.ts +8 -6
  69. package/typings/promiseBasedTypes.d.ts +784 -822
  70. package/typings/types.d.ts +1214 -727
  71. package/CHANGELOG.md +0 -2492
  72. package/docs/advanced.md +0 -351
  73. package/docs/ai.md +0 -246
  74. package/docs/api.md +0 -323
  75. package/docs/basics.md +0 -980
  76. package/docs/bdd.md +0 -535
  77. package/docs/best.md +0 -237
  78. package/docs/books.md +0 -37
  79. package/docs/bootstrap.md +0 -135
  80. package/docs/build/ApiDataFactory.js +0 -409
  81. package/docs/build/Appium.js +0 -1978
  82. package/docs/build/FileSystem.js +0 -228
  83. package/docs/build/GraphQL.js +0 -204
  84. package/docs/build/GraphQLDataFactory.js +0 -309
  85. package/docs/build/JSONResponse.js +0 -338
  86. package/docs/build/Mochawesome.js +0 -71
  87. package/docs/build/Nightmare.js +0 -2147
  88. package/docs/build/OpenAI.js +0 -122
  89. package/docs/build/Playwright.js +0 -4134
  90. package/docs/build/Polly.js +0 -42
  91. package/docs/build/Protractor.js +0 -2701
  92. package/docs/build/Puppeteer.js +0 -3743
  93. package/docs/build/REST.js +0 -344
  94. package/docs/build/SeleniumWebdriver.js +0 -76
  95. package/docs/build/TestCafe.js +0 -2059
  96. package/docs/build/WebDriver.js +0 -4042
  97. package/docs/changelog.md +0 -2501
  98. package/docs/commands.md +0 -254
  99. package/docs/community-helpers.md +0 -58
  100. package/docs/configuration.md +0 -157
  101. package/docs/continuous-integration.md +0 -22
  102. package/docs/custom-helpers.md +0 -306
  103. package/docs/data.md +0 -375
  104. package/docs/detox.md +0 -235
  105. package/docs/docker.md +0 -137
  106. package/docs/email.md +0 -183
  107. package/docs/examples.md +0 -149
  108. package/docs/helpers/ApiDataFactory.md +0 -266
  109. package/docs/helpers/Appium.md +0 -1317
  110. package/docs/helpers/Detox.md +0 -586
  111. package/docs/helpers/FileSystem.md +0 -152
  112. package/docs/helpers/GraphQL.md +0 -130
  113. package/docs/helpers/GraphQLDataFactory.md +0 -226
  114. package/docs/helpers/JSONResponse.md +0 -254
  115. package/docs/helpers/Mochawesome.md +0 -8
  116. package/docs/helpers/MockRequest.md +0 -377
  117. package/docs/helpers/Nightmare.md +0 -1258
  118. package/docs/helpers/OpenAI.md +0 -70
  119. package/docs/helpers/Playwright.md +0 -2250
  120. package/docs/helpers/Polly.md +0 -44
  121. package/docs/helpers/Puppeteer-firefox.md +0 -86
  122. package/docs/helpers/Puppeteer.md +0 -2147
  123. package/docs/helpers/REST.md +0 -218
  124. package/docs/helpers/TestCafe.md +0 -1224
  125. package/docs/helpers/WebDriver.md +0 -2325
  126. package/docs/hooks.md +0 -340
  127. package/docs/index.md +0 -111
  128. package/docs/installation.md +0 -75
  129. package/docs/internal-api.md +0 -265
  130. package/docs/locators.md +0 -331
  131. package/docs/mobile-react-native-locators.md +0 -67
  132. package/docs/mobile.md +0 -344
  133. package/docs/nightmare.md +0 -223
  134. package/docs/pageobjects.md +0 -291
  135. package/docs/parallel.md +0 -288
  136. package/docs/playwright.md +0 -609
  137. package/docs/plugins.md +0 -1225
  138. package/docs/puppeteer.md +0 -316
  139. package/docs/quickstart.md +0 -163
  140. package/docs/react.md +0 -69
  141. package/docs/reports.md +0 -392
  142. package/docs/secrets.md +0 -36
  143. package/docs/shadow.md +0 -68
  144. package/docs/shared/keys.mustache +0 -31
  145. package/docs/shared/react.mustache +0 -1
  146. package/docs/testcafe.md +0 -174
  147. package/docs/translation.md +0 -247
  148. package/docs/tutorial.md +0 -271
  149. package/docs/typescript.md +0 -180
  150. package/docs/ui.md +0 -59
  151. package/docs/videos.md +0 -28
  152. package/docs/visual.md +0 -202
  153. package/docs/vue.md +0 -121
  154. package/docs/webapi/amOnPage.mustache +0 -11
  155. package/docs/webapi/appendField.mustache +0 -11
  156. package/docs/webapi/attachFile.mustache +0 -12
  157. package/docs/webapi/checkOption.mustache +0 -13
  158. package/docs/webapi/clearCookie.mustache +0 -10
  159. package/docs/webapi/clearField.mustache +0 -9
  160. package/docs/webapi/click.mustache +0 -25
  161. package/docs/webapi/clickLink.mustache +0 -8
  162. package/docs/webapi/closeCurrentTab.mustache +0 -7
  163. package/docs/webapi/closeOtherTabs.mustache +0 -8
  164. package/docs/webapi/dontSee.mustache +0 -11
  165. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +0 -10
  166. package/docs/webapi/dontSeeCookie.mustache +0 -8
  167. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +0 -10
  168. package/docs/webapi/dontSeeElement.mustache +0 -8
  169. package/docs/webapi/dontSeeElementInDOM.mustache +0 -8
  170. package/docs/webapi/dontSeeInCurrentUrl.mustache +0 -4
  171. package/docs/webapi/dontSeeInField.mustache +0 -11
  172. package/docs/webapi/dontSeeInSource.mustache +0 -8
  173. package/docs/webapi/dontSeeInTitle.mustache +0 -8
  174. package/docs/webapi/doubleClick.mustache +0 -13
  175. package/docs/webapi/downloadFile.mustache +0 -12
  176. package/docs/webapi/dragAndDrop.mustache +0 -9
  177. package/docs/webapi/dragSlider.mustache +0 -11
  178. package/docs/webapi/executeAsyncScript.mustache +0 -24
  179. package/docs/webapi/executeScript.mustache +0 -26
  180. package/docs/webapi/fillField.mustache +0 -16
  181. package/docs/webapi/forceClick.mustache +0 -28
  182. package/docs/webapi/forceRightClick.mustache +0 -18
  183. package/docs/webapi/grabAllWindowHandles.mustache +0 -7
  184. package/docs/webapi/grabAttributeFrom.mustache +0 -10
  185. package/docs/webapi/grabAttributeFromAll.mustache +0 -9
  186. package/docs/webapi/grabBrowserLogs.mustache +0 -9
  187. package/docs/webapi/grabCookie.mustache +0 -11
  188. package/docs/webapi/grabCssPropertyFrom.mustache +0 -11
  189. package/docs/webapi/grabCssPropertyFromAll.mustache +0 -10
  190. package/docs/webapi/grabCurrentUrl.mustache +0 -9
  191. package/docs/webapi/grabCurrentWindowHandle.mustache +0 -6
  192. package/docs/webapi/grabDataFromPerformanceTiming.mustache +0 -20
  193. package/docs/webapi/grabElementBoundingRect.mustache +0 -20
  194. package/docs/webapi/grabGeoLocation.mustache +0 -8
  195. package/docs/webapi/grabHTMLFrom.mustache +0 -10
  196. package/docs/webapi/grabHTMLFromAll.mustache +0 -9
  197. package/docs/webapi/grabNumberOfOpenTabs.mustache +0 -8
  198. package/docs/webapi/grabNumberOfVisibleElements.mustache +0 -9
  199. package/docs/webapi/grabPageScrollPosition.mustache +0 -8
  200. package/docs/webapi/grabPopupText.mustache +0 -5
  201. package/docs/webapi/grabSource.mustache +0 -8
  202. package/docs/webapi/grabTextFrom.mustache +0 -10
  203. package/docs/webapi/grabTextFromAll.mustache +0 -9
  204. package/docs/webapi/grabTitle.mustache +0 -8
  205. package/docs/webapi/grabValueFrom.mustache +0 -9
  206. package/docs/webapi/grabValueFromAll.mustache +0 -8
  207. package/docs/webapi/moveCursorTo.mustache +0 -12
  208. package/docs/webapi/openNewTab.mustache +0 -7
  209. package/docs/webapi/pressKey.mustache +0 -12
  210. package/docs/webapi/pressKeyDown.mustache +0 -12
  211. package/docs/webapi/pressKeyUp.mustache +0 -12
  212. package/docs/webapi/pressKeyWithKeyNormalization.mustache +0 -60
  213. package/docs/webapi/refreshPage.mustache +0 -6
  214. package/docs/webapi/resizeWindow.mustache +0 -6
  215. package/docs/webapi/rightClick.mustache +0 -14
  216. package/docs/webapi/saveElementScreenshot.mustache +0 -10
  217. package/docs/webapi/saveScreenshot.mustache +0 -12
  218. package/docs/webapi/say.mustache +0 -10
  219. package/docs/webapi/scrollIntoView.mustache +0 -11
  220. package/docs/webapi/scrollPageToBottom.mustache +0 -6
  221. package/docs/webapi/scrollPageToTop.mustache +0 -6
  222. package/docs/webapi/scrollTo.mustache +0 -12
  223. package/docs/webapi/see.mustache +0 -11
  224. package/docs/webapi/seeAttributesOnElements.mustache +0 -9
  225. package/docs/webapi/seeCheckboxIsChecked.mustache +0 -10
  226. package/docs/webapi/seeCookie.mustache +0 -8
  227. package/docs/webapi/seeCssPropertiesOnElements.mustache +0 -9
  228. package/docs/webapi/seeCurrentUrlEquals.mustache +0 -11
  229. package/docs/webapi/seeElement.mustache +0 -8
  230. package/docs/webapi/seeElementInDOM.mustache +0 -8
  231. package/docs/webapi/seeInCurrentUrl.mustache +0 -8
  232. package/docs/webapi/seeInField.mustache +0 -12
  233. package/docs/webapi/seeInPopup.mustache +0 -8
  234. package/docs/webapi/seeInSource.mustache +0 -7
  235. package/docs/webapi/seeInTitle.mustache +0 -8
  236. package/docs/webapi/seeNumberOfElements.mustache +0 -11
  237. package/docs/webapi/seeNumberOfVisibleElements.mustache +0 -10
  238. package/docs/webapi/seeTextEquals.mustache +0 -9
  239. package/docs/webapi/seeTitleEquals.mustache +0 -8
  240. package/docs/webapi/selectOption.mustache +0 -21
  241. package/docs/webapi/setCookie.mustache +0 -16
  242. package/docs/webapi/setGeoLocation.mustache +0 -12
  243. package/docs/webapi/switchTo.mustache +0 -9
  244. package/docs/webapi/switchToNextTab.mustache +0 -10
  245. package/docs/webapi/switchToPreviousTab.mustache +0 -10
  246. package/docs/webapi/type.mustache +0 -21
  247. package/docs/webapi/uncheckOption.mustache +0 -13
  248. package/docs/webapi/wait.mustache +0 -8
  249. package/docs/webapi/waitForClickable.mustache +0 -11
  250. package/docs/webapi/waitForDetached.mustache +0 -10
  251. package/docs/webapi/waitForElement.mustache +0 -11
  252. package/docs/webapi/waitForEnabled.mustache +0 -6
  253. package/docs/webapi/waitForFunction.mustache +0 -17
  254. package/docs/webapi/waitForInvisible.mustache +0 -10
  255. package/docs/webapi/waitForText.mustache +0 -13
  256. package/docs/webapi/waitForValue.mustache +0 -10
  257. package/docs/webapi/waitForVisible.mustache +0 -10
  258. package/docs/webapi/waitInUrl.mustache +0 -9
  259. package/docs/webapi/waitNumberOfVisibleElements.mustache +0 -10
  260. package/docs/webapi/waitToHide.mustache +0 -10
  261. package/docs/webapi/waitUrlEquals.mustache +0 -10
  262. package/docs/webdriver.md +0 -657
  263. package/docs/wiki/Books-&-Posts.md +0 -27
  264. package/docs/wiki/Community-Helpers-&-Plugins.md +0 -49
  265. package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +0 -29
  266. package/docs/wiki/Examples.md +0 -139
  267. package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +0 -68
  268. package/docs/wiki/Home.md +0 -16
  269. package/docs/wiki/Release-Process.md +0 -24
  270. package/docs/wiki/Roadmap.md +0 -23
  271. package/docs/wiki/Tests.md +0 -1393
  272. package/docs/wiki/Upgrading-to-CodeceptJS-3.md +0 -153
  273. package/docs/wiki/Videos.md +0 -19
package/docs/basics.md DELETED
@@ -1,980 +0,0 @@
1
- ---
2
- permalink: /basics
3
- title: Getting Started
4
- ---
5
-
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.
9
-
10
- ```js
11
- Feature('CodeceptJS demo');
12
-
13
- Scenario('check Welcome page on site', ({ I }) => {
14
- I.amOnPage('/');
15
- I.see('Welcome');
16
- });
17
- ```
18
-
19
- Tests are expected to be written in **ECMAScript 7**.
20
-
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**.
23
-
24
- ## Architecture
25
-
26
- CodeceptJS bypasses execution commands to helpers. Depending on the helper enabled, your tests will be executed differently.
27
-
28
- The following is a diagram of the CodeceptJS architecture:
29
-
30
- ![architecture](/img/architecture.png)
31
-
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 but you can do so in Playwright or Puppeteer.
34
-
35
- **Pick one helper, as it defines how tests are executed.** If requirements change it's easy to migrate to another.
36
-
37
- ---
38
-
39
- Refer to following guides to more information on:
40
-
41
- * [▶ Playwright](/playwright)
42
- * [▶ WebDriver](/webdriver)
43
- * [▶ Puppeteer](/puppeteer)
44
- * [▶ Nightmare](/nightmare)
45
- * [▶ TestCafe](/testcafe)
46
-
47
- > ℹ Depending on a helper selected a list of available actions may change.
48
-
49
- To list all available commands for the current configuration run `codeceptjs list`
50
- or enable [auto-completion by generating TypeScript definitions](#intellisense).
51
-
52
- > 🤔 It is possible to access API of a backend you use inside a test or a [custom helper](/helpers/). For instance, to use Puppeteer API inside a test use [`I.usePuppeteerTo`](/helpers/Puppeteer/#usepuppeteerto) inside a test. Similar methods exist for each helper.
53
-
54
-
55
- ## Writing Tests
56
-
57
- 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:
58
-
59
- ```js
60
- I.amOnPage('/');
61
- I.click('Login');
62
- I.see('Please Login', 'h1');
63
- // ...
64
- ```
65
-
66
- ### Opening a Page
67
-
68
- A test should usually start by navigating the browser to a website.
69
-
70
- Start a test by opening a page. Use the `I.amOnPage()` command for this:
71
-
72
- ```js
73
- // When "http://site.com" is url in config
74
- I.amOnPage('/'); // -> opens http://site.com/
75
- I.amOnPage('/about'); // -> opens http://site.com/about
76
- I.amOnPage('https://google.com'); // -> https://google.com
77
- ```
78
-
79
- 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.
80
-
81
- > 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.
82
-
83
-
84
- ### Locating Element
85
-
86
- Element can be found by CSS or XPath locators.
87
-
88
- ```js
89
- I.seeElement('.user'); // element with CSS class user
90
- I.seeElement('//button[contains(., "press me")]'); // button
91
- ```
92
-
93
- By default CodeceptJS tries to guess the locator type.
94
- In order to specify the exact locator type you can pass an object called **strict locator**.
95
-
96
- ```js
97
- I.seeElement({css: 'div.user'});
98
- I.seeElement({xpath: '//div[@class=user]'});
99
- ```
100
-
101
- Strict locators allow to specify additional locator types:
102
-
103
- ```js
104
- // locate form element by name
105
- I.seeElement({name: 'password'});
106
- // locate element by React component and props
107
- I.seeElement({react: 'user-profile', props: {name: 'davert'}});
108
- ```
109
-
110
- In [mobile testing](https://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.
111
-
112
- ```js
113
- // locate element by [aria-label] attribute in web
114
- // or by accessibility id in mobile
115
- I.seeElement('~username');
116
- ```
117
-
118
- > [▶ Learn more about using locators in CodeceptJS](/locators).
119
-
120
- ### Clicking
121
-
122
- CodeceptJS provides a flexible syntax to specify an element to click.
123
-
124
- By default CodeceptJS tries to find the button or link with the exact text on it
125
-
126
- ```js
127
- // search for link or button
128
- I.click('Login');
129
- ```
130
-
131
- 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.
132
-
133
- To narrow down the results you can specify a context in the second parameter.
134
-
135
- ```js
136
- I.click('Login', '.nav'); // search only in .nav
137
- I.click('Login', {css: 'footer'}); // search only in footer
138
- ```
139
-
140
- > 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.
141
-
142
- You are not limited to buttons and links. Any element can be found by passing in valid CSS or XPath:
143
-
144
- ```js
145
- // click element by CSS
146
- I.click('#signup');
147
- // click element located by special test-id attribute
148
- I.click('//dev[@test-id="myid"]');
149
- ```
150
-
151
- > ℹ 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 `forceClick` 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.
152
-
153
- ### Filling Fields
154
-
155
- 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.
156
-
157
- Let's submit this sample form for a test:
158
-
159
- ![](https://user-images.githubusercontent.com/220264/80355863-494a8280-8881-11ea-9b41-ba1f07abf094.png)
160
-
161
- ```html
162
- <form method="post" action="/update" id="update_form">
163
- <label for="user_name">Name</label>
164
- <input type="text" name="user[name]" id="user_name" /><br>
165
- <label for="user_email">Email</label>
166
- <input type="text" name="user[email]" id="user_email" /><br>
167
- <label for="user_role">Role</label>
168
- <select id="user_role" name="user[role]">
169
- <option value="0">Admin</option>
170
- <option value="1">User</option>
171
- </select><br>
172
- <input type="checkbox" id="accept" /> <label for="accept">Accept changes</label>
173
- <div>
174
- <input type="submit" name="submitButton" class="btn btn-primary" value="Save" />
175
- </div>
176
- </form>
177
- ```
178
-
179
- 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.
180
-
181
- ```js
182
- // we are using label to match user_name field
183
- I.fillField('Name', 'Miles');
184
- // we can use input name
185
- I.fillField('user[email]','miles@davis.com');
186
- // select element by label, choose option by text
187
- I.selectOption('Role','Admin');
188
- // click 'Save' button, found by text
189
- I.checkOption('Accept');
190
- I.click('Save');
191
- ```
192
-
193
- > ℹ `selectOption` works only with standard `<select>` <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 `click` to manipulate it.
194
-
195
- > ℹ `checkOption` also works only with standard `<input type="checkbox">` <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 `click` to manipulate it.
196
-
197
- Alternative scenario:
198
-
199
- ```js
200
- // we are using CSS
201
- I.fillField('#user_name', 'Miles');
202
- I.fillField('#user_email','miles@davis.com');
203
- // select element by label, option by value
204
- I.selectOption('#user_role','1');
205
- // click 'Update' button, found by name
206
- I.click('submitButton', '#update_form');
207
- ```
208
-
209
- To fill in sensitive data use the `secret` function, it won't expose actual value in logs.
210
-
211
- ```js
212
- I.fillField('password', secret('123456'));
213
- ```
214
-
215
- > ℹ️ Learn more about [masking secret](/secrets/) output
216
-
217
- ### Assertions
218
-
219
- In order to verify the expected behavior of a web application, its content should be checked.
220
- CodeceptJS provides built-in assertions for that. They start with a `see` (or `dontSee`) prefix.
221
-
222
- The most general and common assertion is `see`, which checks visilibility of a text on a page:
223
-
224
- ```js
225
- // Just a visible text on a page
226
- I.see('Hello');
227
- // text inside .msg element
228
- I.see('Hello', '.msg');
229
- // opposite
230
- I.dontSee('Bye');
231
- ```
232
-
233
- You should provide a text as first argument and, optionally, a locator to search for a text in a context.
234
-
235
- You can check that specific element exists (or not) on a page, as it was described in [Locating Element](#locating-element) section.
236
-
237
- ```js
238
- I.seeElement('.notice');
239
- I.dontSeeElement('.error');
240
- ```
241
-
242
- Additional assertions:
243
-
244
- ```js
245
- I.seeInCurrentUrl('/user/miles');
246
- I.seeInField('user[name]', 'Miles');
247
- I.seeInTitle('My Website');
248
- ```
249
-
250
- To see all possible assertions, check the helper's reference.
251
-
252
- > ℹ If you need custom assertions, you can install an assertion libarary like `chai`, 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.
253
-
254
- ### Grabbing
255
-
256
- Sometimes you need to retrieve data from a page to use it in the following steps of a scenario.
257
- Imagine the application generates a password, and you want to ensure that user can login using this password.
258
-
259
- ```js
260
- Scenario('login with generated password', async ({ I }) => {
261
- I.fillField('email', 'miles@davis.com');
262
- I.click('Generate Password');
263
- const password = await I.grabTextFrom('#password');
264
- I.click('Login');
265
- I.fillField('email', 'miles@davis.com');
266
- I.fillField('password', password);
267
- I.click('Log in!');
268
- I.see('Hello, Miles');
269
- });
270
- ```
271
-
272
- 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).
273
-
274
- ```js
275
- Scenario('use page title', async ({ I }) => {
276
- // ...
277
- const password = await I.grabTextFrom('#password');
278
- I.fillField('password', password);
279
- });
280
- ```
281
-
282
- ### Waiting
283
-
284
- In modern web applications, rendering is done on the client-side.
285
- Sometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet.
286
- To handle these cases, the `wait*` methods has been introduced.
287
-
288
- ```js
289
- I.waitForElement('#agree_button', 30); // secs
290
- // clicks a button only when it is visible
291
- I.click('#agree_button');
292
- ```
293
-
294
- ## How It Works
295
-
296
- Tests are written in a synchronous way. This improves the readability and maintainability of tests.
297
- While writing tests you should not think about promises, and instead should focus on the test scenario.
298
-
299
- However, behind the scenes **all actions are wrapped in promises**, inside of the `I` object.
300
- [Global promise](https://github.com/codeceptjs/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.
301
-
302
- > 📺 [Learn how CodeceptJS](https://www.youtube.com/watch?v=MDLLpHAwy_s) works with promises by watching video on YouTube
303
-
304
- 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.
305
-
306
- ```js
307
- Scenario('try grabbers', async ({ I }) => {
308
- let title = await I.grabTitle();
309
- });
310
- ```
311
-
312
- then you can use those variables in assertions:
313
-
314
- ```js
315
- var title = await I.grabTitle();
316
- var assert = require('assert');
317
- assert.equal(title, 'CodeceptJS');
318
- ```
319
-
320
- It is important to understand the usage of **async** functions in CodeceptJS. While non-returning actions can be called without await, if an async function uses `grab*` action it must be called with `await`:
321
-
322
- ```js
323
- // a helper function
324
- async function getAllUsers(I) {
325
- const users = await I.grabTextFrom('.users');
326
- return users.filter(u => u.includes('active'))
327
- }
328
-
329
- // a test
330
- Scenario('try helper functions', async ({ I }) => {
331
- // we call function with await because it includes `grab`
332
- const users = await getAllUsers(I);
333
- });
334
- ```
335
-
336
- If you miss `await` you get commands unsynchrhonized. And this will result to an error like this:
337
-
338
- ```
339
- (node:446390) UnhandledPromiseRejectionWarning: ...
340
- at processTicksAndRejections (internal/process/task_queues.js:95:5)
341
- (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)
342
- ```
343
-
344
- If you face that error please make sure that all async functions are called with `await`.
345
-
346
- ## Running Tests
347
-
348
- To launch tests use the `run` command, and to execute tests in [multiple threads](/advanced/parallel) using `run-workers` command.
349
-
350
- ### Level of Detail
351
-
352
- To see the step-by-step output of running tests, add the `--steps` flag:
353
-
354
- ```
355
- npx codeceptjs run --steps
356
- ```
357
-
358
- To see a more detailed output add the `--debug` flag:
359
-
360
- ```
361
- npx codeceptjs run --debug
362
- ```
363
-
364
- To see very detailed output informations use the `--verbose` flag:
365
-
366
- ```
367
- npx codeceptjs run --verbose
368
- ```
369
-
370
- ### Filter
371
-
372
- A single test file can be executed if you provide a relative path to such a file:
373
-
374
- ```
375
- npx codeceptjs run github_test.js
376
-
377
- # or
378
-
379
- npx codeceptjs run admin/login_test.js
380
- ```
381
-
382
- To filter a test by name use the `--grep` parameter, which will execute all tests with names matching the regex pattern.
383
-
384
- To run all tests with the `slow` word in it:
385
-
386
- ```
387
- npx codeceptjs run --grep "slow"
388
- ```
389
-
390
- It is recommended to [filter tests by tags](/advanced/#tags).
391
-
392
-
393
- > For more options see [full reference of `run` command](/commands/#run).
394
-
395
- ### Parallel Run
396
-
397
- Tests can be executed in parallel mode by using [NodeJS workers](https://nodejs.org/api/worker_threads.html). Use `run-workers` command with the number of workers (threads) to split tests into different workers.
398
-
399
- ```
400
- npx codeceptjs run-workers 3
401
- ```
402
-
403
- Tests are split by scenarios, not by files. Results are aggregated and shown up in the main process.
404
-
405
- ## Configuration
406
-
407
- Configuration is set in the `codecept.conf.js` file which was created during the `init` process.
408
- Inside the config file you can enable and configure helpers and plugins, and set bootstrap and teardown scripts.
409
-
410
- ```js
411
- exports.config = {
412
- helpers: {
413
- // enabled helpers with their configs
414
- },
415
- plugins: {
416
- // list of used plugins
417
- },
418
- include: {
419
- // current actor and page objects
420
- }
421
- }
422
- ```
423
-
424
- > ▶ See complete [configuration reference](/configuration).
425
-
426
- 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.
427
-
428
- ```
429
- npx codeceptjs run -c codecept.ci.conf.js
430
- ```
431
-
432
- 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/codeceptjs/configure) package with common configuration recipes.
433
-
434
- For instance, you can set the window size or toggle headless mode, no matter of which helpers are actually used.
435
-
436
- ```js
437
- const { setHeadlessWhen, setWindowSize } = require('@codeceptjs/configure');
438
-
439
- // run headless when CI environment variable set
440
- setHeadlessWhen(process.env.CI);
441
- // set window size for any helper: Puppeteer, WebDriver, TestCafe
442
- setWindowSize(1600, 1200);
443
-
444
- exports.config = {
445
- // ...
446
- }
447
- ```
448
-
449
- > ▶ See more [configuration recipes](https://github.com/codeceptjs/configure)
450
-
451
- ## Debug
452
-
453
- CodeceptJS allows to write and debug tests on the fly while keeping your browser opened.
454
- By using the interactive shell you can stop execution at any point and type in any CodeceptJS commands.
455
-
456
- This is especially useful while writing a new scratch. After opening a page call `pause()` to start interacting with a page:
457
-
458
- ```js
459
- I.amOnPage('/');
460
- pause();
461
- ```
462
-
463
- Try to perform your scenario step by step. Then copy succesful commands and insert them into a test.
464
-
465
- ### Pause
466
-
467
- Test execution can be paused in any place of a test with `pause()` call.
468
- Variables can also be passed to `pause({data: 'hi', func: () => console.log('hello')})` which can be accessed in Interactive shell.
469
-
470
- This launches the interactive console where you can call any action from the `I` object.
471
-
472
- ```
473
- Interactive shell started
474
- Press ENTER to resume test
475
- Use JavaScript syntax to try steps in action
476
- - Press ENTER to run the next step
477
- - Press TAB twice to see all available commands
478
- - Type exit + Enter to exit the interactive shell
479
- - Prefix => to run js commands
480
- I.
481
- ```
482
-
483
- Type in different actions to try them, copy and paste successful ones into the test file.
484
-
485
- Press `ENTER` to resume test execution.
486
-
487
- To **debug test step-by-step** press Enter, the next step will be executed and interactive shell will be shown again.
488
-
489
- To see all available commands, press TAB two times to see list of all actions included in the `I` object.
490
-
491
- > The interactive shell can be started outside of test context by running `npx codeceptjs shell`
492
-
493
- PageObjects and other variables can also be passed to as object:
494
-
495
- ```js
496
- pause({ loginPage, data: 'hi', func: () => console.log('hello') });
497
- ```
498
-
499
- Inside a pause mode you can use `loginPage`, `data`, `func` variables.
500
- Arbitrary JavaScript code can be executed when used `=> ` prefix:
501
-
502
- ```js
503
- I.=> loginPage.open()
504
- I.=> func()
505
- I.=> 2 + 5
506
- ```
507
-
508
- ### Pause on Fail
509
-
510
- To start interactive pause automatically for a failing test you can run tests with [pauseOnFail Plugin](/plugins/#pauseonfail).
511
- When a test fails, the pause mode will be activated, so you can inspect current browser session before it is closed.
512
-
513
- > **[pauseOnFail plugin](/plugins/#pauseOnFail) can be used** for new setups
514
-
515
- To run tests with pause on fail enabled use `-p pauseOnFail` option
516
-
517
- ```
518
- npx codeceptjs run -p pauseOnFail
519
- ```
520
-
521
- > To enable pause after a test without a plugin you can use `After(pause)` inside a test file.
522
-
523
-
524
- ### Screenshot on Failure
525
-
526
- By default CodeceptJS saves a screenshot of a failed test.
527
- This can be configured in [screenshotOnFail Plugin](/plugins/#screenshotonfail)
528
-
529
- > **[screenshotOnFail plugin](/plugins/#screenshotonfail) is enabled by default** for new setups
530
-
531
- ### Step By Step Report
532
-
533
- 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.
534
-
535
- ## Before
536
-
537
- Common preparation steps like opening a web page or logging in a user, can be placed in the `Before` or `Background` hooks:
538
-
539
- ```js
540
- Feature('CodeceptJS Demonstration');
541
-
542
- Before(({ I }) => { // or Background
543
- I.amOnPage('/documentation');
544
- });
545
-
546
- Scenario('test some forms', ({ I }) => {
547
- I.click('Create User');
548
- I.see('User is valid');
549
- I.dontSeeInCurrentUrl('/documentation');
550
- });
551
-
552
- Scenario('test title', ({ I }) => {
553
- I.seeInTitle('Example application');
554
- });
555
- ```
556
-
557
- Same as `Before` you can use `After` to run teardown for each scenario.
558
-
559
- ## BeforeSuite
560
-
561
- 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.
562
- `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.
563
- 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)
564
-
565
- ```js
566
- BeforeSuite(({ I }) => {
567
- I.syncDown('testfolder');
568
- });
569
-
570
- AfterSuite(({ I }) => {
571
- I.syncUp('testfolder');
572
- I.clearDir('testfolder');
573
- });
574
- ```
575
-
576
- ## Retries
577
-
578
- ### Auto Retry
579
-
580
- Each failed step is auto-retried by default via [retryFailedStep Plugin](/plugins/#retryfailedstep).
581
- If this is not expected, this plugin can be disabled in a config.
582
-
583
- > **[retryFailedStep plugin](/plugins/#retryfailedstep) is enabled by default** incide global configuration
584
-
585
- ### Retry Step
586
-
587
- Unless you use retryFailedStep plugin you can manually control retries in your project.
588
-
589
- If you have a step which often fails, you can retry execution for this single step.
590
- Use the `retry()` function before an action to ask CodeceptJS to retry it on failure:
591
-
592
- ```js
593
- I.retry().see('Welcome');
594
- ```
595
-
596
- If you'd like to retry a step more than once, pass the amount as a parameter:
597
-
598
- ```js
599
- I.retry(3).see('Welcome');
600
- ```
601
-
602
- 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).
603
-
604
-
605
- ```js
606
- // retry action 3 times waiting for 0.1 second before next try
607
- I.retry({ retries: 3, minTimeout: 100 }).see('Hello');
608
-
609
- // retry action 3 times waiting no more than 3 seconds for last retry
610
- I.retry({ retries: 3, maxTimeout: 3000 }).see('Hello');
611
-
612
- // retry 2 times if error with message 'Node not visible' happens
613
- I.retry({
614
- retries: 2,
615
- when: err => err.message === 'Node not visible'
616
- }).seeElement('#user');
617
- ```
618
-
619
- Pass a function to the `when` option to retry only when an error matches the expected one.
620
-
621
- ### Retry Multiple Steps
622
-
623
- To retry a group of steps enable [retryTo plugin](/plugins/#retryto):
624
-
625
- ```js
626
- // retry these steps 5 times before failing
627
- await retryTo((tryNum) => {
628
- I.switchTo('#editor frame');
629
- I.click('Open');
630
- I.see('Opened')
631
- }, 5);
632
- ```
633
-
634
- ### Retry Scenario
635
-
636
- When you need to rerun scenarios a few times, add the `retries` option to the `Scenario` declaration.
637
-
638
- CodeceptJS implements retries the same way [Mocha does](https://mochajs.org#retry-tests);
639
- You can set the number of a retries for a feature:
640
-
641
- ```js
642
- Scenario('Really complex', ({ I }) => {
643
- // test goes here
644
- }).retry(2);
645
-
646
- // alternative
647
- Scenario('Really complex', { retries: 2 },({ I }) => {});
648
- ```
649
-
650
- This scenario will be restarted two times on a failure.
651
- Unlike retry step, there is no `when` condition supported for retries on a scenario level.
652
-
653
- ### Retry Before <Badge text="Since 3.4" type="warning"/>
654
-
655
- To retry `Before`, `BeforeSuite`, `After`, `AfterSuite` hooks, add corresponding option to a `Feature`:
656
-
657
- * `retryBefore`
658
- * `retryBeforeSuite`
659
- * `retryAfter`
660
- * `retryAfterSuite`
661
-
662
- For instance, to retry Before hook 3 times:
663
-
664
- ```js
665
- Feature('this have a flaky Befure', { retryBefore: 3 })
666
- ```
667
-
668
- Multiple options of different values can be set at the same time
669
-
670
- ### Retry Feature
671
-
672
- To set this option for all scenarios in a file, add `retry` to a feature:
673
-
674
- ```js
675
- Feature('Complex JS Stuff').retry(3);
676
- // or
677
- Feature('Complex JS Stuff', { retries: 3 })
678
- ```
679
-
680
- Every Scenario inside this feature will be rerun 3 times.
681
- You can make an exception for a specific scenario by passing the `retries` option to a Scenario.
682
-
683
- ### Retry Configuration <Badge text="Since 3.4" type="warning"/>
684
-
685
- It is possible to set retry rules globally via `retry` config option. The configuration is flexible and allows multiple formats.
686
- The simplest config would be:
687
-
688
- ```js
689
- // inside codecept.conf.js
690
- retry: 3
691
- ```
692
-
693
- This will enable Feature Retry for all executed feature, retrying failing tests 3 times.
694
-
695
- An object can be used to tune retries of a Before/After hook, Scenario or Feature
696
-
697
- ```js
698
- // inside codecept.conf.js
699
- retry: {
700
- Feature: ...,
701
- Scenario: ...,
702
- Before: ...,
703
- BeforeSuite: ...,
704
- After: ...,
705
- AfterSuite: ...,
706
- }
707
- ```
708
-
709
- Multiple retry configs can be added via array. To use different retry configs for different subset of tests use `grep` option inside a retry config:
710
-
711
- ```js
712
- // inside codecept.conf.js
713
- retry: [
714
- {
715
- // enable this config only for flaky tests
716
- grep: '@flaky',
717
- Before: 3
718
- Scenario: 3
719
- },
720
- {
721
- // retry less when running slow tests
722
- grep: '@slow'
723
- Scenario: 1
724
- Before: 1
725
- }, {
726
- // retry all BeforeSuite
727
- BeforeSuite: 3
728
- }
729
- ]
730
- ```
731
-
732
- When using `grep` with `Before`, `After`, `BeforeSuite`, `AfterSuite`, a suite title will be checked for included value.
733
-
734
- > ℹ️ `grep` value can be string or regexp
735
-
736
- 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.
737
-
738
- ### Retry Run
739
-
740
- On the highest level of the "retry pyramid" there is an option to retry a complete run multiple times.
741
- Even this is the slowest option of all, it can be helpful to detect flaky tests.
742
-
743
- [`run-rerun`](https://codecept.io/commands/#run-rerun) command will restart the run multiple times to values you provide. You can set minimal and maximal number of restarts in configuration file.
744
-
745
- ```
746
- npx codeceptjs run-rerun
747
- ```
748
-
749
-
750
- [Here are some ideas](https://github.com/codeceptjs/CodeceptJS/pull/231#issuecomment-249554933) on where to use BeforeSuite hooks.
751
-
752
- ## Within
753
-
754
- To specify the exact area on a page where actions can be performed you can use the `within` function.
755
- Everything executed in its context will be narrowed to context specified by locator:
756
-
757
- Usage: `within('section', ()=>{})`
758
-
759
- ```js
760
- I.amOnPage('https://github.com');
761
- within('.js-signup-form', () => {
762
- I.fillField('user[login]', 'User');
763
- I.fillField('user[email]', 'user@user.com');
764
- I.fillField('user[password]', 'user@user.com');
765
- I.click('button');
766
- });
767
- I.see('There were problems creating your account.');
768
- ```
769
-
770
- > ⚠ `within` can cause problems when used incorrectly. If you see a weird behavior of a test try to refactor it to not use `within`. It is recommended to keep within for simplest cases when possible.
771
- > Since `within` returns a Promise, it may be necessary to `await` the result even when you're not intending to use the return value.
772
-
773
- `within` can also work with IFrames. A special `frame` locator is required to locate the iframe and get into its context.
774
-
775
-
776
- See example:
777
-
778
- ```js
779
- within({frame: "#editor"}, () => {
780
- I.see('Page');
781
- });
782
- ```
783
-
784
- > ℹ IFrames can also be accessed via `I.switchTo` command of a corresponding helper.
785
-
786
- Nested IFrames can be set by passing an array *(WebDriver, Nightmare & Puppeteer only)*:
787
-
788
- ```js
789
- within({frame: [".content", "#editor"]}, () => {
790
- I.see('Page');
791
- });
792
- ```
793
-
794
- When running steps inside, a within block will be shown with a shift:
795
-
796
- ![within](/img/within.png)
797
-
798
- Within can return a value, which can be used in a scenario:
799
-
800
- ```js
801
- // inside async function
802
- const val = await within('#sidebar', () => {
803
- return I.grabTextFrom({ css: 'h1' });
804
- });
805
- I.fillField('Description', val);
806
- ```
807
-
808
- ## Conditional Actions
809
-
810
- There is a way to execute unsuccessful actions to without failing a test.
811
- This might be useful when you might need to click "Accept cookie" button but probably cookies were already accepted.
812
- To handle these cases `tryTo` function was introduced:
813
-
814
- ```js
815
- tryTo(() => I.click('Accept', '.cookies'));
816
- ```
817
-
818
- You may also use `tryTo` for cases when you deal with uncertainty on page:
819
-
820
- * A/B testing
821
- * soft assertions
822
- * cookies & gdpr
823
-
824
- `tryTo` function is enabled by default via [tryTo plugin](/plugins/#tryto)
825
-
826
- ## Comments
827
-
828
- There is a simple way to add additional comments to your test scenario:
829
- Use the `say` command to print information to screen:
830
-
831
- ```js
832
- I.say('I am going to publish post');
833
- I.say('I enter title and body');
834
- I.say('I expect post is visible on site');
835
- ```
836
-
837
- Use the second parameter to pass in a color value (ASCII).
838
-
839
- ```js
840
- I.say('This is red', 'red'); //red is used
841
- I.say('This is blue', 'blue'); //blue is used
842
- I.say('This is by default'); //cyan is used
843
- ```
844
-
845
-
846
- ## IntelliSense
847
-
848
- ![Edit](/img/edit.gif)
849
-
850
- To get autocompletion when working with CodeceptJS, use Visual Studio Code or another IDE that supports TypeScript Definitions.
851
-
852
- Generate step definitions with:
853
-
854
- ```sh
855
- npx codeceptjs def
856
- ```
857
-
858
- Create a file called `jsconfig.json` in your project root directory, unless you already have one.
859
-
860
- ```jsconfig.json
861
- {
862
- "compilerOptions": {
863
- "allowJs": true,
864
- }
865
- }
866
- ```
867
-
868
- Alternatively, you can include `/// <reference path="./steps.d.ts" />` into your test files
869
- to get method autocompletion while writing tests.
870
-
871
-
872
- ## Multiple Sessions
873
-
874
- 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:
875
-
876
- ```js
877
- Scenario('test app', ({ I }) => {
878
- I.amOnPage('/chat');
879
- I.fillField('name', 'davert');
880
- I.click('Sign In');
881
- I.see('Hello, davert');
882
- session('john', () => {
883
- // another session started
884
- I.amOnPage('/chat');
885
- I.fillField('name', 'john');
886
- I.click('Sign In');
887
- I.see('Hello, john');
888
- });
889
- // switching back to default session
890
- I.fillField('message', 'Hi, john');
891
- // there is a message from current user
892
- I.see('me: Hi, john', '.messages');
893
- session('john', () => {
894
- // let's check if john received it
895
- I.see('davert: Hi, john', '.messages');
896
- });
897
- });
898
- ```
899
-
900
- 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.
901
-
902
- You can override the configuration for the session by passing a second parameter:
903
-
904
- ```js
905
- session('john', { browser: 'firefox' } , () => {
906
- // run this steps in firefox
907
- I.amOnPage('/');
908
- });
909
- ```
910
-
911
- or just start the session without switching to it. Call `session` passing only its name:
912
-
913
- ```js
914
- Scenario('test', ({ I }) => {
915
- // opens 3 additional browsers
916
- session('john');
917
- session('mary');
918
- session('jane');
919
-
920
- I.amOnPage('/');
921
-
922
- // switch to session by its name
923
- session('mary', () => {
924
- I.amOnPage('/login');
925
- });
926
- }
927
- ```
928
- `session` can return a value which can be used in a scenario:
929
-
930
- ```js
931
- // inside async function
932
- const val = await session('john', () => {
933
- I.amOnPage('/info');
934
- return I.grabTextFrom({ css: 'h1' });
935
- });
936
- I.fillField('Description', val);
937
- ```
938
-
939
- Functions passed into a session can use the `I` object, page objects, and any other objects declared for the scenario.
940
- This function can also be declared as async (but doesn't work as generator).
941
-
942
- Also, you can use `within` inside a session, but you can't call session from inside `within`.
943
-
944
-
945
- ## Skipping
946
-
947
- Like in Mocha you can use `x` and `only` to skip tests or to run a single test.
948
-
949
- * `xScenario` - skips current test
950
- * `Scenario.skip` - skips current test
951
- * `Scenario.only` - executes only the current test
952
- * `xFeature` - skips current suite <Badge text="Since 2.6.6" type="warning"/>
953
- * `Feature.skip` - skips the current suite <Badge text="Since 2.6.6" type="warning"/>
954
-
955
-
956
- ## Todo Test
957
-
958
- You can use `Scenario.todo` when you are planning on writing tests.
959
-
960
- This test will be skipped like with regular `Scenario.skip` but with additional message "Test not implemented!":
961
-
962
- Use it with a test body as a test plan:
963
-
964
- ```js
965
- Scenario.todo('Test', I => {
966
- /**
967
- * 1. Click to field
968
- * 2. Fill field
969
- *
970
- * Result:
971
- * 3. Field contains text
972
- */
973
- });
974
- ```
975
-
976
- Or even without a test body:
977
-
978
- ```js
979
- Scenario.todo('Test');
980
- ```