codeceptjs 3.5.6 → 3.5.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +5 -1
  2. package/docs/advanced.md +1 -1
  3. package/docs/bdd.md +11 -7
  4. package/docs/build/ApiDataFactory.js +2 -1
  5. package/docs/build/Appium.js +26 -23
  6. package/docs/build/Expect.js +422 -0
  7. package/docs/build/Nightmare.js +53 -56
  8. package/docs/build/Playwright.js +202 -103
  9. package/docs/build/Protractor.js +66 -69
  10. package/docs/build/Puppeteer.js +124 -81
  11. package/docs/build/TestCafe.js +56 -55
  12. package/docs/build/WebDriver.js +81 -82
  13. package/docs/changelog.md +562 -1
  14. package/docs/commands.md +12 -0
  15. package/docs/community-helpers.md +8 -4
  16. package/docs/examples.md +8 -2
  17. package/docs/helpers/Appium.md +50 -32
  18. package/docs/helpers/Expect.md +275 -0
  19. package/docs/helpers/Nightmare.md +141 -94
  20. package/docs/helpers/Playwright.md +360 -261
  21. package/docs/helpers/Protractor.md +229 -169
  22. package/docs/helpers/Puppeteer.md +270 -187
  23. package/docs/helpers/TestCafe.md +201 -149
  24. package/docs/helpers/WebDriver.md +252 -178
  25. package/docs/mobile.md +17 -21
  26. package/docs/plugins.md +35 -1
  27. package/docs/webapi/amOnPage.mustache +1 -1
  28. package/docs/webapi/appendField.mustache +1 -1
  29. package/docs/webapi/attachFile.mustache +1 -1
  30. package/docs/webapi/blur.mustache +1 -0
  31. package/docs/webapi/checkOption.mustache +1 -1
  32. package/docs/webapi/clearCookie.mustache +1 -1
  33. package/docs/webapi/clearField.mustache +1 -1
  34. package/docs/webapi/click.mustache +1 -1
  35. package/docs/webapi/clickLink.mustache +1 -1
  36. package/docs/webapi/closeCurrentTab.mustache +1 -1
  37. package/docs/webapi/closeOtherTabs.mustache +1 -1
  38. package/docs/webapi/dontSee.mustache +1 -1
  39. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +1 -1
  40. package/docs/webapi/dontSeeCookie.mustache +1 -1
  41. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +1 -1
  42. package/docs/webapi/dontSeeElement.mustache +1 -1
  43. package/docs/webapi/dontSeeElementInDOM.mustache +1 -1
  44. package/docs/webapi/dontSeeInCurrentUrl.mustache +1 -1
  45. package/docs/webapi/dontSeeInField.mustache +1 -1
  46. package/docs/webapi/dontSeeInSource.mustache +1 -1
  47. package/docs/webapi/dontSeeInTitle.mustache +1 -1
  48. package/docs/webapi/doubleClick.mustache +1 -1
  49. package/docs/webapi/downloadFile.mustache +1 -1
  50. package/docs/webapi/dragAndDrop.mustache +1 -1
  51. package/docs/webapi/dragSlider.mustache +1 -1
  52. package/docs/webapi/executeAsyncScript.mustache +0 -2
  53. package/docs/webapi/executeScript.mustache +0 -2
  54. package/docs/webapi/fillField.mustache +1 -1
  55. package/docs/webapi/focus.mustache +1 -0
  56. package/docs/webapi/forceClick.mustache +1 -1
  57. package/docs/webapi/forceRightClick.mustache +1 -1
  58. package/docs/webapi/grabCookie.mustache +1 -1
  59. package/docs/webapi/grabDataFromPerformanceTiming.mustache +1 -1
  60. package/docs/webapi/moveCursorTo.mustache +1 -1
  61. package/docs/webapi/openNewTab.mustache +1 -1
  62. package/docs/webapi/pressKey.mustache +1 -1
  63. package/docs/webapi/pressKeyDown.mustache +1 -1
  64. package/docs/webapi/pressKeyUp.mustache +1 -1
  65. package/docs/webapi/pressKeyWithKeyNormalization.mustache +1 -1
  66. package/docs/webapi/refreshPage.mustache +1 -1
  67. package/docs/webapi/resizeWindow.mustache +1 -1
  68. package/docs/webapi/rightClick.mustache +1 -1
  69. package/docs/webapi/saveElementScreenshot.mustache +1 -1
  70. package/docs/webapi/saveScreenshot.mustache +1 -1
  71. package/docs/webapi/say.mustache +1 -1
  72. package/docs/webapi/scrollIntoView.mustache +1 -1
  73. package/docs/webapi/scrollPageToBottom.mustache +1 -1
  74. package/docs/webapi/scrollPageToTop.mustache +1 -1
  75. package/docs/webapi/scrollTo.mustache +1 -1
  76. package/docs/webapi/see.mustache +1 -1
  77. package/docs/webapi/seeAttributesOnElements.mustache +1 -1
  78. package/docs/webapi/seeCheckboxIsChecked.mustache +1 -1
  79. package/docs/webapi/seeCookie.mustache +1 -1
  80. package/docs/webapi/seeCssPropertiesOnElements.mustache +1 -1
  81. package/docs/webapi/seeCurrentUrlEquals.mustache +1 -1
  82. package/docs/webapi/seeElement.mustache +1 -1
  83. package/docs/webapi/seeElementInDOM.mustache +1 -1
  84. package/docs/webapi/seeInCurrentUrl.mustache +1 -1
  85. package/docs/webapi/seeInField.mustache +1 -1
  86. package/docs/webapi/seeInPopup.mustache +1 -1
  87. package/docs/webapi/seeInSource.mustache +1 -1
  88. package/docs/webapi/seeInTitle.mustache +1 -1
  89. package/docs/webapi/seeNumberOfElements.mustache +1 -1
  90. package/docs/webapi/seeNumberOfVisibleElements.mustache +1 -1
  91. package/docs/webapi/seeTextEquals.mustache +1 -1
  92. package/docs/webapi/seeTitleEquals.mustache +1 -1
  93. package/docs/webapi/selectOption.mustache +1 -1
  94. package/docs/webapi/setCookie.mustache +1 -1
  95. package/docs/webapi/setGeoLocation.mustache +1 -1
  96. package/docs/webapi/switchTo.mustache +1 -1
  97. package/docs/webapi/switchToNextTab.mustache +1 -1
  98. package/docs/webapi/switchToPreviousTab.mustache +1 -1
  99. package/docs/webapi/type.mustache +1 -1
  100. package/docs/webapi/uncheckOption.mustache +1 -1
  101. package/docs/webapi/wait.mustache +1 -1
  102. package/docs/webapi/waitForClickable.mustache +1 -1
  103. package/docs/webapi/waitForDetached.mustache +1 -1
  104. package/docs/webapi/waitForElement.mustache +1 -1
  105. package/docs/webapi/waitForEnabled.mustache +1 -1
  106. package/docs/webapi/waitForFunction.mustache +1 -1
  107. package/docs/webapi/waitForInvisible.mustache +1 -1
  108. package/docs/webapi/waitForText.mustache +1 -1
  109. package/docs/webapi/waitForValue.mustache +1 -1
  110. package/docs/webapi/waitForVisible.mustache +1 -1
  111. package/docs/webapi/waitInUrl.mustache +1 -1
  112. package/docs/webapi/waitNumberOfVisibleElements.mustache +1 -1
  113. package/docs/webapi/waitToHide.mustache +1 -1
  114. package/docs/webapi/waitUrlEquals.mustache +1 -1
  115. package/docs/webdriver.md +1 -1
  116. package/lib/cli.js +3 -1
  117. package/lib/command/dryRun.js +2 -1
  118. package/lib/helper/ApiDataFactory.js +2 -1
  119. package/lib/helper/Appium.js +8 -5
  120. package/lib/helper/Expect.js +422 -0
  121. package/lib/helper/Playwright.js +127 -32
  122. package/lib/helper/Puppeteer.js +47 -4
  123. package/lib/interfaces/gherkin.js +21 -2
  124. package/lib/output.js +1 -1
  125. package/lib/plugin/autoLogin.js +41 -3
  126. package/lib/utils.js +1 -1
  127. package/lib/workers.js +23 -2
  128. package/package.json +25 -16
  129. package/translations/de-DE.js +5 -0
  130. package/translations/fr-FR.js +1 -0
  131. package/translations/it-IT.js +1 -0
  132. package/translations/ja-JP.js +5 -0
  133. package/translations/pl-PL.js +5 -0
  134. package/translations/pt-BR.js +1 -0
  135. package/translations/ru-RU.js +1 -0
  136. package/translations/zh-CN.js +5 -0
  137. package/translations/zh-TW.js +5 -0
  138. package/typings/promiseBasedTypes.d.ts +928 -862
  139. package/typings/types.d.ts +932 -845
