codeceptjs 3.5.5 → 3.5.7-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 (151) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/docs/bdd.md +11 -7
  3. package/docs/build/ApiDataFactory.js +2 -1
  4. package/docs/build/Appium.js +25 -23
  5. package/docs/build/Expect.js +422 -0
  6. package/docs/build/FileSystem.js +1 -1
  7. package/docs/build/Nightmare.js +53 -56
  8. package/docs/build/Playwright.js +209 -135
  9. package/docs/build/Protractor.js +66 -69
  10. package/docs/build/Puppeteer.js +83 -83
  11. package/docs/build/TestCafe.js +56 -55
  12. package/docs/build/WebDriver.js +85 -86
  13. package/docs/changelog.md +63 -0
  14. package/docs/commands.md +12 -0
  15. package/docs/helpers/Appium.md +50 -32
  16. package/docs/helpers/Expect.md +275 -0
  17. package/docs/helpers/FileSystem.md +1 -1
  18. package/docs/helpers/Nightmare.md +141 -94
  19. package/docs/helpers/Playwright.md +281 -212
  20. package/docs/helpers/Protractor.md +229 -169
  21. package/docs/helpers/Puppeteer.md +257 -186
  22. package/docs/helpers/TestCafe.md +201 -149
  23. package/docs/helpers/WebDriver.md +253 -179
  24. package/docs/mobile.md +17 -21
  25. package/docs/plugins.md +35 -1
  26. package/docs/webapi/amOnPage.mustache +1 -1
  27. package/docs/webapi/appendField.mustache +1 -1
  28. package/docs/webapi/attachFile.mustache +1 -1
  29. package/docs/webapi/blur.mustache +1 -0
  30. package/docs/webapi/checkOption.mustache +1 -1
  31. package/docs/webapi/clearCookie.mustache +1 -1
  32. package/docs/webapi/clearField.mustache +1 -1
  33. package/docs/webapi/click.mustache +1 -1
  34. package/docs/webapi/clickLink.mustache +1 -1
  35. package/docs/webapi/closeCurrentTab.mustache +1 -1
  36. package/docs/webapi/closeOtherTabs.mustache +1 -1
  37. package/docs/webapi/dontSee.mustache +1 -1
  38. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +1 -1
  39. package/docs/webapi/dontSeeCookie.mustache +1 -1
  40. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +1 -1
  41. package/docs/webapi/dontSeeElement.mustache +1 -1
  42. package/docs/webapi/dontSeeElementInDOM.mustache +1 -1
  43. package/docs/webapi/dontSeeInCurrentUrl.mustache +1 -1
  44. package/docs/webapi/dontSeeInField.mustache +1 -1
  45. package/docs/webapi/dontSeeInSource.mustache +1 -1
  46. package/docs/webapi/dontSeeInTitle.mustache +1 -1
  47. package/docs/webapi/doubleClick.mustache +1 -1
  48. package/docs/webapi/downloadFile.mustache +1 -1
  49. package/docs/webapi/dragAndDrop.mustache +1 -1
  50. package/docs/webapi/dragSlider.mustache +1 -1
  51. package/docs/webapi/executeAsyncScript.mustache +0 -2
  52. package/docs/webapi/executeScript.mustache +0 -2
  53. package/docs/webapi/fillField.mustache +1 -1
  54. package/docs/webapi/focus.mustache +1 -0
  55. package/docs/webapi/forceClick.mustache +1 -1
  56. package/docs/webapi/forceRightClick.mustache +1 -1
  57. package/docs/webapi/grabCookie.mustache +1 -1
  58. package/docs/webapi/grabDataFromPerformanceTiming.mustache +1 -1
  59. package/docs/webapi/moveCursorTo.mustache +1 -1
  60. package/docs/webapi/openNewTab.mustache +1 -1
  61. package/docs/webapi/pressKey.mustache +1 -1
  62. package/docs/webapi/pressKeyDown.mustache +1 -1
  63. package/docs/webapi/pressKeyUp.mustache +1 -1
  64. package/docs/webapi/pressKeyWithKeyNormalization.mustache +1 -1
  65. package/docs/webapi/refreshPage.mustache +1 -1
  66. package/docs/webapi/resizeWindow.mustache +1 -1
  67. package/docs/webapi/rightClick.mustache +1 -1
  68. package/docs/webapi/saveElementScreenshot.mustache +1 -1
  69. package/docs/webapi/saveScreenshot.mustache +1 -1
  70. package/docs/webapi/say.mustache +1 -1
  71. package/docs/webapi/scrollIntoView.mustache +1 -1
  72. package/docs/webapi/scrollPageToBottom.mustache +1 -1
  73. package/docs/webapi/scrollPageToTop.mustache +1 -1
  74. package/docs/webapi/scrollTo.mustache +1 -1
  75. package/docs/webapi/see.mustache +1 -1
  76. package/docs/webapi/seeAttributesOnElements.mustache +1 -1
  77. package/docs/webapi/seeCheckboxIsChecked.mustache +1 -1
  78. package/docs/webapi/seeCookie.mustache +1 -1
  79. package/docs/webapi/seeCssPropertiesOnElements.mustache +1 -1
  80. package/docs/webapi/seeCurrentUrlEquals.mustache +1 -1
  81. package/docs/webapi/seeElement.mustache +1 -1
  82. package/docs/webapi/seeElementInDOM.mustache +1 -1
  83. package/docs/webapi/seeInCurrentUrl.mustache +1 -1
  84. package/docs/webapi/seeInField.mustache +1 -1
  85. package/docs/webapi/seeInPopup.mustache +1 -1
  86. package/docs/webapi/seeInSource.mustache +1 -1
  87. package/docs/webapi/seeInTitle.mustache +1 -1
  88. package/docs/webapi/seeNumberOfElements.mustache +1 -1
  89. package/docs/webapi/seeNumberOfVisibleElements.mustache +1 -1
  90. package/docs/webapi/seeTextEquals.mustache +1 -1
  91. package/docs/webapi/seeTitleEquals.mustache +1 -1
  92. package/docs/webapi/selectOption.mustache +1 -1
  93. package/docs/webapi/setCookie.mustache +1 -1
  94. package/docs/webapi/setGeoLocation.mustache +1 -1
  95. package/docs/webapi/switchTo.mustache +1 -1
  96. package/docs/webapi/switchToNextTab.mustache +1 -1
  97. package/docs/webapi/switchToPreviousTab.mustache +1 -1
  98. package/docs/webapi/type.mustache +1 -1
  99. package/docs/webapi/uncheckOption.mustache +1 -1
  100. package/docs/webapi/wait.mustache +1 -1
  101. package/docs/webapi/waitForClickable.mustache +1 -1
  102. package/docs/webapi/waitForDetached.mustache +1 -1
  103. package/docs/webapi/waitForElement.mustache +1 -1
  104. package/docs/webapi/waitForEnabled.mustache +1 -1
  105. package/docs/webapi/waitForFunction.mustache +1 -1
  106. package/docs/webapi/waitForInvisible.mustache +1 -1
  107. package/docs/webapi/waitForText.mustache +1 -1
  108. package/docs/webapi/waitForValue.mustache +1 -1
  109. package/docs/webapi/waitForVisible.mustache +1 -1
  110. package/docs/webapi/waitInUrl.mustache +1 -1
  111. package/docs/webapi/waitNumberOfVisibleElements.mustache +1 -1
  112. package/docs/webapi/waitToHide.mustache +1 -1
  113. package/docs/webapi/waitUrlEquals.mustache +1 -1
  114. package/lib/ai.js +12 -3
  115. package/lib/cli.js +3 -1
  116. package/lib/codecept.js +3 -0
  117. package/lib/command/dryRun.js +2 -1
  118. package/lib/command/info.js +24 -0
  119. package/lib/command/run-workers.js +3 -2
  120. package/lib/command/run.js +3 -2
  121. package/lib/data/context.js +14 -6
  122. package/lib/helper/ApiDataFactory.js +2 -1
  123. package/lib/helper/Appium.js +7 -5
  124. package/lib/helper/Expect.js +422 -0
  125. package/lib/helper/FileSystem.js +1 -1
  126. package/lib/helper/Playwright.js +134 -64
  127. package/lib/helper/Puppeteer.js +6 -6
  128. package/lib/helper/WebDriver.js +4 -4
  129. package/lib/helper/scripts/highlightElement.js +1 -1
  130. package/lib/html.js +3 -3
  131. package/lib/interfaces/gherkin.js +21 -2
  132. package/lib/output.js +1 -1
  133. package/lib/pause.js +6 -5
  134. package/lib/plugin/autoLogin.js +35 -8
  135. package/lib/plugin/heal.js +40 -7
  136. package/lib/plugin/retryTo.js +0 -2
  137. package/lib/plugin/tryTo.js +0 -3
  138. package/lib/recorder.js +12 -5
  139. package/lib/session.js +1 -1
  140. package/package.json +24 -17
  141. package/translations/de-DE.js +5 -0
  142. package/translations/fr-FR.js +14 -1
  143. package/translations/it-IT.js +1 -0
  144. package/translations/ja-JP.js +5 -0
  145. package/translations/pl-PL.js +5 -0
  146. package/translations/pt-BR.js +1 -0
  147. package/translations/ru-RU.js +1 -0
  148. package/translations/zh-CN.js +5 -0
  149. package/translations/zh-TW.js +5 -0
  150. package/typings/promiseBasedTypes.d.ts +905 -863
  151. package/typings/types.d.ts +909 -850
