codeceptjs 3.5.10 → 3.5.12-beta.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 (225) hide show
  1. package/README.md +3 -3
  2. package/lib/command/run-multiple.js +3 -1
  3. package/lib/command/run-workers.js +32 -1
  4. package/lib/command/workers/runTests.js +18 -2
  5. package/lib/helper/Expect.js +33 -33
  6. package/lib/helper/Playwright.js +49 -26
  7. package/lib/helper/Puppeteer.js +41 -19
  8. package/lib/helper/WebDriver.js +155 -48
  9. package/lib/helper/extras/PlaywrightReactVueLocator.js +38 -0
  10. package/lib/locator.js +17 -4
  11. package/lib/plugin/retryFailedStep.js +6 -2
  12. package/lib/plugin/retryTo.js +2 -2
  13. package/lib/plugin/tryTo.js +5 -4
  14. package/package.json +25 -22
  15. package/typings/index.d.ts +8 -5
  16. package/typings/promiseBasedTypes.d.ts +203 -75
  17. package/typings/types.d.ts +213 -145
  18. package/docs/advanced.md +0 -351
  19. package/docs/ai.md +0 -248
  20. package/docs/api.md +0 -323
  21. package/docs/basics.md +0 -979
  22. package/docs/bdd.md +0 -539
  23. package/docs/best.md +0 -237
  24. package/docs/books.md +0 -37
  25. package/docs/bootstrap.md +0 -135
  26. package/docs/build/ApiDataFactory.js +0 -410
  27. package/docs/build/Appium.js +0 -2027
  28. package/docs/build/Expect.js +0 -422
  29. package/docs/build/FileSystem.js +0 -228
  30. package/docs/build/GraphQL.js +0 -229
  31. package/docs/build/GraphQLDataFactory.js +0 -309
  32. package/docs/build/JSONResponse.js +0 -338
  33. package/docs/build/Mochawesome.js +0 -71
  34. package/docs/build/Nightmare.js +0 -2152
  35. package/docs/build/OpenAI.js +0 -126
  36. package/docs/build/Playwright.js +0 -5078
  37. package/docs/build/Protractor.js +0 -2706
  38. package/docs/build/Puppeteer.js +0 -3874
  39. package/docs/build/REST.js +0 -344
  40. package/docs/build/TestCafe.js +0 -2125
  41. package/docs/build/WebDriver.js +0 -4124
  42. package/docs/changelog.md +0 -2572
  43. package/docs/commands.md +0 -266
  44. package/docs/community-helpers.md +0 -58
  45. package/docs/configuration.md +0 -157
  46. package/docs/continuous-integration.md +0 -22
  47. package/docs/custom-helpers.md +0 -306
  48. package/docs/data.md +0 -379
  49. package/docs/detox.md +0 -235
  50. package/docs/docker.md +0 -136
  51. package/docs/email.md +0 -183
  52. package/docs/examples.md +0 -149
  53. package/docs/helpers/ApiDataFactory.md +0 -266
  54. package/docs/helpers/Appium.md +0 -1374
  55. package/docs/helpers/Detox.md +0 -586
  56. package/docs/helpers/Expect.md +0 -275
  57. package/docs/helpers/FileSystem.md +0 -152
  58. package/docs/helpers/GraphQL.md +0 -151
  59. package/docs/helpers/GraphQLDataFactory.md +0 -226
  60. package/docs/helpers/JSONResponse.md +0 -254
  61. package/docs/helpers/Mochawesome.md +0 -8
  62. package/docs/helpers/MockRequest.md +0 -377
  63. package/docs/helpers/Nightmare.md +0 -1305
  64. package/docs/helpers/OpenAI.md +0 -70
  65. package/docs/helpers/Playwright.md +0 -2706
  66. package/docs/helpers/Polly.md +0 -44
  67. package/docs/helpers/Protractor.md +0 -1769
  68. package/docs/helpers/Puppeteer-firefox.md +0 -86
  69. package/docs/helpers/Puppeteer.md +0 -2291
  70. package/docs/helpers/REST.md +0 -218
  71. package/docs/helpers/TestCafe.md +0 -1321
  72. package/docs/helpers/WebDriver.md +0 -2460
  73. package/docs/hooks.md +0 -340
  74. package/docs/index.md +0 -111
  75. package/docs/installation.md +0 -75
  76. package/docs/internal-api.md +0 -266
  77. package/docs/locators.md +0 -331
  78. package/docs/mobile-react-native-locators.md +0 -67
  79. package/docs/mobile.md +0 -338
  80. package/docs/pageobjects.md +0 -291
  81. package/docs/parallel.md +0 -400
  82. package/docs/playwright.md +0 -632
  83. package/docs/plugins.md +0 -1259
  84. package/docs/puppeteer.md +0 -316
  85. package/docs/quickstart.md +0 -162
  86. package/docs/react.md +0 -69
  87. package/docs/reports.md +0 -392
  88. package/docs/secrets.md +0 -36
  89. package/docs/shadow.md +0 -68
  90. package/docs/shared/keys.mustache +0 -31
  91. package/docs/shared/react.mustache +0 -1
  92. package/docs/testcafe.md +0 -174
  93. package/docs/translation.md +0 -247
  94. package/docs/tutorial.md +0 -271
  95. package/docs/typescript.md +0 -180
  96. package/docs/ui.md +0 -59
  97. package/docs/videos.md +0 -28
  98. package/docs/visual.md +0 -202
  99. package/docs/vue.md +0 -121
  100. package/docs/webapi/amOnPage.mustache +0 -11
  101. package/docs/webapi/appendField.mustache +0 -11
  102. package/docs/webapi/attachFile.mustache +0 -12
  103. package/docs/webapi/blur.mustache +0 -18
  104. package/docs/webapi/checkOption.mustache +0 -13
  105. package/docs/webapi/clearCookie.mustache +0 -9
  106. package/docs/webapi/clearField.mustache +0 -9
  107. package/docs/webapi/click.mustache +0 -25
  108. package/docs/webapi/clickLink.mustache +0 -8
  109. package/docs/webapi/closeCurrentTab.mustache +0 -7
  110. package/docs/webapi/closeOtherTabs.mustache +0 -8
  111. package/docs/webapi/dontSee.mustache +0 -11
  112. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +0 -10
  113. package/docs/webapi/dontSeeCookie.mustache +0 -8
  114. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +0 -10
  115. package/docs/webapi/dontSeeElement.mustache +0 -8
  116. package/docs/webapi/dontSeeElementInDOM.mustache +0 -8
  117. package/docs/webapi/dontSeeInCurrentUrl.mustache +0 -4
  118. package/docs/webapi/dontSeeInField.mustache +0 -11
  119. package/docs/webapi/dontSeeInSource.mustache +0 -8
  120. package/docs/webapi/dontSeeInTitle.mustache +0 -8
  121. package/docs/webapi/doubleClick.mustache +0 -13
  122. package/docs/webapi/downloadFile.mustache +0 -12
  123. package/docs/webapi/dragAndDrop.mustache +0 -9
  124. package/docs/webapi/dragSlider.mustache +0 -11
  125. package/docs/webapi/executeAsyncScript.mustache +0 -24
  126. package/docs/webapi/executeScript.mustache +0 -26
  127. package/docs/webapi/fillField.mustache +0 -16
  128. package/docs/webapi/focus.mustache +0 -13
  129. package/docs/webapi/forceClick.mustache +0 -28
  130. package/docs/webapi/forceRightClick.mustache +0 -18
  131. package/docs/webapi/grabAllWindowHandles.mustache +0 -7
  132. package/docs/webapi/grabAttributeFrom.mustache +0 -10
  133. package/docs/webapi/grabAttributeFromAll.mustache +0 -9
  134. package/docs/webapi/grabBrowserLogs.mustache +0 -9
  135. package/docs/webapi/grabCookie.mustache +0 -11
  136. package/docs/webapi/grabCssPropertyFrom.mustache +0 -11
  137. package/docs/webapi/grabCssPropertyFromAll.mustache +0 -10
  138. package/docs/webapi/grabCurrentUrl.mustache +0 -9
  139. package/docs/webapi/grabCurrentWindowHandle.mustache +0 -6
  140. package/docs/webapi/grabDataFromPerformanceTiming.mustache +0 -20
  141. package/docs/webapi/grabElementBoundingRect.mustache +0 -20
  142. package/docs/webapi/grabGeoLocation.mustache +0 -8
  143. package/docs/webapi/grabHTMLFrom.mustache +0 -10
  144. package/docs/webapi/grabHTMLFromAll.mustache +0 -9
  145. package/docs/webapi/grabNumberOfOpenTabs.mustache +0 -8
  146. package/docs/webapi/grabNumberOfVisibleElements.mustache +0 -9
  147. package/docs/webapi/grabPageScrollPosition.mustache +0 -8
  148. package/docs/webapi/grabPopupText.mustache +0 -5
  149. package/docs/webapi/grabSource.mustache +0 -8
  150. package/docs/webapi/grabTextFrom.mustache +0 -10
  151. package/docs/webapi/grabTextFromAll.mustache +0 -9
  152. package/docs/webapi/grabTitle.mustache +0 -8
  153. package/docs/webapi/grabValueFrom.mustache +0 -9
  154. package/docs/webapi/grabValueFromAll.mustache +0 -8
  155. package/docs/webapi/grabWebElement.mustache +0 -9
  156. package/docs/webapi/grabWebElements.mustache +0 -9
  157. package/docs/webapi/moveCursorTo.mustache +0 -12
  158. package/docs/webapi/openNewTab.mustache +0 -7
  159. package/docs/webapi/pressKey.mustache +0 -12
  160. package/docs/webapi/pressKeyDown.mustache +0 -12
  161. package/docs/webapi/pressKeyUp.mustache +0 -12
  162. package/docs/webapi/pressKeyWithKeyNormalization.mustache +0 -60
  163. package/docs/webapi/refreshPage.mustache +0 -6
  164. package/docs/webapi/resizeWindow.mustache +0 -6
  165. package/docs/webapi/rightClick.mustache +0 -14
  166. package/docs/webapi/saveElementScreenshot.mustache +0 -10
  167. package/docs/webapi/saveScreenshot.mustache +0 -12
  168. package/docs/webapi/say.mustache +0 -10
  169. package/docs/webapi/scrollIntoView.mustache +0 -11
  170. package/docs/webapi/scrollPageToBottom.mustache +0 -6
  171. package/docs/webapi/scrollPageToTop.mustache +0 -6
  172. package/docs/webapi/scrollTo.mustache +0 -12
  173. package/docs/webapi/see.mustache +0 -11
  174. package/docs/webapi/seeAttributesOnElements.mustache +0 -9
  175. package/docs/webapi/seeCheckboxIsChecked.mustache +0 -10
  176. package/docs/webapi/seeCookie.mustache +0 -8
  177. package/docs/webapi/seeCssPropertiesOnElements.mustache +0 -9
  178. package/docs/webapi/seeCurrentUrlEquals.mustache +0 -11
  179. package/docs/webapi/seeElement.mustache +0 -8
  180. package/docs/webapi/seeElementInDOM.mustache +0 -8
  181. package/docs/webapi/seeInCurrentUrl.mustache +0 -8
  182. package/docs/webapi/seeInField.mustache +0 -12
  183. package/docs/webapi/seeInPopup.mustache +0 -8
  184. package/docs/webapi/seeInSource.mustache +0 -7
  185. package/docs/webapi/seeInTitle.mustache +0 -8
  186. package/docs/webapi/seeNumberOfElements.mustache +0 -11
  187. package/docs/webapi/seeNumberOfVisibleElements.mustache +0 -10
  188. package/docs/webapi/seeTextEquals.mustache +0 -9
  189. package/docs/webapi/seeTitleEquals.mustache +0 -8
  190. package/docs/webapi/selectOption.mustache +0 -21
  191. package/docs/webapi/setCookie.mustache +0 -16
  192. package/docs/webapi/setGeoLocation.mustache +0 -12
  193. package/docs/webapi/switchTo.mustache +0 -9
  194. package/docs/webapi/switchToNextTab.mustache +0 -10
  195. package/docs/webapi/switchToPreviousTab.mustache +0 -10
  196. package/docs/webapi/type.mustache +0 -21
  197. package/docs/webapi/uncheckOption.mustache +0 -13
  198. package/docs/webapi/wait.mustache +0 -8
  199. package/docs/webapi/waitForClickable.mustache +0 -11
  200. package/docs/webapi/waitForDetached.mustache +0 -10
  201. package/docs/webapi/waitForElement.mustache +0 -11
  202. package/docs/webapi/waitForEnabled.mustache +0 -6
  203. package/docs/webapi/waitForFunction.mustache +0 -17
  204. package/docs/webapi/waitForInvisible.mustache +0 -10
  205. package/docs/webapi/waitForText.mustache +0 -13
  206. package/docs/webapi/waitForValue.mustache +0 -10
  207. package/docs/webapi/waitForVisible.mustache +0 -10
  208. package/docs/webapi/waitInUrl.mustache +0 -9
  209. package/docs/webapi/waitNumberOfVisibleElements.mustache +0 -10
  210. package/docs/webapi/waitToHide.mustache +0 -10
  211. package/docs/webapi/waitUrlEquals.mustache +0 -10
  212. package/docs/webdriver.md +0 -655
  213. package/docs/wiki/Books-&-Posts.md +0 -27
  214. package/docs/wiki/Community-Helpers-&-Plugins.md +0 -53
  215. package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +0 -61
  216. package/docs/wiki/Examples.md +0 -145
  217. package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +0 -68
  218. package/docs/wiki/Home.md +0 -16
  219. package/docs/wiki/Migration-to-Appium-v2---CodeceptJS.md +0 -83
  220. package/docs/wiki/Release-Process.md +0 -24
  221. package/docs/wiki/Roadmap.md +0 -23
  222. package/docs/wiki/Tests.md +0 -1393
  223. package/docs/wiki/Upgrading-to-CodeceptJS-3.md +0 -153
  224. package/docs/wiki/Videos.md +0 -19
  225. package/lib/helper/extras/PlaywrightReact.js +0 -9