@@ -4,6 +4,7 @@ const fsExtra = require('fs-extra');
4
4
  const path = require('path');
5
5
 
6
6
  const Helper = require('@codeceptjs/helper');
7
+ const { v4: uuidv4 } = require('uuid');
7
8
  const Locator = require('../locator');
8
9
  const recorder = require('../recorder');
9
10
  const store = require('../store');
@@ -19,6 +20,7 @@ const {
19
20
  fileExists,
20
21
  chunkArray,
21
22
  toCamelCase,
23
+ clearString,
22
24
  convertCssPropertiesToCamelCase,
23
25
  screenshotOutputFolder,
24
26
  getNormalizedKeyAttributeValue,
@@ -57,6 +59,8 @@ const consoleLogStore = new Console();
57
59
  * @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
58
60
  * @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
59
61
  * @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
62
+ * @prop {boolean} [trace=false] - record [tracing information](https://pptr.dev/api/puppeteer.tracing) with screenshots.
63
+ * @prop {boolean} [keepTraceForPassedTests=false] - save trace for passed tests.
60
64
  * @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to false.
61
65
  * @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to false.
62
66
  * @prop {number} [waitForAction=100] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
@@ -92,6 +96,14 @@ const config = {};
92
96
  *
93
97
  * <!-- configuration -->
94
98
  *
99
+ * #### Trace Recording Customization
100
+ *
101
+ * Trace recording provides complete information on test execution and includes screenshots, and network requests logged during run.
102
+ * Traces will be saved to `output/trace`
103
+ *
104
+ * * `trace`: enables trace recording for failed tests; trace are saved into `output/trace` folder
105
+ * * `keepTraceForPassedTests`: - save trace for passed tests
106
+ *
95
107
  * #### Example #1: Wait for 0 network connections.
96
108
  *
97
109
  * ```js
@@ -281,8 +293,9 @@ class Puppeteer extends Helper {
281
293
  }
282
294
  }
283
295
 
284
- async _before() {
296
+ async _before(test) {
285
297
  this.sessionPages = {};
298
+ this.currentRunningTest = test;
286
299
  recorder.retry({
287
300
  retries: 3,
288
301
  when: err => {
@@ -647,6 +660,14 @@ class Puppeteer extends Helper {
647
660
  }
648
661
  }
649
662
 
663
+ if (this.options.trace) {
664
+ const fileName = `${`${global.output_dir}${path.sep}trace${path.sep}${uuidv4()}_${clearString(this.currentRunningTest.title)}`.slice(0, 245)}.json`;
665
+ const dir = path.dirname(fileName);
666
+ if (!fileExists(dir)) fs.mkdirSync(dir);
667
+ await this.page.tracing.start({ screenshots: true, path: fileName });
668
+ this.currentRunningTest.artifacts.trace = fileName;
669
+ }
670
+
650
671
  await this.page.goto(url, { waitUntil: this.options.waitForNavigation });
651
672
 
652
673
  const performanceTiming = JSON.parse(await this.page.evaluate(() => JSON.stringify(window.performance.timing)));
@@ -682,14 +703,14 @@ class Puppeteer extends Helper {
682
703
  * Set headers for all next requests
683
704
  *
684
705
  * ```js
685
- * I.haveRequestHeaders({
706
+ * I.setPuppeteerRequestHeaders({
686
707
  * 'X-Sent-By': 'CodeceptJS',
687
708
  * });
688
709
  * ```
689
710
  *
690
711
  * @param {object} customHeaders headers to set
691
712
  */
692
- async haveRequestHeaders(customHeaders) {
713
+ async setPuppeteerRequestHeaders(customHeaders) {
693
714
  if (!customHeaders) {
694
715
  throw new Error('Cannot send empty headers.');
695
716
  }
@@ -1898,8 +1919,30 @@ class Puppeteer extends Helper {
1898
1919
  }
1899
1920
  }
1900
1921
 
1901
- async _failed() {
1922
+ async _failed(test) {
1923
+ await this._withinEnd();
1924
+
1925
+ if (this.options.trace) {
1926
+ await this.page.tracing.stop();
1927
+ const _traceName = this.currentRunningTest.artifacts.trace.replace('.json', '.failed.json');
1928
+ fs.renameSync(this.currentRunningTest.artifacts.trace, _traceName);
1929
+ test.artifacts.trace = _traceName;
1930
+ }
1931
+ }
1932
+
1933
+ async _passed(test) {
1902
1934
  await this._withinEnd();
1935
+
1936
+ if (this.options.trace) {
1937
+ await this.page.tracing.stop();
1938
+ if (this.options.keepTraceForPassedTests) {
1939
+ const _traceName = this.currentRunningTest.artifacts.trace.replace('.json', '.passed.json');
1940
+ fs.renameSync(this.currentRunningTest.artifacts.trace, _traceName);
1941
+ test.artifacts.trace = _traceName;
1942
+ } else {
1943
+ fs.unlinkSync(this.currentRunningTest.artifacts.trace);
1944
+ }
1945
+ }
1903
1946
  }
1904
1947
 
1905
1948
  /**
@@ -18,6 +18,11 @@ parser.stopAtFirstError = false;
18
18
 
19
19
  module.exports = (text, file) => {
20
20
  const ast = parser.parse(text);
21
+ let currentLanguage;
22
+
23
+ if (ast.feature) {
24
+ currentLanguage = getTranslation(ast.feature.language);
25
+ }
21
26
 
22
27
  if (!ast.feature) {
23
28
  throw new Error(`No 'Features' available in Gherkin '${file}' provided!`);
@@ -96,7 +101,7 @@ module.exports = (text, file) => {
96
101
  suite.beforeEach('Before', scenario.injected(async () => runSteps(child.background.steps), suite, 'before'));
97
102
  continue;
98
103
  }
99
- if (child.scenario && child.scenario.keyword === 'Scenario Outline') {
104
+ if (child.scenario && (currentLanguage ? child.scenario.keyword === currentLanguage.contexts.ScenarioOutline : child.scenario.keyword === 'Scenario Outline')) {
100
105
  for (const examples of child.scenario.examples) {
101
106
  const fields = examples.tableHeader.cells.map(c => c.value);
102
107
  for (const example of examples.tableBody) {
@@ -141,7 +146,7 @@ function transformTable(table) {
141
146
  let str = '';
142
147
  for (const id in table.rows) {
143
148
  const cells = table.rows[id].cells;
144
- str += cells.map(c => c.value).map(c => c.slice(0, 15).padEnd(15)).join(' | ');
149
+ str += cells.map(c => c.value).map(c => c.padEnd(15)).join(' | ');
145
150
  str += '\n';
146
151
  }
147
152
  return str;
@@ -162,3 +167,17 @@ function addExampleInTable(exampleSteps, placeholders) {
162
167
  }
163
168
  return steps;
164
169
  }
170
+
171
+ function getTranslation(language) {
172
+ const translations = Object.keys(require('../../translations'));
173
+
174
+ for (const availableTranslation of translations) {
175
+ if (!language) {
176
+ break;
177
+ }
178
+
179
+ if (availableTranslation.includes(language)) {
180
+ return require('../../translations')[availableTranslation];
181
+ }
182
+ }
183
+ }
package/lib/output.js CHANGED
@@ -106,7 +106,7 @@ module.exports = {
106
106
  if (!step) return;
107
107
  // Avoid to print non-gherkin steps, when gherkin is running for --steps mode
108
108
  if (outputLevel === 1) {
109
- if (step.hasBDDAncestor()) {
109
+ if (typeof step === 'object' && step.hasBDDAncestor()) {
110
110
  return;
111
111
  }
112
112
  }
@@ -9,6 +9,7 @@ const isAsyncFunction = require('../utils').isAsyncFunction;
9
9
 
10
10
  const defaultUser = {
11
11
  fetch: I => I.grabCookie(),
12
+ check: () => {},
12
13
  restore: (I, cookies) => {
13
14
  I.amOnPage('/'); // open a page
14
15
  I.setCookie(cookies);
@@ -61,7 +62,7 @@ const defaultConfig = {
61
62
  * #### How It Works
62
63
  *
63
64
  * 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.
65
+ * 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
66
  * 3. If `restore` and `check` were not successful, `login` is executed
66
67
  * 4. `login` should fill in login form
67
68
  * 5. After successful login, `fetch` is executed to save cookies into memory or file.
@@ -212,6 +213,38 @@ const defaultConfig = {
212
213
  * })
213
214
  * ```
214
215
  *
216
+ * #### Tips: Using session to validate user
217
+ *
218
+ * Instead of asserting on page elements for the current user in `check`, you can use the `session` you saved in `fetch`
219
+ *
220
+ * ```js
221
+ * autoLogin: {
222
+ * enabled: true,
223
+ * saveToFile: true,
224
+ * inject: 'login',
225
+ * users: {
226
+ * admin: {
227
+ * login: async (I) => { // If you use async function in the autoLogin plugin
228
+ * const phrase = await I.grabTextFrom('#phrase')
229
+ * I.fillField('username', 'admin'),
230
+ * I.fillField('password', 'password')
231
+ * I.fillField('phrase', phrase)
232
+ * },
233
+ * check: (I, session) => {
234
+ * // Throwing an error in `check` will make CodeceptJS perform the login step for the user
235
+ * if (session.profile.email !== the.email.you.expect@some-mail.com) {
236
+ * throw new Error ('Wrong user signed in');
237
+ * }
238
+ * },
239
+ * }
240
+ * }
241
+ * }
242
+ * ```
243
+ *
244
+ * ```js
245
+ * Scenario('login', async ( {I, login} ) => {
246
+ * await login('admin') // you should use `await`
247
+ * })
215
248
  *
216
249
  *
217
250
  */
@@ -251,7 +284,12 @@ module.exports = function (config) {
251
284
  } else {
252
285
  userSession.login(I);
253
286
  }
287
+
254
288
  const cookies = await userSession.fetch(I);
289
+ if (!cookies) {
290
+ debug('Cannot save user session with empty cookies from auto login\'s fetch method');
291
+ return;
292
+ }
255
293
  if (config.saveToFile) {
256
294
  debug(`Saved user session into file for ${name}`);
257
295
  fs.writeFileSync(path.join(global.output_dir, `${name}_session.json`), JSON.stringify(cookies));
@@ -264,10 +302,10 @@ module.exports = function (config) {
264
302
  recorder.session.start('check login');
265
303
  if (shouldAwait) {
266
304
  await userSession.restore(I, cookies);
267
- await userSession.check(I);
305
+ await userSession.check(I, cookies);
268
306
  } else {
269
307
  userSession.restore(I, cookies);
270
- userSession.check(I);
308
+ userSession.check(I, cookies);
271
309
  }
272
310
  recorder.session.catch((err) => {
273
311
  debug(`Failed auto login for ${name} due to ${err}`);
package/lib/utils.js CHANGED
@@ -11,7 +11,7 @@ function deepMerge(target, source) {
11
11
  }
12
12
 
13
13
  module.exports.genTestId = (test) => {
14
- return require('crypto').createHash('md5').update(test.fullTitle()).digest('base64')
14
+ return require('crypto').createHash('sha256').update(test.fullTitle()).digest('base64')
15
15
  .slice(0, -2);
16
16
  };
17
17
 
package/lib/workers.js CHANGED
@@ -94,10 +94,31 @@ const createWorkerObjects = (testGroups, config, testRoot, options, selectedRuns
94
94
  });
95
95
  }
96
96
  const workersToExecute = [];
97
+
98
+ const currentOutputFolder = config.output;
99
+ let currentMochawesomeReportDir;
100
+ let currentMochaJunitReporterFile;
101
+
102
+ if (config.mocha && config.mocha.reporterOptions) {
103
+ currentMochawesomeReportDir = config.mocha.reporterOptions?.mochawesome.options.reportDir;
104
+ currentMochaJunitReporterFile = config.mocha.reporterOptions['mocha-junit-reporter'].options.mochaFile;
105
+ }
106
+
97
107
  collection.createRuns(selectedRuns, config).forEach((worker) => {
98
- const workerName = worker.getOriginalName() || worker.getName();
108
+ const separator = path.sep;
109
+ const _config = { ...config };
110
+ let workerName = worker.name.replace(':', '_');
111
+ _config.output = `${currentOutputFolder}${separator}${workerName}`;
112
+ if (config.mocha && config.mocha.reporterOptions) {
113
+ _config.mocha.reporterOptions.mochawesome.options.reportDir = `${currentMochawesomeReportDir}${separator}${workerName}`;
114
+
115
+ const _tempArray = currentMochaJunitReporterFile.split(separator);
116
+ _tempArray.splice(_tempArray.findIndex(item => item.includes('.xml')), 0, workerName);
117
+ _config.mocha.reporterOptions['mocha-junit-reporter'].options.mochaFile = _tempArray.join(separator);
118
+ }
119
+ workerName = worker.getOriginalName() || worker.getName();
99
120
  const workerConfig = worker.getConfig();
100
- workersToExecute.push(getOverridenConfig(workerName, workerConfig, config));
121
+ workersToExecute.push(getOverridenConfig(workerName, workerConfig, _config));
101
122
  });
102
123
  const workers = [];
103
124
  let index = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codeceptjs",
3
- "version": "3.5.6",
3
+ "version": "3.5.7",
4
4
  "description": "Supercharged End 2 End Testing Framework for NodeJS",
5
5
  "keywords": [
6
6
  "acceptance",
@@ -43,14 +43,17 @@
43
43
  "test:unit": "mocha test/unit --recursive --timeout 10000",
44
44
  "test:runner": "mocha test/runner --recursive --timeout 10000",
45
45
  "test": "npm run test:unit && npm run test:runner",
46
- "test:appium-quick": "mocha test/helper/Appium_test.js --grep 'quick'",
47
- "test:appium-other": "mocha test/helper/Appium_test.js --grep 'second'",
46
+ "test:appium-quick": "mocha test/helper/AppiumV2_test.js --grep 'quick'",
47
+ "test:appium-other": "mocha test/helper/AppiumV2_test.js --grep 'second'",
48
+ "test:ios:appium-quick": "mocha test/helper/AppiumV2_ios_test.js --grep 'quick'",
49
+ "test:ios:appium-other": "mocha test/helper/AppiumV2_ios_test.js --grep 'second'",
48
50
  "test-app:start": "php -S 127.0.0.1:8000 -t test/data/app",
49
51
  "test-app:stop": "kill -9 $(lsof -t -i:8000)",
50
52
  "test:unit:webbapi:playwright": "mocha test/helper/Playwright_test.js",
51
53
  "test:unit:webbapi:puppeteer": "mocha test/helper/Puppeteer_test.js",
52
54
  "test:unit:webbapi:webDriver": "mocha test/helper/WebDriver_test.js",
53
55
  "test:unit:webbapi:testCafe": "mocha test/helper/TestCafe_test.js",
56
+ "test:unit:expect": "mocha test/helper/Expect_test.js",
54
57
  "def": "./runok.js def",
55
58
  "dev:graphql": "node test/data/graphql/index.js",
56
59
  "publish:site": "./runok.js publish:site",
@@ -70,6 +73,11 @@
70
73
  "axios": "1.3.3",
71
74
  "chai": "4.3.8",
72
75
  "chai-deep-match": "1.2.1",
76
+ "chai-exclude": "^2.1.0",
77
+ "chai-json-schema": "^1.5.1",
78
+ "chai-json-schema-ajv": "^5.2.4",
79
+ "chai-match-pattern": "^1.3.0",
80
+ "chai-string": "^1.5.0",
73
81
  "chalk": "4.1.2",
74
82
  "commander": "11.0.0",
75
83
  "cross-spawn": "7.0.3",
@@ -82,7 +90,7 @@
82
90
  "glob": "6.0.1",
83
91
  "html-minifier": "4.0.0",
84
92
  "inquirer": "6.5.2",
85
- "joi": "17.6.0",
93
+ "joi": "17.11.0",
86
94
  "js-beautify": "1.14.9",
87
95
  "lodash.clonedeep": "4.5.0",
88
96
  "lodash.merge": "4.6.2",
@@ -104,21 +112,22 @@
104
112
  "@faker-js/faker": "7.6.0",
105
113
  "@pollyjs/adapter-puppeteer": "6.0.6",
106
114
  "@pollyjs/core": "5.1.0",
115
+ "@types/chai": "^4.3.7",
107
116
  "@types/inquirer": "9.0.3",
108
117
  "@types/node": "20.4.4",
109
118
  "@wdio/sauce-service": "8.3.8",
110
119
  "@wdio/selenium-standalone-service": "8.3.2",
111
- "@wdio/utils": "8.16.22",
120
+ "@wdio/utils": "8.20.3",
112
121
  "apollo-server-express": "2.25.3",
113
122
  "chai-as-promised": "7.1.1",
114
123
  "chai-subset": "1.6.0",
115
- "contributor-faces": "1.0.3",
124
+ "contributor-faces": "1.1.0",
116
125
  "documentation": "12.3.0",
117
126
  "dtslint": "4.1.6",
118
- "electron": "26.1.0",
119
- "eslint": "8.50.0",
127
+ "electron": "27.0.2",
128
+ "eslint": "8.53.0",
120
129
  "eslint-config-airbnb-base": "15.0.0",
121
- "eslint-plugin-import": "2.25.4",
130
+ "eslint-plugin-import": "2.29.0",
122
131
  "eslint-plugin-mocha": "6.3.0",
123
132
  "expect": "29.7.0",
124
133
  "express": "4.17.2",
@@ -128,23 +137,23 @@
128
137
  "jsdoc": "3.6.10",
129
138
  "jsdoc-typeof-plugin": "1.0.0",
130
139
  "json-server": "0.10.1",
131
- "playwright": "1.38.1",
140
+ "playwright": "1.39.0",
132
141
  "puppeteer": "21.1.1",
133
142
  "qrcode-terminal": "0.12.0",
134
143
  "rosie": "2.1.0",
135
144
  "runok": "0.9.3",
136
- "sinon": "15.2.0",
145
+ "sinon": "17.0.1",
137
146
  "sinon-chai": "3.7.0",
138
- "testcafe": "3.0.1",
147
+ "testcafe": "3.3.0",
139
148
  "ts-morph": "19.0.0",
140
149
  "ts-node": "10.9.1",
141
150
  "tsd-jsdoc": "2.5.0",
142
- "typedoc": "0.24.8",
151
+ "typedoc": "0.25.3",
143
152
  "typedoc-plugin-markdown": "3.13.4",
144
- "typescript": "5.1.6",
153
+ "typescript": "5.2.2",
145
154
  "wdio-docker-service": "1.5.0",
146
155
  "webdriverio": "8.3.8",
147
- "xml2js": "0.6.0",
156
+ "xml2js": "0.6.2",
148
157
  "xmldom": "0.6.0",
149
158
  "xpath": "0.0.33"
150
159
  },
@@ -153,4 +162,4 @@
153
162
  "npm": ">=5.6.0"
154
163
  },
155
164
  "es6": true
156
- }
165
+ }
@@ -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',
@@ -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應用內',