@@ -61,7 +61,7 @@ const defaultConfig = {
61
61
  * #### How It Works
62
62
  *
63
63
  * 1. `restore` method is executed. It should open a page and set credentials.
64
- * 2. `check` method is executed. It should reload a page (so cookies are applied) and check that this page belongs to logged in user.
64
+ * 2. `check` method is executed. It should reload a page (so cookies are applied) and check that this page belongs to logged-in user. When you pass the second args `session`, you could perform the validation using passed session.
65
65
  * 3. If `restore` and `check` were not successful, `login` is executed
66
66
  * 4. `login` should fill in login form
67
67
  * 5. After successful login, `fetch` is executed to save cookies into memory or file.
@@ -212,6 +212,38 @@ const defaultConfig = {
212
212
  * })
213
213
  * ```
214
214
  *
215
+ * #### Tips: Using session to validate user
216
+ *
217
+ * Instead of asserting on page elements for the current user in `check`, you can use the `session` you saved in `fetch`
218
+ *
219
+ * ```js
220
+ * autoLogin: {
221
+ * enabled: true,
222
+ * saveToFile: true,
223
+ * inject: 'login',
224
+ * users: {
225
+ * admin: {
226
+ * login: async (I) => { // If you use async function in the autoLogin plugin
227
+ * const phrase = await I.grabTextFrom('#phrase')
228
+ * I.fillField('username', 'admin'),
229
+ * I.fillField('password', 'password')
230
+ * I.fillField('phrase', phrase)
231
+ * },
232
+ * check: (I, session) => {
233
+ * // Throwing an error in `check` will make CodeceptJS perform the login step for the user
234
+ * if (session.profile.email !== the.email.you.expect@some-mail.com) {
235
+ * throw new Error ('Wrong user signed in');
236
+ * }
237
+ * },
238
+ * }
239
+ * }
240
+ * }
241
+ * ```
242
+ *
243
+ * ```js
244
+ * Scenario('login', async ( {I, login} ) => {
245
+ * await login('admin') // you should use `await`
246
+ * })
215
247
  *