package/README.md CHANGED
@@ -304,8 +304,8 @@ Thanks all to those who are and will have contributing to this awesome project!
304
304
  <a href="https://github.com/APshenkin"><img src="https://avatars.githubusercontent.com/u/14344430?v=4" title="APshenkin" width="80" height="80"></a>
305
305
  <a href="https://github.com/fabioel"><img src="https://avatars.githubusercontent.com/u/9824235?v=4" title="fabioel" width="80" height="80"></a>
306
306
  <a href="https://github.com/pablopaul"><img src="https://avatars.githubusercontent.com/u/635526?v=4" title="pablopaul" width="80" height="80"></a>
307
- <a href="https://github.com/Georgegriff"><img src="https://avatars.githubusercontent.com/u/9056958?v=4" title="Georgegriff" width="80" height="80"></a>
308
307
  <a href="https://github.com/mirao"><img src="https://avatars.githubusercontent.com/u/12584138?v=4" title="mirao" width="80" height="80"></a>
308
+ <a href="https://github.com/Georgegriff"><img src="https://avatars.githubusercontent.com/u/9056958?v=4" title="Georgegriff" width="80" height="80"></a>
309
309
  <a href="https://github.com/KMKoushik"><img src="https://avatars.githubusercontent.com/u/24666922?v=4" title="KMKoushik" width="80" height="80"></a>
