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/bdd.md CHANGED
@@ -1,15 +1,17 @@
1
1
  ---
2
- id: bdd
2
+ permalink: /bdd
3
3
  title: Behavior Driven Development
4
4
  ---
5
5
 
6
+ # Behavior Driven Development
7
+
6
8
  Behavior Driven Development (BDD) is a popular software development methodology. BDD is considered an extension of TDD, and is greatly inspired by [Agile](http://agilemanifesto.org/) practices. The primary reason to choose BDD as your development process is to break down communication barriers between business and technical teams. BDD encourages the use of automated testing to verify all documented features of a project from the very beginning. This is why it is common to talk about BDD in the context of test frameworks (like CodeceptJS). The BDD approach, however, is about much more than testing - it is a common language for all team members to use during the development process.
7
9
 
8
10
  ## What is Behavior Driven Development
9
11
 
10
12
  BDD was introduced by [Dan North](https://dannorth.net/introducing-bdd/). He described it as:
11
13
 
12
- > outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.
14
+ > outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.
13
15
 
14
16
  BDD has its own evolution from the days it was born, started by replacing "test" to "should" in unit tests, and moving towards powerful tools like Cucumber and Behat, which made user stories (human readable text) to be executed as an acceptance test.
15
17
 
@@ -221,14 +223,14 @@ Steps in background are defined the same way as in scenarios.
221
223
  Scenarios can become more descriptive when you represent repeating data as tables. Instead of writing several steps "I have product with :num1 $ price in my cart" we can have one step with multiple values in it.
222
224
 
223
225
  ```gherkin
224
- Given i have products in my cart
226
+ Given I have products in my cart
225
227
  | name | category | price |
226
228
  | Harry Potter | Books | 5 |
227
229
  | iPhone 5 | Smartphones | 1200 |
228
230
  | Nuclear Bomb | Weapons | 100000 |
229
231
  ```
230
232
 
231
- Tables is a recommended ways to pass arrays into test scenarios.
233
+ Tables are the recommended way to pass arrays into test scenarios.
232
234
  Inside a step definition data is stored in argument passed as `DataTable` JavaScript object.
233
235
  You can iterate on it like this:
234
236
 
@@ -245,7 +247,30 @@ Given('I have products in my cart', (table) => { // eslint-disable-line
245
247
  // take values
246
248
  const name = cells[0].value;
247
249
  const category = cells[1].value;
248
- const price = cells[1].value;
250
+ const price = cells[2].value;
251
+ // ...
252
+ }
253
+ });
254
+ ```
255
+
256
+ You can also use the `parse()` method to obtain an object that allow you to get a simple version of the table parsed by column or row, with header (or not):
257
+
258
+ - `raw()` - returns the table as a 2-D array
259
+ - `rows()` - returns the table as a 2-D array, without the first row
260
+ - `hashes()` - returns an array of objects where each row is converted to an object (column header is the key)
261
+
262
+ If we use hashes() with the previous exemple :
263
+
264
+ ```js
265
+ Given('I have products in my cart', (table) => { // eslint-disable-line
266
+ //parse the table by header
267
+ const tableByHeader = table.parse().hashes();
268
+ for (const row in tableByHeader) {
269
+
270
+ // take values
271
+ const name = row.name;
272
+ const category = row.category;
273
+ const price = row.price;
249
274
  // ...
250
275
  }
251
276
  });
package/docs/best.md CHANGED
@@ -1,8 +1,10 @@
1
1
  ---
2
- id: best
2
+ permalink: /best
3
3
  title: Best Practices
4
4
  ---
5
5
 
6
+ # Best Practices
7
+
6
8
  ## Focus on Readability
7
9
 
8
10
  In CodeceptJS we encourage users to follow semantic elements on page while writing tests.
@@ -22,7 +24,7 @@ Even a text on the button changes its much easier to update it.
22
24
 
23
25
  > If your code goes beyond using `I` object or page objects, you are probably doing something wrong.
24
26
 
25
- When it's hard to match text to element we recommend using [locator builder](https://codecept.io/locators#locator-builder). It allows to build complex locators via fluent API.
27
+ When it's hard to match text to element we recommend using [locator builder](/locators#locator-builder). It allows to build complex locators via fluent API.
26
28
  So if you want to click an element which is not a button or a link and use its text you can use `locate()` to build a readable locator:
27
29
 
28
30
  ```js
@@ -35,10 +37,10 @@ I.click(locate('.button').withText('Click me'));
35
37
  To write simpler and effective tests we encourage to use short cuts.
36
38
  Make test be focused on one feature and try to simplify everything that is not related directly to test.
37
39
 
38
- * If data is required for a test, try to create that data via API. See how to do it in [Data Management](https://codecept.io/data) chapter.
39
- * If user login is required, use [autoLogin plugin](https://codecept.io/plugins#autoLogin) instead of putting login steps inside a test.
40
+ * If data is required for a test, try to create that data via API. See how to do it in [Data Management](/data) chapter.
41
+ * If user login is required, use [autoLogin plugin](/plugins#autoLogin) instead of putting login steps inside a test.
40
42
  * Break a long test into few. Long test can be fragile and complicated to follow and update.
41
- * Use [custom steps and page objects](https://codecept.io/pageobjects) to hide steps which are not relevant to current test.
43
+ * Use [custom steps and page objects](/pageobjects) to hide steps which are not relevant to current test.
42
44
 
43
45
  Make test as simple as:
44
46
 
@@ -70,7 +72,7 @@ Here is a recommended strategy what to store where:
70
72
  * When site-wide widgets are used, interactions with them should be placed in **Page Fragments**. This should be applied to global navigation, modals, widgets.
71
73
  * A custom action that require some low-level driver access, should be placed into a **Helper**. For instance, database connections, complex mouse actions, email testing, filesystem, services access.
72
74
 
73
- > [Learn more](https://codecept.io/pageobjects) about different refactoring options
75
+ > [Learn more](/pageobjects) about different refactoring options
74
76
 
75
77
  However, it's recommended to not overengineer and keep tests simple. If a test code doesn't require reusage at this point it should not be transformed to use page objects.
76
78
 
package/docs/books.md CHANGED
@@ -1,8 +1,12 @@
1
1
  ---
2
- id: books
2
+ permalink: /books
3
+ layout: Section
4
+ sidebar: false
3
5
  title: Books & Posts
6
+ editLink: false
4
7
  ---
5
8
 
9
+ # Books & Posts
6
10
  > Add your own books or posts to our [Wiki Page](https://github.com/Codeception/CodeceptJS/wiki/Books-&-Posts)
7
11
  ### [Practical End 2 End Testing with CodeceptJS](https://leanpub.com/codeceptjs/)
8
12
 
@@ -27,6 +31,7 @@ A list of good educational posts about CodeceptJS
27
31
 
28
32
  * [QA Automation From Zero-to-Hero with CodeceptJS End-to-End Testing](https://medium.com/@dan.ryan.emmons/qa-automation-from-zero-to-hero-with-codeceptjs-end-to-end-testing-719db9d6ff5c) by Dan Emmons
29
33
  * [Effective End2End Tests with CodeceptJS](https://hackernoon.com/effective-end-2-end-testing-in-javascript-with-codeceptjs-37c8d7d6a928) by @davertmik
34
+ * [Customizing CodeceptJS Skeleton](https://medium.com/@successivetech/codeceptjs-skeleton-9ba86d3b45ec)
30
35
  * [Running End to End tests as Google Cloud Functions](https://hackernoon.com/running-end-to-end-tests-as-google-cloud-functions-f5e34ffc3984)
31
36
  * [End-To-End Testing With CodeceptJS](https://www.monterail.com/blog/end-to-end-testing-with-codeceptjs) by Piotr Michalski
32
37
  * [Getting started with CodeceptJS and Selenium WebDriver](https://medium.com/@garrettvorce/getting-started-with-selenium-and-codeceptjs-c0698e8df677)
@@ -1,11 +1,13 @@
1
1
  let webdriverio;
2
2
  let wdioV4;
3
3
  let SCREEN_SIZE;
4
+
5
+ const fs = require('fs');
6
+ const requireg = require('requireg');
7
+
4
8
  const Webdriver = require('./WebDriver');
5
9
  const AssertionFailedError = require('../assert/error');
6
10
  const truth = require('../assert/truth').truth;
7
- const requireg = require('requireg');
8
- const fs = require('fs');
9
11
  const recorder = require('../recorder');
10
12
  const Locator = require('../locator');
11
13
  const ConnectionRefused = require('./errors/ConnectionRefused');
@@ -249,7 +251,8 @@ class Appium extends Webdriver {
249
251
  width: res.value[0],
250
252
  height: res.value[1],
251
253
  });
252
- } else if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && !this.platform) {
254
+ }
255
+ if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && !this.platform) {
253
256
  const dimensions = this.options.windowSize.split('x');
254
257
  await this.browser.windowHandleSize({
255
258
  width: dimensions[0],
@@ -435,7 +438,7 @@ class Appium extends Webdriver {
435
438
  * I.seeAppIsInstalled("com.example.android.apis");
436
439
  * ```
437
440
  *
438
- * @param bundleId String ID of bundled app
441
+ * @param {string} bundleId String ID of bundled app
439
442
  *
440
443
  * Appium: support only Android
441
444
  */
@@ -452,7 +455,7 @@ class Appium extends Webdriver {
452
455
  * I.seeAppIsNotInstalled("com.example.android.apis");
453
456
  * ```
454
457
  *
455
- * @param bundleId String ID of bundled app
458
+ * @param {string} bundleId String ID of bundled app
456
459
  *
457
460
  * Appium: support only Android
458
461
  */
@@ -468,7 +471,7 @@ class Appium extends Webdriver {
468
471
  * ```js
469
472
  * I.installApp('/path/to/file.apk');
470
473
  * ```
471
- * @param path path to apk file
474
+ * @param {string} path path to apk file
472
475
  *
473
476
  * Appium: support only Android
474
477
  */
@@ -483,7 +486,8 @@ class Appium extends Webdriver {
483
486
  * ```js
484
487
  * I.removeApp('appName', 'com.example.android.apis');
485
488
  * ```
486
- * @param bundleId String ID of bundle
489
+ * @param {string} appId
490
+ * @param {string} bundleId String ID of bundle
487
491
  *
488
492
  * Appium: support only Android
489
493
  */
@@ -507,6 +511,7 @@ class Appium extends Webdriver {
507
511
  * ```js
508
512
  * I.seeCurrentActivityIs(".HomeScreenActivity")
509
513
  * ```
514
+ * @param {string} currentActivity
510
515
  *
511
516
  * Appium: support only Android
512
517
  */
@@ -554,7 +559,7 @@ class Appium extends Webdriver {
554
559
  * I.seeOrientationIs('LANDSCAPE')
555
560
  * ```
556
561
  *
557
- * @param orientation LANDSCAPE or PORTRAIT
562
+ * @param {'LANDSCAPE'|'PORTRAIT'} orientation LANDSCAPE or PORTRAIT
558
563
  *
559
564
  * Appium: support Android and iOS
560
565
  */
@@ -584,7 +589,7 @@ class Appium extends Webdriver {
584
589
  * I.setOrientation('LANDSCAPE')
585
590
  * ```
586
591
  *
587
- * @param orientation LANDSCAPE or PORTRAIT
592
+ * @param {'LANDSCAPE'|'PORTRAIT'} orientation LANDSCAPE or PORTRAIT
588
593
  *
589
594
  * Appium: support Android and iOS
590
595
  */
@@ -700,7 +705,7 @@ class Appium extends Webdriver {
700
705
  /**
701
706
  * Switch to the specified context.
702
707
  *
703
- * @param context the context to switch to
708
+ * @param {*} context the context to switch to
704
709
 
705
710
  */
706
711
  async _switchToContext(context) {
@@ -799,7 +804,7 @@ class Appium extends Webdriver {
799
804
  * I.setSettings({cyberdelia: 'open'});
800
805
  * ```
801
806
  *
802
- * @param settings object
807
+ * @param {object} settings object
803
808
  *
804
809
  * Appium: support Android and iOS
805
810
  */
@@ -820,7 +825,7 @@ class Appium extends Webdriver {
820
825
  * I.hideDeviceKeyboard('pressKey', 'Done');
821
826
  * ```
822
827
  *
823
- * @param strategy desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
828
+ * @param {'tapOutside' | 'pressKey'} strategy desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
824
829
  *
825
830
  * Appium: support Android and iOS
826
831
  */
@@ -838,7 +843,7 @@ class Appium extends Webdriver {
838
843
  * I.sendDeviceKeyEvent(3);
839
844
  * ```
840
845
  *
841
- * @param keyValue Device specific key value
846
+ * @param {number} keyValue Device specific key value
842
847
  *
843
848
  * Appium: support only Android
844
849
  */
@@ -912,10 +917,10 @@ class Appium extends Webdriver {
912
917
  *
913
918
  * [See complete reference](http://webdriver.io/api/mobile/swipe.html)
914
919
  *
915
- * @param locator
916
- * @param xoffset
917
- * @param yoffset
918
- * @param speed (optional), 1000 by default
920
+ * @param {CodeceptJS.LocatorOrString} locator
921
+ * @param {number} xoffset
922
+ * @param {number} yoffset
923
+ * @param {number} [speed=1000] (optional), 1000 by default
919
924
  *
920
925
  * Appium: support Android and iOS
921
926
  */
@@ -933,8 +938,8 @@ class Appium extends Webdriver {
933
938
  * I.performswipe(100,200);
934
939
  * ```
935
940
  *
936
- * @param from
937
- * @param to
941
+ * @param {number} from
942
+ * @param {number} to
938
943
  *
939
944
  * Appium: support Android and iOS
940
945
  */
@@ -964,9 +969,9 @@ class Appium extends Webdriver {
964
969
  * I.swipeDown(locator, 1200, 1000); // set offset and speed
965
970
  * ```
966
971
  *
967
- * @param locator
968
- * @param yoffset (optional)
969
- * @param speed (optional), 1000 by default
972
+ * @param {CodeceptJS.LocatorOrString} locator
973
+ * @param {number} [yoffset] (optional)
974
+ * @param {number} [speed=1000] (optional), 1000 by default
970
975
  *
971
976
  * Appium: support Android and iOS
972
977
  */
@@ -992,9 +997,9 @@ class Appium extends Webdriver {
992
997
  * I.swipeLeft(locator, 1200, 1000); // set offset and speed
993
998
  * ```
994
999
  *
995
- * @param locator
996
- * @param xoffset (optional)
997
- * @param speed (optional), 1000 by default
1000
+ * @param {CodeceptJS.LocatorOrString} locator
1001
+ * @param {number} [xoffset] (optional)
1002
+ * @param {number} [speed=1000] (optional), 1000 by default
998
1003
  *
999
1004
  * Appium: support Android and iOS
1000
1005
  */
@@ -1018,9 +1023,9 @@ class Appium extends Webdriver {
1018
1023
  * I.swipeRight(locator, 1200, 1000); // set offset and speed
1019
1024
  * ```
1020
1025
  *
1021
- * @param locator
1022
- * @param xoffset (optional)
1023
- * @param speed (optional), 1000 by default
1026
+ * @param {CodeceptJS.LocatorOrString} locator
1027
+ * @param {number} [xoffset] (optional)
1028
+ * @param {number} [speed=1000] (optional), 1000 by default
1024
1029
  *
1025
1030
  * Appium: support Android and iOS
1026
1031
  */
@@ -1044,9 +1049,9 @@ class Appium extends Webdriver {
1044
1049
  * I.swipeUp(locator, 1200, 1000); // set offset and speed
1045
1050
  * ```
1046
1051
  *
1047
- * @param locator
1048
- * @param yoffset (optional)
1049
- * @param speed (optional), 1000 by default
1052
+ * @param {CodeceptJS.LocatorOrString} locator
1053
+ * @param {number} [yoffset] (optional)
1054
+ * @param {number} [speed=1000] (optional), 1000 by default
1050
1055
  *
1051
1056
  * Appium: support Android and iOS
1052
1057
  */
@@ -1074,12 +1079,12 @@ class Appium extends Webdriver {
1074
1079
  * 500);
1075
1080
  * ```
1076
1081
  *
1077
- * @param searchableLocator
1078
- * @param scrollLocator
1079
- * @param direction
1080
- * @param timeout
1081
- * @param offset
1082
- * @param speed
1082
+ * @param {string} searchableLocator
1083
+ * @param {string} scrollLocator
1084
+ * @param {string} direction
1085
+ * @param {number} timeout
1086
+ * @param {number} offset
1087
+ * @param {number} speed
1083
1088
  *
1084
1089
  * Appium: support Android and iOS
1085
1090
  */
@@ -1268,9 +1273,8 @@ class Appium extends Webdriver {
1268
1273
  * ```js
1269
1274
  * I.appendField('#myTextField', 'appended');
1270
1275
  * ```
1271
- * @param {string|object} field located by label|name|CSS|XPath|strict locator
1276
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator
1272
1277
  * @param {string} value text value to append.
1273
- * {--end--}
1274
1278
  *
1275
1279
  */
1276
1280
  async appendField(field, value) {
@@ -1289,9 +1293,8 @@ class Appium extends Webdriver {
1289
1293
  * I.checkOption('I Agree to Terms and Conditions');
1290
1294
  * I.checkOption('agree', '//form');
1291
1295
  * ```
1292
- * @param {string|object} field checkbox located by label | name | CSS | XPath | strict locator.
1293
- * @param {string} context (optional, `null` by default) element located by CSS | XPath | strict locator.
1294
- * {--end--}
1296
+ * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1297
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1295
1298
  *
1296
1299
  */
1297
1300
  async checkOption(field) {
@@ -1322,9 +1325,9 @@ class Appium extends Webdriver {
1322
1325
  * I.click({css: 'nav a.login'});
1323
1326
  * ```
1324
1327
  *
1325
- * @param {string|object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1326
- * @param {string|object} context (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1327
- * {--end--}
1328
+ * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1329
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1330
+ *
1328
1331
  *
1329
1332
  */
1330
1333
  async click(locator, context) {
@@ -1341,8 +1344,8 @@ class Appium extends Webdriver {
1341
1344
  * I.dontSeeCheckboxIsChecked('agree'); // located by name
1342
1345
  * ```
1343
1346
  *
1344
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1345
- * {--end--}
1347
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1348
+ *
1346
1349
  *
1347
1350
  */
1348
1351
  async dontSeeCheckboxIsChecked(field) {
@@ -1357,8 +1360,7 @@ class Appium extends Webdriver {
1357
1360
  * I.dontSeeElement('.modal'); // modal is not shown
1358
1361
  * ```
1359
1362
  *
1360
- * @param {string|object} locator located by CSS|XPath|Strict locator.
1361
- * {--end--}
1363
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
1362
1364
  */
1363
1365
  async dontSeeElement(locator) {
1364
1366
  if (this.isWeb) return super.dontSeeElement(locator);
@@ -1374,9 +1376,8 @@ class Appium extends Webdriver {
1374
1376
  * I.dontSeeInField({ css: 'form input.email' }, 'user@user.com'); // field by CSS
1375
1377
  * ```
1376
1378
  *
1377
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1379
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1378
1380
  * @param {string} value value to check.
1379
- * {--end--}
1380
1381
  *
1381
1382
  */
1382
1383
  async dontSeeInField(field, value) {
@@ -1395,9 +1396,8 @@ class Appium extends Webdriver {
1395
1396
  * ```
1396
1397
  *
1397
1398
  * @param {string} text which is not present.
1398
- * @param {string|object} context (optional) element located by CSS|XPath|strict locator in which to perfrom search.
1399
- *
1400
- * {--end--}
1399
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
1400
+ *
1401
1401
  */
1402
1402
  async dontSee(text, context = null) {
1403
1403
  if (this.isWeb) return super.dontSee(text, context);
@@ -1418,9 +1418,9 @@ class Appium extends Webdriver {
1418
1418
  * // or by strict locator
1419
1419
  * I.fillField({css: 'form#login input[name=username]'}, 'John');
1420
1420
  * ```
1421
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1421
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1422
1422
  * @param {string} value text value to fill.
1423
- * {--end--}
1423
+ *
1424
1424
  *
1425
1425
  */
1426
1426
  async fillField(field, value) {
@@ -1438,9 +1438,8 @@ class Appium extends Webdriver {
1438
1438
  * ```
1439
1439
  * If multiple elements found returns an array of texts.
1440
1440
  *
1441
- * @param locator element located by CSS|XPath|strict locator.
1442
- * @returns {Promise<string>} attribute value
1443
- * {--end--}
1441
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1442
+ * @returns {Promise<string|string[]>} attribute value
1444
1443
  *
1445
1444
  */
1446
1445
  async grabTextFrom(locator) {
@@ -1455,9 +1454,8 @@ class Appium extends Webdriver {
1455
1454
  * ```js
1456
1455
  * let email = await I.grabValueFrom('input[name=email]');
1457
1456
  * ```
1458
- * @param {string|object} locator field located by label|name|CSS|XPath|strict locator.
1457
+ * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1459
1458
  * @returns {Promise<string>} attribute value
1460
- * {--end--}
1461
1459
  *
1462
1460
  */
1463
1461
  async grabValueFrom(locator) {
@@ -1465,6 +1463,25 @@ class Appium extends Webdriver {
1465
1463
  return super.grabValueFrom(parseLocator.call(this, locator));
1466
1464
  }
1467
1465
 
1466
+ /**
1467
+ * Scroll element into viewport.
1468
+ *
1469
+ * ```js
1470
+ * I.scrollIntoView('#submit');
1471
+ * I.scrollIntoView('#submit', true);
1472
+ * I.scrollIntoView('#submit', { behavior: "smooth", block: "center", inline: "center" });
1473
+ * ```
1474
+ *
1475
+ * @param {string|object} locator located by CSS|XPath|strict locator.
1476
+ * @param {boolean|object} alignToTop (optional) or scrollIntoViewOptions (optional), see https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView.
1477
+ *
1478
+ *
1479
+ * Supported only for web testing
1480
+ */
1481
+ async scrollIntoView(locator, scrollIntoViewOptions) {
1482
+ if (this.isWeb) return super.scrollIntoView(locator, scrollIntoViewOptions);
1483
+ }
1484
+
1468
1485
  /**
1469
1486
  * Verifies that the specified checkbox is checked.
1470
1487
  *
@@ -1474,8 +1491,8 @@ class Appium extends Webdriver {
1474
1491
  * I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1475
1492
  * ```
1476
1493
  *
1477
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1478
- * {--end--}
1494
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1495
+ *
1479
1496
  *
1480
1497
  */
1481
1498
  async seeCheckboxIsChecked(field) {
@@ -1490,8 +1507,7 @@ class Appium extends Webdriver {
1490
1507
  * ```js
1491
1508
  * I.seeElement('#modal');
1492
1509
  * ```
1493
- * @param {string|object} locator located by CSS|XPath|strict locator.
1494
- * {--end--}
1510
+ * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1495
1511
  *
1496
1512
  */
1497
1513
  async seeElement(locator) {
@@ -1509,9 +1525,9 @@ class Appium extends Webdriver {
1509
1525
  * I.seeInField('form input[type=hidden]','hidden_value');
1510
1526
  * I.seeInField('#searchform input','Search');
1511
1527
  * ```
1512
- * @param {string|object} field located by label|name|CSS|XPath|strict locator.
1528
+ * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1513
1529
  * @param {string} value value to check.
1514
- * {--end--}
1530
+ *
1515
1531
  *
1516
1532
  */
1517
1533
  async seeInField(field, value) {
@@ -1529,8 +1545,7 @@ class Appium extends Webdriver {
1529
1545
  * I.see('Register', {css: 'form.register'}); // use strict locator
1530
1546
  * ```
1531
1547
  * @param {string} text expected on page.
1532
- * @param {string|object} context (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
1533
- * {--end--}
1548
+ * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
1534
1549
  *
1535
1550
  */
1536
1551
  async see(text, context) {
@@ -1557,11 +1572,10 @@ class Appium extends Webdriver {
1557
1572
  * ```js
1558
1573
  * I.selectOption('Which OS do you use?', ['Android', 'iOS']);
1559
1574
  * ```
1560
- * @param {string|object} select field located by label|name|CSS|XPath|strict locator.
1561
- * @param {string|array} option visible text or value of option.
1562
- * {--end--}
1575
+ * @param {CodeceptJS.LocatorOrString} select field located by label|name|CSS|XPath|strict locator.
1576
+ * @param {string|Array<*>} option visible text or value of option.
1563
1577
  *
1564
- * * Supported on only for web testing!
1578
+ * Supported only for web testing
1565
1579
  */
1566
1580
  async selectOption(select, option) {
1567
1581
  if (this.isWeb) return super.selectOption(select, option);
@@ -1577,9 +1591,8 @@ class Appium extends Webdriver {
1577
1591
  * I.waitForElement('.btn.continue', 5); // wait for 5 secs
1578
1592
  * ```
1579
1593
  *
1580
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1581
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1582
- * {--end--}
1594
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1595
+ * @param {number} [sec] (optional, `1` by default) time in seconds to wait
1583
1596
  *
1584
1597
  */
1585
1598
  async waitForElement(locator, sec = null) {
@@ -1595,9 +1608,8 @@ class Appium extends Webdriver {
1595
1608
  * I.waitForVisible('#popup');
1596
1609
  * ```
1597
1610
  *
1598
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1599
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1600
- * {--end--}
1611
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1612
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1601
1613
  *
1602
1614
  */
1603
1615
  async waitForVisible(locator, sec = null) {
@@ -1613,9 +1625,8 @@ class Appium extends Webdriver {
1613
1625
  * I.waitForInvisible('#popup');
1614
1626
  * ```
1615
1627
  *
1616
- * @param {string|object} locator element located by CSS|XPath|strict locator.
1617
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1618
- * {--end--}
1628
+ * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1629
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1619
1630
  *
1620
1631
  */
1621
1632
  async waitForInvisible(locator, sec = null) {
@@ -1634,9 +1645,8 @@ class Appium extends Webdriver {
1634
1645
  * ```
1635
1646
  *
1636
1647
  * @param {string }text to wait for.
1637
- * @param {number} sec (optional, `1` by default) time in seconds to wait
1638
- * @param {string|object} context (optional) element located by CSS|XPath|strict locator.
1639
- * {--end--}
1648
+ * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
1649
+ * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
1640
1650
  *
1641
1651
  */
1642
1652
  async waitForText(text, sec = null, context = null) {