216
248
  *
217
249
  */
@@ -251,27 +283,23 @@ module.exports = function (config) {
251
283
  } else {
252
284
  userSession.login(I);
253
285
  }
254
- store.debugMode = true;
255
286
  const cookies = await userSession.fetch(I);
256
287
  if (config.saveToFile) {
257
288
  debug(`Saved user session into file for ${name}`);
258
289
  fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies));
259
290
  }
260
291
  store[`${name}_session`] = cookies;
261
- store.debugMode = false;
262
292
  };
263
293
 
264
294
  if (!cookies) return loginAndSave();
265
295
 
266
- store.debugMode = true;
267
-
268
296
  recorder.session.start('check login');
269
297
  if (shouldAwait) {
270
298
  await userSession.restore(I, cookies);
271
- await userSession.check(I);
299
+ await userSession.check(I, cookies);
272
300
  } else {
273
301
  userSession.restore(I, cookies);
274
- userSession.check(I);
302
+ userSession.check(I, cookies);
275
303
  }
276
304
  recorder.session.catch((err) => {
277
305
  debug(`Failed auto login for ${name} due to ${err}`);
@@ -287,7 +315,6 @@ module.exports = function (config) {
287
315
  });
288
316
  });
289
317
  recorder.add(() => {
290
- store.debugMode = false;
291
318
  recorder.session.restore('check login');
292
319
  });