310
310
  <a href="https://github.com/nikocanvacom"><img src="https://avatars.githubusercontent.com/u/83254493?v=4" title="nikocanvacom" width="80" height="80"></a>
311
311
  <a href="https://github.com/elukoyanov"><img src="https://avatars.githubusercontent.com/u/11647141?v=4" title="elukoyanov" width="80" height="80"></a>
@@ -321,9 +321,9 @@ Thanks all to those who are and will have contributing to this awesome project!
321
321
  <a href="https://github.com/ngraf"><img src="https://avatars.githubusercontent.com/u/7094389?v=4" title="ngraf" width="80" height="80"></a>
322
322
  <a href="https://github.com/maojunxyz"><img src="https://avatars.githubusercontent.com/u/28778042?v=4" title="maojunxyz" width="80" height="80"></a>
323
323
  <a href="https://github.com/abhimanyupandian"><img src="https://avatars.githubusercontent.com/u/36107381?v=4" title="abhimanyupandian" width="80" height="80"></a>
324
- <a href="https://github.com/hatufacci"><img src="https://avatars.githubusercontent.com/u/4963181?v=4" title="hatufacci" width="80" height="80"></a>
325
324
  <a href="https://github.com/martomo"><img src="https://avatars.githubusercontent.com/u/1850135?v=4" title="martomo" width="80" height="80"></a>
326
- <a href="https://github.com/denis-sokolov"><img src="https://avatars.githubusercontent.com/u/113721?v=4" title="denis-sokolov" width="80" height="80"></a>
325
+ <a href="https://github.com/hatufacci"><img src="https://avatars.githubusercontent.com/u/4963181?v=4" title="hatufacci" width="80" height="80"></a>
326
+ <a href="https://github.com/johnyb"><img src="https://avatars.githubusercontent.com/u/86358?v=4" title="johnyb" width="80" height="80"></a>
327
327
 
328
328
  [//]: contributor-faces
329
329
 
@@ -28,7 +28,9 @@ let processesDone;
28
28
 
29
29
  module.exports = async function (selectedRuns, options) {
30
30
  // registering options globally to use in config
31
- process.env.profile = options.profile;
31
+ if (options.profile) {
32
+ process.env.profile = options.profile;
33
+ }
32
34
  const configFile = options.config;
33
35
 
34
36
  const testRoot = getTestRoot(configFile);
@@ -11,6 +11,7 @@ module.exports = async function (workerCount, selectedRuns, options) {
11
11
  const passedTestArr = [];
12
12
  const failedTestArr = [];
13
13
  const skippedTestArr = [];
14
+ const stepArr = [];
14
15
 
15
16
  const { config: testConfig, override = '' } = options;
16
17
  const overrideConfigs = tryOrDefault(() => JSON.parse(override), {});
@@ -36,6 +37,14 @@ module.exports = async function (workerCount, selectedRuns, options) {
36
37
  suiteArr.push(suite);
37
38
  });
38
39
 
40
+ workers.on(event.step.passed, (step) => {
41
+ stepArr.push(step);
42
+ });
43
+
44
+ workers.on(event.step.failed, (step) => {
45
+ stepArr.push(step);
46
+ });
47
+
39
48
  workers.on(event.test.failed, (test) => {
40
49
  failedTestArr.push(test);
41
50
  output.test.failed(test);
@@ -48,11 +57,33 @@ module.exports = async function (workerCount, selectedRuns, options) {
48
57
 
49
58
  workers.on(event.test.skipped, (test) => {
50
59
  skippedTestArr.push(test);
51
- output.test.passed(test);
60
+ output.test.skipped(test);
52
61
  });
53
62
 
54
63
  workers.on(event.all.result, () => {
55
64
  // expose test stats after all workers finished their execution
65
+ function addStepsToTest(test, stepArr) {
66
+ stepArr.test.steps.forEach(step => {
67
+ if (test.steps.length === 0) {
68
+ test.steps.push(step);
69
+ }
70
+ });
71
+ }
72
+
73
+ stepArr.forEach(step => {
74
+ passedTestArr.forEach(test => {
75
+ if (step.test.title === test.title) {
76
+ addStepsToTest(test, step);
77
+ }
78
+ });
79
+
80
+ failedTestArr.forEach(test => {
81
+ if (step.test.title === test.title) {
82
+ addStepsToTest(test, step);
83
+ }
84
+ });
85
+ });
86
+
56
87
  event.dispatcher.emit(event.workers.result, {
57
88
  suites: suiteArr,
58
89
  tests: {
@@ -132,7 +132,7 @@ function initializeListeners() {
132
132
  duration: test.duration || 0,
133
133
  err,
134
134
  parent,
135
- steps: test.steps ? simplifyStepsInTestObject(test.steps, err) : [],
135
+ steps: test.steps && test.steps.length > 0 ? simplifyStepsInTestObject(test.steps, err) : [],
136
136
  };
137
137
  }
138
138
 
@@ -141,11 +141,27 @@ function initializeListeners() {
141
141
  const _steps = [];
142
142
 
143
143
  for (step of steps) {
144
+ const _args = [];
145
+
146
+ if (step.args) {
147
+ for (const arg of step.args) {
148
+ // check if arg is a JOI object
149
+ if (arg && arg.$_root) {
150
+ _args.push(JSON.stringify(arg).slice(0, 300));
151
+ // check if arg is a function
152
+ } else if (arg && typeof arg === 'function') {
153
+ _args.push(arg.name);
154
+ } else {
155
+ _args.push(arg);
156
+ }
157
+ }
158
+ }
159
+
144
160
  _steps.push({
145
161
  actor: step.actor,
146
162
  name: step.name,
147
163
  status: step.status,
148
- agrs: step.args,
164
+ args: _args,
149
165
  startedAt: step.startedAt,
150
166
  startTime: step.startTime,
151
167
  endTime: step.endTime,
@@ -20,7 +20,7 @@ chai.use(require('chai-match-pattern'));
20
20
  *{
21
21
  * helpers: {
22
22
  * Playwright: {...},
23
- * ExpectHelper: {},
23
+ * Expect: {},
24
24
  * }
25
25
  *}
26
26
  * ```
@@ -32,7 +32,7 @@ class ExpectHelper {
32
32
  *
33
33
  * @param {*} actualValue
34
34
  * @param {*} expectedValue
35
- * @param {*} customErrorMsg
35
+ * @param {*} [customErrorMsg]
36
36
  */
37
37
  expectEqual(actualValue, expectedValue, customErrorMsg = '') {
38
38
  // @ts-ignore
@@ -44,7 +44,7 @@ class ExpectHelper {
44
44
  *
45
45
  * @param {*} actualValue
46
46
  * @param {*} expectedValue
47
- * @param {*} customErrorMsg
47
+ * @param {*} [customErrorMsg]
48
48
  */
49
49
  expectNotEqual(actualValue, expectedValue, customErrorMsg = '') {
50
50
  // @ts-ignore
@@ -56,7 +56,7 @@ class ExpectHelper {
56
56
  *
57
57
  * @param {*} actualValue
58
58
  * @param {*} expectedValue
59
- * @param {*} customErrorMsg
59
+ * @param {*} [customErrorMsg]
60
60
 
61
61
  */
62
62
  expectDeepEqual(actualValue, expectedValue, customErrorMsg = '') {
@@ -69,7 +69,7 @@ class ExpectHelper {
69
69
  *
70
70
  * @param {*} actualValue
71
71
  * @param {*} expectedValue
72
- * @param {*} customErrorMsg
72
+ * @param {*} [customErrorMsg]
73
73
  */
74
74
  expectNotDeepEqual(actualValue, expectedValue, customErrorMsg = '') {
75
75
  // @ts-ignore
@@ -81,7 +81,7 @@ class ExpectHelper {
81
81
  *
82
82
  * @param {*} actualValue
83
83
  * @param {*} expectedValueToContain
84
- * @param {*} customErrorMsg
84
+ * @param {*} [customErrorMsg]
85
85
  */
86
86
  expectContain(actualValue, expectedValueToContain, customErrorMsg = '') {
87
87
  // @ts-ignore
@@ -95,7 +95,7 @@ class ExpectHelper {
95
95
  *
96
96
  * @param {*} actualValue
97
97
  * @param {*} expectedValueToNotContain
98
- * @param {*} customErrorMsg
98
+ * @param {*} [customErrorMsg]
99
99
  */
100
100
  expectNotContain(
101
101
  actualValue,
@@ -113,7 +113,7 @@ class ExpectHelper {
113
113
  *
114
114
  * @param {*} actualValue
115
115
  * @param {*} expectedValueToStartWith
116
- * @param {*} customErrorMsg
116
+ * @param {*} [customErrorMsg]
117
117
  */
118
118
  expectStartsWith(actualValue, expectedValueToStartWith, customErrorMsg = '') {
119
119
  // @ts-ignore
@@ -127,7 +127,7 @@ class ExpectHelper {
127
127
  *
128
128
  * @param {*} actualValue
129
129
  * @param {*} expectedValueToNotStartWith
130
- * @param {*} customErrorMsg
130
+ * @param {*} [customErrorMsg]
131
131
  */
132
132
  expectNotStartsWith(
133
133
  actualValue,
@@ -144,7 +144,7 @@ class ExpectHelper {
144
144
  /**
145
145
  * @param {*} actualValue
146
146
  * @param {*} expectedValueToEndWith
147
- * @param {*} customErrorMsg
147
+ * @param {*} [customErrorMsg]
148
148
  */
149
149
  expectEndsWith(actualValue, expectedValueToEndWith, customErrorMsg = '') {
150
150
  // @ts-ignore
@@ -157,7 +157,7 @@ class ExpectHelper {
157
157
  /**
158
158
  * @param {*} actualValue
159
159
  * @param {*} expectedValueToNotEndWith
160
- * @param {*} customErrorMsg
160
+ * @param {*} [customErrorMsg]
161
161
  */
162
162
  expectNotEndsWith(
163
163
  actualValue,
@@ -174,7 +174,7 @@ class ExpectHelper {
174
174
  /**
175
175
  * @param {*} targetData
176
176
  * @param {*} jsonSchema
177
- * @param {*} customErrorMsg
177
+ * @param {*} [customErrorMsg]
178
178
  */
179
179
  expectJsonSchema(targetData, jsonSchema, customErrorMsg = '') {
180
180
  // @ts-ignore
@@ -186,7 +186,7 @@ class ExpectHelper {
186
186
  /**
187
187
  * @param {*} targetData
188
188
  * @param {*} jsonSchema
189
- * @param {*} customErrorMsg
189
+ * @param {*} [customErrorMsg]
190
190
  * @param {*} ajvOptions Pass AJV options
191
191
  */
192
192
  expectJsonSchemaUsingAJV(
@@ -204,7 +204,7 @@ class ExpectHelper {
204
204
  /**
205
205
  * @param {*} targetData
206
206
  * @param {*} propertyName
207
- * @param {*} customErrorMsg
207
+ * @param {*} [customErrorMsg]
208
208
  */
209
209
  expectHasProperty(targetData, propertyName, customErrorMsg = '') {
210
210
  // @ts-ignore
@@ -215,7 +215,7 @@ class ExpectHelper {
215
215
  /**
216
216
  * @param {*} targetData
217
217
  * @param {*} propertyName
218
- * @param {*} customErrorMsg
218
+ * @param {*} [customErrorMsg]
219
219
  */
220
220
  expectHasAProperty(targetData, propertyName, customErrorMsg = '') {
221
221
  // @ts-ignore
@@ -226,7 +226,7 @@ class ExpectHelper {
226
226
  /**
227
227
  * @param {*} targetData
228
228
  * @param {*} type
229
- * @param {*} customErrorMsg
229
+ * @param {*} [customErrorMsg]
230
230
  */
231
231
  expectToBeA(targetData, type, customErrorMsg = '') {
232
232
  // @ts-ignore
@@ -237,7 +237,7 @@ class ExpectHelper {
237
237
  /**
238
238
  * @param {*} targetData
239
239
  * @param {*} type
240
- * @param {*} customErrorMsg
240
+ * @param {*} [customErrorMsg]
241
241
  */
242
242
  expectToBeAn(targetData, type, customErrorMsg = '') {
243
243
  // @ts-ignore
@@ -248,7 +248,7 @@ class ExpectHelper {
248
248
  /**
249
249
  * @param {*} targetData
250
250
  * @param {*} regex
251
- * @param {*} customErrorMsg
251
+ * @param {*} [customErrorMsg]
252
252
  */
253
253
  expectMatchRegex(targetData, regex, customErrorMsg = '') {
254
254
  // @ts-ignore
@@ -259,7 +259,7 @@ class ExpectHelper {
259
259
  /**
260
260
  * @param {*} targetData
261
261
  * @param {*} length
262
- * @param {*} customErrorMsg
262
+ * @param {*} [customErrorMsg]
263
263
  */
264
264
  expectLengthOf(targetData, length, customErrorMsg = '') {
265
265
  // @ts-ignore
@@ -269,7 +269,7 @@ class ExpectHelper {
269
269
 
270
270
  /**
271
271
  * @param {*} targetData
272
- * @param {*} customErrorMsg
272
+ * @param {*} [customErrorMsg]
273
273
  */
274
274
  expectEmpty(targetData, customErrorMsg = '') {
275
275
  // @ts-ignore
@@ -279,7 +279,7 @@ class ExpectHelper {
279
279
 
280
280
  /**
281
281
  * @param {*} targetData
282
- * @param {*} customErrorMsg
282
+ * @param {*} [customErrorMsg]
283
283
  */
284
284
  expectTrue(targetData, customErrorMsg = '') {
285
285
  // @ts-ignore
@@ -289,7 +289,7 @@ class ExpectHelper {
289
289
 
290
290
  /**
291
291
  * @param {*} targetData
292
- * @param {*} customErrorMsg
292
+ * @param {*} [customErrorMsg]
293
293
  */
294
294
  expectFalse(targetData, customErrorMsg = '') {
295
295
  // @ts-ignore
@@ -299,8 +299,8 @@ class ExpectHelper {
299
299
 
300
300
  /**
301
301
  * @param {*} targetData
302
- * @param {*} aboveThan number | Date
303
- * @param {*} customErrorMsg
302
+ * @param {*} aboveThan
303
+ * @param {*} [customErrorMsg]
304
304
  */
305
305
  expectAbove(targetData, aboveThan, customErrorMsg = '') {
306
306
  // @ts-ignore
@@ -310,8 +310,8 @@ class ExpectHelper {
310
310
 
311
311
  /**
312
312
  * @param {*} targetData
313
- * @param {*} belowThan number | Date
314
- * @param {*} customErrorMsg
313
+ * @param {*} belowThan
314
+ * @param {*} [customErrorMsg]
315
315
  */
316
316
  expectBelow(targetData, belowThan, customErrorMsg = '') {
317
317
  // @ts-ignore
@@ -322,7 +322,7 @@ class ExpectHelper {
322
322
  /**
323
323
  * @param {*} targetData
324
324
  * @param {*} lengthAboveThan
325
- * @param {*} customErrorMsg
325
+ * @param {*} [customErrorMsg]
326
326
  */
327
327
  expectLengthAboveThan(targetData, lengthAboveThan, customErrorMsg = '') {
328
328
  // @ts-ignore
@@ -335,7 +335,7 @@ class ExpectHelper {
335
335
  /**
336
336
  * @param {*} targetData
337
337
  * @param {*} lengthBelowThan
338
- * @param {*} customErrorMsg
338
+ * @param {*} [customErrorMsg]
339
339
  */
340
340
  expectLengthBelowThan(targetData, lengthBelowThan, customErrorMsg = '') {
341
341
  // @ts-ignore
@@ -348,7 +348,7 @@ class ExpectHelper {
348
348
  /**
349
349
  * @param {*} actualValue
350
350
  * @param {*} expectedValue
351
- * @param {*} customErrorMsg
351
+ * @param {*} [customErrorMsg]
352
352
  */
353
353
  expectEqualIgnoreCase(actualValue, expectedValue, customErrorMsg = '') {
354
354
  // @ts-ignore
@@ -362,7 +362,7 @@ class ExpectHelper {
362
362
  * expects members of two arrays are deeply equal
363
363
  * @param {*} actualValue
364
364
  * @param {*} expectedValue
365
- * @param {*} customErrorMsg
365
+ * @param {*} [customErrorMsg]
366
366
  */
367
367
  expectDeepMembers(actualValue, expectedValue, customErrorMsg = '') {
368
368
  // @ts-ignore
@@ -376,7 +376,7 @@ class ExpectHelper {
376
376
  * expects an array to be a superset of another array
377
377
  * @param {*} superset
378
378
  * @param {*} set
379
- * @param {*} customErrorMsg
379
+ * @param {*} [customErrorMsg]
380
380
  */
381
381
  expectDeepIncludeMembers(superset, set, customErrorMsg = '') {
382
382
  // @ts-ignore
@@ -391,7 +391,7 @@ class ExpectHelper {
391
391
  * @param {*} actualValue
392
392
  * @param {*} expectedValue
393
393
  * @param {*} fieldsToExclude
394
- * @param {*} customErrorMsg
394
+ * @param {*} [customErrorMsg]
395
395
  */
396
396
  expectDeepEqualExcluding(
397
397
  actualValue,
@@ -410,7 +410,7 @@ class ExpectHelper {
410
410
  * expects a JSON object matches a provided pattern
411
411
  * @param {*} actualValue
412
412
  * @param {*} expectedPattern
413
- * @param {*} customErrorMsg
413
+ * @param {*} [customErrorMsg]
414
414
  */
415
415
  expectMatchesPattern(actualValue, expectedPattern, customErrorMsg = '') {
416
416
  // @ts-ignore
@@ -33,7 +33,7 @@ const ElementNotFound = require('./errors/ElementNotFound');
33
33
  const RemoteBrowserConnectionRefused = require('./errors/RemoteBrowserConnectionRefused');
34
34
  const Popup = require('./extras/Popup');
35
35
  const Console = require('./extras/Console');
36
- const findReact = require('./extras/React');
36
+ const { findReact, findVue } = require('./extras/PlaywrightReactVueLocator');
37
37
 
38
38
  let playwright;
39
39
  let perfTiming;
@@ -517,8 +517,9 @@ class Playwright extends Helper {
517
517
  if (this.options.userAgent) contextOptions.userAgent = this.options.userAgent;
518
518
  if (this.options.locale) contextOptions.locale = this.options.locale;
519
519
  if (this.options.colorScheme) contextOptions.colorScheme = this.options.colorScheme;
520
+ this.contextOptions = contextOptions;
520
521
  if (!this.browserContext || !restartsSession()) {
521
- this.browserContext = await this.browser.newContext(contextOptions); // Adding the HTTPSError ignore in the context so that we can ignore those errors
522
+ this.browserContext = await this.browser.newContext(this.contextOptions); // Adding the HTTPSError ignore in the context so that we can ignore those errors
522
523
  }
523
524
  }
524
525
 
@@ -606,7 +607,7 @@ class Playwright extends Helper {
606
607
  page = await browser.firstWindow();
607
608
  } else {
608
609
  try {
609
- browserContext = await this.browser.newContext(Object.assign(this.options, config));
610
+ browserContext = await this.browser.newContext(Object.assign(this.contextOptions, config));
610
611
  page = await browserContext.newPage();
611
612
  } catch (e) {
612
613
  if (this.playwrightOptions.userDataDir) {
@@ -666,7 +667,7 @@ class Playwright extends Helper {
666
667
  * ```
667
668
  *
668
669
  * @param {string} description used to show in logs.
669
- * @param {function} fn async function that executed with Playwright helper as argumen
670
+ * @param {function} fn async function that executed with Playwright helper as arguments
670
671
  */
671
672
  usePlaywrightTo(description, fn) {
672
673
  return this._useTo(...arguments);
@@ -946,10 +947,9 @@ class Playwright extends Helper {
946
947
  }
947
948
 
948
949
  /**
949
- * {{> resizeWindow }}
950
950
  *
951
951
  * Unlike other drivers Playwright changes the size of a viewport, not the window!
952
- * Playwright does not control the window of a browser so it can't adjust its real size.
952
+ * Playwright does not control the window of a browser, so it can't adjust its real size.
953
953
  * It also can't maximize a window.
954
954
  *
955
955
  * Update configuration to change real window size on start:
@@ -959,6 +959,8 @@ class Playwright extends Helper {
959
959
  * // @codeceptjs/configure package must be installed
960
960
  * { setWindowSize } = require('@codeceptjs/configure');
961
961
  * ````
962
+ *
963
+ * {{> resizeWindow }}
962
964
  */
963
965
  async resizeWindow(width, height) {
964
966
  if (width === 'maximize') {
@@ -1058,8 +1060,6 @@ class Playwright extends Helper {
1058
1060
  }
1059
1061
 
1060
1062
  /**
1061
- * {{> dragAndDrop }}
1062
- * @param {any} [options] [Additional options](https://playwright.dev/docs/api/class-page#page-drag-and-drop) can be passed as 3rd argument.
1063
1063
  *
1064
1064
  * ```js
1065
1065
  * // specify coordinates for source position
@@ -1067,6 +1067,10 @@ class Playwright extends Helper {
1067
1067
  * ```
1068
1068
  *
1069
1069
  * > When no option is set, custom drag and drop would be used, to use the dragAndDrop API from Playwright, please set options, for example `force: true`
1070
+ *
1071
+ * {{> dragAndDrop }}
1072
+ * @param {any} [options] [Additional options](https://playwright.dev/docs/api/class-page#page-drag-and-drop) can be passed as 3rd argument.
1073
+ *
1070
1074
  */
1071
1075
  async dragAndDrop(srcElement, destElement, options) {
1072
1076
  const src = new Locator(srcElement);
@@ -1514,7 +1518,7 @@ class Playwright extends Helper {
1514
1518
  *
1515
1519
  * @param {any} [options] [Additional options](https://playwright.dev/docs/api/class-page#page-click) for click available as 3rd argument.
1516
1520
  *
1517
- * Examples:
1521
+ * @example
1518
1522
  *
1519
1523
  * ```js
1520
1524
  * // click on element at position
@@ -1547,8 +1551,6 @@ class Playwright extends Helper {
1547
1551
 
1548
1552
  /**
1549
1553
  * {{> doubleClick }}
1550
- *
1551
- *
1552
1554
  */
1553
1555
  async doubleClick(locator, context = null) {
1554
1556
  return proceedClick.call(this, locator, context, { clickCount: 2 });
@@ -1556,15 +1558,12 @@ class Playwright extends Helper {
1556
1558
 
1557
1559
  /**
1558
1560
  * {{> rightClick }}
1559
- *
1560
- *
1561
1561
  */
1562
1562
  async rightClick(locator, context = null) {
1563
1563
  return proceedClick.call(this, locator, context, { button: 'right' });
1564
1564
  }
1565
1565
 
1566
1566
  /**
1567
- * {{> checkOption }}
1568
1567
  *
1569
1568
  * [Additional options](https://playwright.dev/docs/api/class-elementhandle#element-handle-check) for check available as 3rd argument.
1570
1569
  *
@@ -1575,6 +1574,9 @@ class Playwright extends Helper {
1575
1574
  * I.checkOption('Agree', '.signup', { position: { x: 5, y: 5 } })
1576
1575
  * ```
1577
1576
  * > ⚠️ To avoid flakiness, option `force: true` is set by default
1577
+ *
1578
+ * {{> checkOption }}
1579
+ *
1578
1580
  */
1579
1581
  async checkOption(field, context = null, options = { force: true }) {
1580
1582
  const elm = await this._locateCheckable(field, context);
@@ -1583,7 +1585,6 @@ class Playwright extends Helper {
1583
1585
  }
1584
1586
 
1585
1587
  /**
1586
- * {{> uncheckOption }}
1587
1588
  *
1588
1589
  * [Additional options](https://playwright.dev/docs/api/class-elementhandle#element-handle-uncheck) for uncheck available as 3rd argument.
1589
1590
  *
@@ -1594,6 +1595,8 @@ class Playwright extends Helper {
1594
1595
  * I.uncheckOption('Agree', '.signup', { position: { x: 5, y: 5 } })
1595
1596
  * ```
1596
1597
  * > ⚠️ To avoid flakiness, option `force: true` is set by default
1598
+ *
1599
+ * {{> uncheckOption }}
1597
1600
  */
1598
1601
  async uncheckOption(field, context = null, options = { force: true }) {
1599
1602
  const elm = await this._locateCheckable(field, context);
@@ -1634,9 +1637,10 @@ class Playwright extends Helper {
1634
1637
  }
1635
1638
 
1636
1639
  /**
1637
- * {{> pressKeyWithKeyNormalization }}
1638
1640
  *
1639
1641
  * _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/Puppeteer#1313](https://github.com/GoogleChrome/puppeteer/issues/1313)).
1642
+ *
1643
+ * {{> pressKeyWithKeyNormalization }}
1640
1644
  */
1641
1645
  async pressKey(key) {
1642
1646
  const modifiers = [];
@@ -1728,8 +1732,6 @@ class Playwright extends Helper {
1728
1732
 
1729
1733
  /**
1730
1734
  * {{> appendField }}
1731
- *
1732
- *
1733
1735
  */
1734
1736
  async appendField(field, value) {
1735
1737
  const els = await findFields.call(this, field);
@@ -1953,9 +1955,9 @@ class Playwright extends Helper {
1953
1955
  }
1954
1956
 
1955
1957
  /**
1956
- * {{> grabCookie }}
1957
- *
1958
1958
  * Returns cookie in JSON format. If name not passed returns all cookies for this domain.
1959
+ *
1960
+ * {{> grabCookie }}
1959
1961
  */
1960
1962
  async grabCookie(name) {
1961
1963
  const cookies = await this.browserContext.cookies();
@@ -1986,8 +1988,8 @@ class Playwright extends Helper {
1986
1988
  * ```js
1987
1989
  * I.executeScript(({x, y}) => x + y, {x, y});
1988
1990
  * ```
1989
- * You can pass only one parameter into a function
1990
- * but you can pass in array or object.
1991
+ * You can pass only one parameter into a function,
1992
+ * or you can pass in array or object.
1991
1993
  *
1992
1994
  * ```js
1993
1995
  * I.executeScript(([x, y]) => x + y, [x, y]);
@@ -2167,7 +2169,8 @@ class Playwright extends Helper {
2167
2169
  let chunked = chunkArray(attrs, values.length);
2168
2170
  chunked = chunked.filter((val) => {
2169
2171
  for (let i = 0; i < val.length; ++i) {
2170
- if (!val[i].includes(values[i])) return false;
2172
+ // if the attribute doesn't exist, returns false as well
2173
+ if (!val[i] || !val[i].includes(values[i])) return false;
2171
2174
  }
2172
2175
  return true;
2173
2176
  });
@@ -2493,9 +2496,9 @@ class Playwright extends Helper {
2493
2496
  }
2494
2497
 
2495
2498
  /**
2496
- * {{> waitForVisible }}
2497
- *
2498
2499
  * This method accepts [React selectors](https://codecept.io/react).
2500
+ *
2501
+ * {{> waitForVisible }}
2499
2502
  */
2500
2503
  async waitForVisible(locator, sec) {
2501
2504
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -2581,6 +2584,24 @@ class Playwright extends Helper {
2581
2584
  });
2582
2585
  }
2583
2586
 
2587
+ /**
2588
+ * {{> waitForNumberOfTabs }}
2589
+ */
2590
+ async waitForNumberOfTabs(expectedTabs, sec) {
2591
+ const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
2592
+ let currentTabs;
2593
+ let count = 0;
2594
+
2595
+ do {
2596
+ currentTabs = await this.grabNumberOfOpenTabs();
2597
+ await this.wait(1);
2598
+ count += 1000;
2599
+ if (currentTabs >= expectedTabs) return;
2600
+ } while (count <= waitTimeout);
2601
+
2602
+ throw new Error(`Expected ${expectedTabs} tabs are not met after ${waitTimeout / 1000} sec.`);
2603
+ }
2604
+
2584
2605
  async _getContext() {
2585
2606
  if (this.context && this.context.constructor.name === 'FrameLocator') {
2586
2607
  return this.context;
@@ -3260,7 +3281,7 @@ class Playwright extends Helper {
3260
3281
  /**
3261
3282
  * Returns all URLs of all network requests recorded so far during execution of test scenario.
3262
3283
  *
3263
- * @return {string} List of URLs recorded as a string, seperaeted by new lines after each URL
3284
+ * @return {string} List of URLs recorded as a string, separated by new lines after each URL
3264
3285
  * @private
3265
3286
  */
3266
3287
  _getTrafficDump() {
@@ -3442,6 +3463,7 @@ function buildLocatorString(locator) {
3442
3463
 
3443
3464
  async function findElements(matcher, locator) {
3444
3465
  if (locator.react) return findReact(matcher, locator);
3466
+ if (locator.vue) return findVue(matcher, locator);
3445
3467
  locator = new Locator(locator, 'css');
3446
3468
 
3447
3469
  return matcher.locator(buildLocatorString(locator)).all();
@@ -3503,6 +3525,7 @@ async function proceedClick(locator, context = null, options = {}) {
3503
3525
 
3504
3526
  async function findClickable(matcher, locator) {
3505
3527
  if (locator.react) return findReact(matcher, locator);
3528
+ if (locator.vue) return findVue(matcher, locator);
3506
3529
 
3507
3530
  locator = new Locator(locator);
3508
3531
  if (!locator.isFuzzy()) return findElements.call(this, matcher, locator);