293
320
 
@@ -8,6 +8,7 @@ const output = require('../output');
8
8
  const supportedHelpers = require('./standardActingHelpers');
9
9
 
10
10
  const defaultConfig = {
11
+ healTries: 1,
11
12
  healLimit: 2,
12
13
  healSteps: [
13
14
  'click',
@@ -54,11 +55,14 @@ const defaultConfig = {
54
55
  *
55
56
  */
56
57
  module.exports = function (config = {}) {
57
- const aiAssistant = new AiAssistant();
58
+ const aiAssistant = AiAssistant.getInstance();
58
59
 
59
60
  let currentTest = null;
60
61
  let currentStep = null;
61
62
  let healedSteps = 0;
63
+ let caughtError;
64
+ let healTries = 0;
65
+ let isHealing = false;
62
66
 
63
67
  const healSuggestions = [];
64
68
 
@@ -67,20 +71,35 @@ module.exports = function (config = {}) {
67
71
  event.dispatcher.on(event.test.before, (test) => {
68
72
  currentTest = test;
69
73
  healedSteps = 0;
74
+ caughtError = null;
70
75
  });
71
76
 
72
77
  event.dispatcher.on(event.step.started, step => currentStep = step);
73
78
 
74
- event.dispatcher.on(event.step.before, () => {
79
+ event.dispatcher.on(event.step.after, (step) => {
80
+ if (isHealing) return;
75
81
  const store = require('../store');
76
82
  if (store.debugMode) return;
77
-
78
83
  recorder.catchWithoutStop(async (err) => {
79
- if (!aiAssistant.isEnabled) throw err;
84
+ isHealing = true;
85
+ if (caughtError === err) throw err; // avoid double handling
86
+ caughtError = err;
87
+ if (!aiAssistant.isEnabled) {
88
+ output.print(colors.yellow('Heal plugin can\'t operate, AI assistant is disabled. Please set OPENAI_API_KEY env variable to enable it.'));
89
+ throw err;
90
+ }
80
91
  if (!currentStep) throw err;
81
92
  if (!config.healSteps.includes(currentStep.name)) throw err;
82
93
  const test = currentTest;
83
94
 
95
+ if (healTries >= config.healTries) {
96
+ output.print(colors.bold.red(`Healing failed for ${config.healTries} time(s)`));
97
+ output.print('AI couldn\'t identify the correct solution');
98
+ output.print('Probably the entire flow has changed and the test should be updated');
99
+
100
+ throw err;
101
+ }
102
+
84
103
  if (healedSteps >= config.healLimit) {
85
104
  output.print(colors.bold.red(`Can't heal more than ${config.healLimit} step(s) in a test`));
86
105
  output.print('Entire flow can be broken, please check it manually');
@@ -111,9 +130,17 @@ module.exports = function (config = {}) {
111
130
 
112
131
  if (!html) throw err;
113
132
 
114
- aiAssistant.setHtmlContext(html);
133
+ healTries++;
134
+ await aiAssistant.setHtmlContext(html);
115
135
  await tryToHeal(step, err);
116
- recorder.session.restore();
136
+
137
+ recorder.add('close healing session', () => {
138
+ recorder.session.restore('heal');
139
+ recorder.ignoreErr(err);
140
+ });
141
+ await recorder.promise();
142
+
143
+ isHealing = false;
117
144
  });
118
145
  });
119
146
 
@@ -155,6 +182,9 @@ module.exports = function (config = {}) {
155
182
  for (const codeSnippet of codeSnippets) {
156
183
  try {
157
184
  debug('Executing', codeSnippet);
185
+ recorder.catch((e) => {
186
+ console.log(e);
187
+ });
158
188
  await eval(codeSnippet); // eslint-disable-line
159
189
 
160
190
  healSuggestions.push({
@@ -163,14 +193,17 @@ module.exports = function (config = {}) {
163
193
  snippet: codeSnippet,
164
194
  });
165
195
 
166
- output.print(colors.bold.green(' Code healed successfully'));
196
+ recorder.add('healed', () => output.print(colors.bold.green(' Code healed successfully')));
167
197
  healedSteps++;
168
198
  return;
169
199
  } catch (err) {
170
200
  debug('Failed to execute code', err);
201
+ recorder.ignoreErr(err); // healing ded not help
202
+ // recorder.catch(() => output.print(colors.bold.red(' Failed healing code')));
171
203
  }
172
204
  }
173
205
 
174
206
  output.debug(`Couldn't heal the code for ${failedStep.toCode()}`);
175
207
  }
208
+ return recorder.promise();
176
209
  };
@@ -83,7 +83,6 @@ module.exports = function (config) {
83
83
  return retryTo;
84
84
 
85
85
  function retryTo(callback, maxTries, pollInterval = undefined) {
86
- const mode = store.debugMode;
87
86
  let tries = 1;
88
87
  if (!pollInterval) pollInterval = config.pollInterval;
89
88
 
@@ -113,7 +112,6 @@ module.exports = function (config) {
113
112
  };
114
113
 
115
114
  recorder.add('retryTo', async () => {
116
- store.debugMode = true;
117
115
  tryBlock();
118
116
  });
119
117
  }).then(() => {
@@ -81,10 +81,8 @@ module.exports = function (config) {
81
81
  };
82
82
 
83
83
  function tryTo(callback) {
84
- const mode = store.debugMode;
85
84
  let result = false;
86
85
  return recorder.add('tryTo', () => {
87
- store.debugMode = true;
88
86
  recorder.session.start('tryTo');
89
87
  callback();
90
88
  recorder.add(() => {
@@ -100,7 +98,6 @@ function tryTo(callback) {
100
98
  return result;
101
99
  });
102
100
  return recorder.add('result', () => {
103
- store.debugMode = mode;
104
101
  return result;
105
102
  }, true, false);
106
103
  }, false, false);
package/lib/recorder.js CHANGED
@@ -11,6 +11,7 @@ let errFn;
11
11
  let queueId = 0;
12
12
  let sessionId = null;
13
13
  let asyncErr = null;
14
+ let ignoredErrs = [];
14
15
 
15
16
  let tasks = [];
16
17
  let oldPromises = [];
@@ -93,6 +94,7 @@ module.exports = {
93
94
  promise = Promise.resolve();
94
95
  oldPromises = [];
95
96
  tasks = [];
97
+ ignoredErrs = [];
96
98
  this.session.running = false;
97
99
  // reset this retries makes the retryFailedStep plugin won't work if there is Before/BeforeSuit block due to retries is undefined on Scenario
98
100
  // this.retries = [];
@@ -226,9 +228,10 @@ module.exports = {
226
228
  * @inner
227
229
  */
228
230
  catch(customErrFn) {
229
- debug(`${currentQueue()}Queued | catch with error handler`);
231
+ const fnDescription = customErrFn?.toString()?.replace(/\s{2,}/g, ' ').replace(/\n/g, ' ')?.slice(0, 50);
232
+ debug(`${currentQueue()}Queued | catch with error handler ${fnDescription || ''}`);
230
233
  return promise = promise.catch((err) => {
231
- log(`${currentQueue()}Error | ${err}`);
234
+ log(`${currentQueue()}Error | ${err} ${fnDescription}...`);
232
235
  if (!(err instanceof Error)) { // strange things may happen
233
236
  err = new Error(`[Wrapped Error] ${printObjectProperties(err)}`); // we should be prepared for them
234
237
  }
@@ -247,15 +250,15 @@ module.exports = {
247
250
  * @inner
248
251
  */
249
252
  catchWithoutStop(customErrFn) {
253
+ const fnDescription = customErrFn?.toString()?.replace(/\s{2,}/g, ' ').replace(/\n/g, ' ')?.slice(0, 50);
250
254
  return promise = promise.catch((err) => {
251
- log(`${currentQueue()}Error | ${err}`);
255
+ if (ignoredErrs.includes(err)) return; // already caught
256
+ log(`${currentQueue()}Error (Non-Terminated) | ${err} | ${fnDescription || ''}...`);
252
257
  if (!(err instanceof Error)) { // strange things may happen
253
258
  err = new Error(`[Wrapped Error] ${JSON.stringify(err)}`); // we should be prepared for them
254
259
  }
255
260
  if (customErrFn) {
256
261
  return customErrFn(err);
257
- } if (errFn) {
258
- return errFn(err);
259
262
  }
260
263
  });
261
264
  },
@@ -274,6 +277,10 @@ module.exports = {
274
277
  });
275
278
  },
276
279
 
280
+ ignoreErr(err) {
281
+ ignoredErrs.push(err);
282
+ },
283
+
277
284
  /**
278
285
  * @param {*} err
279
286
  * @inner
package/lib/session.js CHANGED
@@ -19,7 +19,7 @@ const savedSessions = {};
19
19
  * @param {CodeceptJS.LocatorOrString} sessionName
20
20
  * @param {Function | Object<string, *>} config
21
21
  * @param {Function} [fn]
22
- * @return {Promise<*> | undefined}
22
+ * @return {any}
23
23
  */
24
24
  function session(sessionName, config, fn) {
25
25
  if (typeof config === 'function') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.5.5",
3
+ "version": "3.5.7-beta.1",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -40,8 +40,8 @@
40
40
  "lint": "eslint bin/ examples/ lib/ test/ translations/ runok.js",
41
41
  "lint-fix": "eslint bin/ examples/ lib/ test/ translations/ runok.js --fix",
42
42
  "docs": "./runok.js docs",
43
- "test:unit": "mocha test/unit --recursive --timeout 5000",
44
- "test:runner": "mocha test/runner --recursive --timeout 5000",
43
+ "test:unit": "mocha test/unit --recursive --timeout 10000",
44
+ "test:runner": "mocha test/runner --recursive --timeout 10000",
45
45
  "test": "npm run test:unit && npm run test:runner",
46
46
  "test:appium-quick": "mocha test/helper/Appium_test.js --grep 'quick'",
47
47
  "test:appium-other": "mocha test/helper/Appium_test.js --grep 'second'",
@@ -51,6 +51,7 @@
51
51
  "test:unit:webbapi:puppeteer": "mocha test/helper/Puppeteer_test.js",
52
52
  "test:unit:webbapi:webDriver": "mocha test/helper/WebDriver_test.js",
53
53
  "test:unit:webbapi:testCafe": "mocha test/helper/TestCafe_test.js",
54
+ "test:unit:expect": "mocha test/helper/Expect_test.js",
54
55
  "def": "./runok.js def",
55
56
  "dev:graphql": "node test/data/graphql/index.js",
56
57
  "publish:site": "./runok.js publish:site",
@@ -68,8 +69,13 @@
68
69
  "acorn": "8.10.0",
69
70
  "arrify": "2.0.1",
70
71
  "axios": "1.3.3",
71
- "chai": "4.3.6",
72
+ "chai": "4.3.8",
72
73
  "chai-deep-match": "1.2.1",
74
+ "chai-exclude": "^2.1.0",
75
+ "chai-json-schema": "^1.5.1",
76
+ "chai-json-schema-ajv": "^5.2.4",
77
+ "chai-match-pattern": "^1.3.0",
78
+ "chai-string": "^1.5.0",
73
79
  "chalk": "4.1.2",
74
80
  "commander": "11.0.0",
75
81
  "cross-spawn": "7.0.3",
@@ -80,10 +86,10 @@
80
86
  "fn-args": "4.0.0",
81
87
  "fs-extra": "8.1.0",
82
88
  "glob": "6.0.1",
83
- "html-minifier": "4.0.0",
89
+ "html-minifier-terser": "^7.2.0",
84
90
  "inquirer": "6.5.2",
85
91
  "joi": "17.6.0",
86
- "js-beautify": "1.14.0",
92
+ "js-beautify": "1.14.9",
87
93
  "lodash.clonedeep": "4.5.0",
88
94
  "lodash.merge": "4.6.2",
89
95
  "mkdirp": "1.0.4",
@@ -102,49 +108,50 @@
102
108
  "@codeceptjs/detox-helper": "1.0.2",
103
109
  "@codeceptjs/mock-request": "0.3.1",
104
110
  "@faker-js/faker": "7.6.0",
105
- "@pollyjs/adapter-puppeteer": "6.0.5",
111
+ "@pollyjs/adapter-puppeteer": "6.0.6",
106
112
  "@pollyjs/core": "5.1.0",
113
+ "@types/chai": "^4.3.7",
107
114
  "@types/inquirer": "9.0.3",
108
115
  "@types/node": "20.4.4",
109
116
  "@wdio/sauce-service": "8.3.8",
110
117
  "@wdio/selenium-standalone-service": "8.3.2",
111
- "@wdio/utils": "8.3.0",
118
+ "@wdio/utils": "8.16.22",
112
119
  "apollo-server-express": "2.25.3",
113
120
  "chai-as-promised": "7.1.1",
114
121
  "chai-subset": "1.6.0",
115
122
  "contributor-faces": "1.0.3",
116
123
  "documentation": "12.3.0",
117
124
  "dtslint": "4.1.6",
118
- "electron": "26.1.0",
119
- "eslint": "8.45.0",
125
+ "electron": "27.0.2",
126
+ "eslint": "8.50.0",
120
127
  "eslint-config-airbnb-base": "15.0.0",
121
128
  "eslint-plugin-import": "2.25.4",
122
129
  "eslint-plugin-mocha": "6.3.0",
123
- "expect": "29.6.2",
130
+ "expect": "29.7.0",
124
131
  "express": "4.17.2",
125
132
  "graphql": "14.6.0",
126
- "husky": "8.0.1",
133
+ "husky": "8.0.3",
127
134
  "inquirer-test": "2.0.1",
128
135
  "jsdoc": "3.6.10",
129
136
  "jsdoc-typeof-plugin": "1.0.0",
130
137
  "json-server": "0.10.1",
131
- "playwright": "1.35.1",
138
+ "playwright": "1.39.0",
132
139
  "puppeteer": "21.1.1",
133
140
  "qrcode-terminal": "0.12.0",
134
141
  "rosie": "2.1.0",
135
- "runok": "0.9.2",
142
+ "runok": "0.9.3",
136
143
  "sinon": "15.2.0",
137
144
  "sinon-chai": "3.7.0",
138
- "testcafe": "3.0.1",
145
+ "testcafe": "3.3.0",
139
146
  "ts-morph": "19.0.0",
140
147
  "ts-node": "10.9.1",
141
148
  "tsd-jsdoc": "2.5.0",
142
149
  "typedoc": "0.24.8",
143
150
  "typedoc-plugin-markdown": "3.13.4",
144
- "typescript": "5.1.6",
151
+ "typescript": "5.2.2",
145
152
  "wdio-docker-service": "1.5.0",
146
153
  "webdriverio": "8.3.8",
147
- "xml2js": "0.6.0",
154
+ "xml2js": "0.6.2",
148
155
  "xmldom": "0.6.0",
149
156
  "xpath": "0.0.33"
150
157
  },
@@ -1,5 +1,10 @@
1
1
  module.exports = {
2
2
  I: 'Ich',
3
+ contexts: {
4
+ Feature: 'Funktionalität',
5
+ Scenario: 'Szenario',
6
+ ScenarioOutline: 'Szenariogrundriss',
7
+ },
3
8
  actions: {
4
9
  amOutsideAngularApp: 'befinde_mich_außerhalb_der_angular_app',
5
10
  amInsideAngularApp: 'bedinde_mich_innerhalb_der_angular_app',
@@ -3,6 +3,7 @@ module.exports = {
3
3
  contexts: {
4
4
  Feature: 'Fonctionnalité',
5
5
  Scenario: 'Scénario',
6
+ ScenarioOutline: 'Plan du scénario',
6
7
  Before: 'Avant',
7
8
  After: 'Après',
8
9
  BeforeSuite: 'AvantLaSuite',
@@ -12,11 +13,15 @@ module.exports = {
12
13
  amOutsideAngularApp: 'suisALExtérieurDeLApplicationAngular',
13
14
  amInsideAngularApp: 'suisALIntérieurDeLApplicationAngular',
14
15
  waitForElement: 'attendsLElément',
15
- waitForClickable: 'attends',
16
+ waitForClickable: 'attendsDeCliquer',
16
17
  waitForVisible: 'attendsPourVoir',
18
+ waitForEnabled: 'attendsLActivationDe',
19
+ waitForInvisible: 'attendsLInvisibilitéDe',
20
+ waitInUrl: 'attendsDansLUrl',
17
21
  waitForText: 'attendsLeTexte',
18
22
  moveTo: 'vaisSur',
19
23
  refresh: 'rafraîchis',
24
+ refreshPage: 'rafraîchisLaPage',
20
25
  haveModule: 'ajouteLeModule',
21
26
  resetModule: 'réinitialiseLeModule',
22
27
  amOnPage: 'suisSurLaPage',
@@ -59,5 +64,13 @@ module.exports = {
59
64
  grabCookie: 'prendsLeCookie',
60
65
  resizeWindow: 'redimensionneLaFenêtre',
61
66
  wait: 'attends',
67
+ clearField: 'effaceLeChamp',
68
+ dontSeeElementInDOM: 'neVoisPasDansLeDOM',
69
+ moveCursorTo: 'bougeLeCurseurSur',
70
+ scrollTo: 'défileVers',
71
+ sendGetRequest: 'envoieLaRequêteGet',
72
+ sendPutRequest: 'envoieLaRequêtePut',
73
+ sendDeleteRequest: 'envoieLaRequêteDelete',
74
+ sendPostRequest: 'envoieLaRequêtePost',
62
75
  },
63
76
  };
@@ -3,6 +3,7 @@ module.exports = {
3
3
  contexts: {
4
4
  Feature: 'Caratteristica',
5
5
  Scenario: 'lo_scenario',
6
+ ScenarioOutline: 'Schema dello scenario',
6
7
  Before: 'Prima',
7
8
  After: 'Dopo',
8
9
  BeforeSuite: 'Prima_della_suite',
@@ -1,5 +1,10 @@
1
1
  module.exports = {
2
2
  I: '私は',
3
+ contexts: {
4
+ Feature: 'フィーチャ',
5
+ Scenario: 'シナリオ',
6
+ ScenarioOutline: 'シナリオアウトライン',
7
+ },
3
8
  actions: {
4
9
  amOutsideAngularApp: 'Angularの外に出る',
5
10
  amInsideAngularApp: 'Angularの中に入る',
@@ -1,5 +1,10 @@
1
1
  module.exports = {
2
2
  I: 'Ja',
3
+ contexts: {
4
+ Feature: 'Funkcja',
5
+ Scenario: 'Scenariusz',
6
+ ScenarioOutline: 'Szablon scenariusza',
7
+ },
3
8
  actions: {
4
9
  amOutsideAngularApp: 'jestem_poza_aplikacją_angular',
5
10
  amInsideAngularApp: 'jestem_w_aplikacji_angular',
@@ -3,6 +3,7 @@ module.exports = {
3
3
  contexts: {
4
4
  Feature: 'Funcionalidade',
5
5
  Scenario: 'Cenário',
6
+ ScenarioOutline: 'Esquema do Cenário',
6
7
  Before: 'Antes',
7
8
  After: 'Depois',
8
9
  BeforeSuite: 'AntesDaSuite',
@@ -3,6 +3,7 @@ module.exports = {
3
3
  contexts: {
4
4
  Feature: 'Цель',
5
5
  Scenario: 'Сценарий',
6
+ ScenarioOutline: 'Структура сценария',
6
7
  Before: 'Начало',
7
8
  After: 'Конец',
8
9
  BeforeSuite: 'Перед_всем',
@@ -1,5 +1,10 @@
1
1
  module.exports = {
2
2
  I: '我',
3
+ contexts: {
4
+ Feature: '功能',
5
+ Scenario: '场景',
6
+ ScenarioOutline: '场景大纲',
7
+ },
3
8
  actions: {
4
9
  amOutsideAngularApp: '在Angular应用外',
5
10
  amInsideAngularApp: '在Angular应用内',
@@ -1,5 +1,10 @@
1
1
  module.exports = {
2
2
  I: '我',
3
+ contexts: {
4
+ Feature: '功能',
5
+ Scenario: '場景',
6
+ ScenarioOutline: '場景大綱',
7
+ },
3
8
  actions: {
4
9
  amOutsideAngularApp: '在Angular應用外',
5
10
  amInsideAngularApp: '在Angular應用內',