codeceptjs 3.3.5-beta.6 → 3.3.6

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 (160) hide show
  1. package/CHANGELOG.md +69 -2
  2. package/bin/codecept.js +40 -3
  3. package/docs/basics.md +24 -1
  4. package/docs/build/Appium.js +41 -22
  5. package/docs/build/FileSystem.js +1 -1
  6. package/docs/build/Nightmare.js +106 -57
  7. package/docs/build/Playwright.js +187 -111
  8. package/docs/build/Protractor.js +132 -70
  9. package/docs/build/Puppeteer.js +143 -76
  10. package/docs/build/REST.js +2 -2
  11. package/docs/build/TestCafe.js +107 -57
  12. package/docs/build/WebDriver.js +162 -89
  13. package/docs/changelog.md +107 -2
  14. package/docs/commands.md +5 -3
  15. package/docs/community-helpers.md +7 -4
  16. package/docs/configuration.md +5 -5
  17. package/docs/examples.md +39 -48
  18. package/docs/helpers/Appium.md +25 -23
  19. package/docs/helpers/FileSystem.md +1 -1
  20. package/docs/helpers/Nightmare.md +57 -57
  21. package/docs/helpers/Playwright.md +76 -75
  22. package/docs/helpers/Puppeteer.md +76 -85
  23. package/docs/helpers/REST.md +1 -1
  24. package/docs/helpers/TestCafe.md +57 -57
  25. package/docs/helpers/WebDriver.md +84 -97
  26. package/docs/quickstart.md +1 -1
  27. package/docs/reports.md +1 -1
  28. package/docs/secrets.md +1 -1
  29. package/docs/typescript.md +9 -69
  30. package/docs/webapi/appendField.mustache +1 -1
  31. package/docs/webapi/attachFile.mustache +3 -3
  32. package/docs/webapi/checkOption.mustache +1 -1
  33. package/docs/webapi/clearCookie.mustache +1 -1
  34. package/docs/webapi/clearField.mustache +1 -1
  35. package/docs/webapi/click.mustache +1 -1
  36. package/docs/webapi/clickLink.mustache +1 -1
  37. package/docs/webapi/closeCurrentTab.mustache +1 -1
  38. package/docs/webapi/closeOtherTabs.mustache +1 -1
  39. package/docs/webapi/dontSee.mustache +1 -1
  40. package/docs/webapi/dontSeeCheckboxIsChecked.mustache +1 -1
  41. package/docs/webapi/dontSeeCookie.mustache +1 -1
  42. package/docs/webapi/dontSeeCurrentUrlEquals.mustache +1 -1
  43. package/docs/webapi/dontSeeElement.mustache +1 -1
  44. package/docs/webapi/dontSeeElementInDOM.mustache +1 -1
  45. package/docs/webapi/dontSeeInCurrentUrl.mustache +1 -1
  46. package/docs/webapi/dontSeeInField.mustache +1 -1
  47. package/docs/webapi/dontSeeInSource.mustache +1 -1
  48. package/docs/webapi/dontSeeInTitle.mustache +1 -1
  49. package/docs/webapi/doubleClick.mustache +1 -1
  50. package/docs/webapi/downloadFile.mustache +1 -1
  51. package/docs/webapi/dragAndDrop.mustache +1 -1
  52. package/docs/webapi/dragSlider.mustache +1 -1
  53. package/docs/webapi/executeAsyncScript.mustache +1 -1
  54. package/docs/webapi/executeScript.mustache +1 -1
  55. package/docs/webapi/fillField.mustache +1 -1
  56. package/docs/webapi/forceClick.mustache +1 -1
  57. package/docs/webapi/forceRightClick.mustache +1 -1
  58. package/docs/webapi/moveCursorTo.mustache +1 -1
  59. package/docs/webapi/openNewTab.mustache +1 -1
  60. package/docs/webapi/pressKey.mustache +1 -1
  61. package/docs/webapi/pressKeyDown.mustache +1 -1
  62. package/docs/webapi/pressKeyUp.mustache +1 -1
  63. package/docs/webapi/pressKeyWithKeyNormalization.mustache +1 -1
  64. package/docs/webapi/refreshPage.mustache +1 -1
  65. package/docs/webapi/resizeWindow.mustache +1 -1
  66. package/docs/webapi/rightClick.mustache +1 -1
  67. package/docs/webapi/saveElementScreenshot.mustache +2 -2
  68. package/docs/webapi/saveScreenshot.mustache +2 -2
  69. package/docs/webapi/say.mustache +1 -1
  70. package/docs/webapi/scrollIntoView.mustache +1 -1
  71. package/docs/webapi/scrollPageToBottom.mustache +1 -1
  72. package/docs/webapi/scrollPageToTop.mustache +1 -1
  73. package/docs/webapi/scrollTo.mustache +1 -1
  74. package/docs/webapi/see.mustache +1 -1
  75. package/docs/webapi/seeAttributesOnElements.mustache +1 -1
  76. package/docs/webapi/seeCheckboxIsChecked.mustache +1 -1
  77. package/docs/webapi/seeCookie.mustache +1 -1
  78. package/docs/webapi/seeCssPropertiesOnElements.mustache +1 -1
  79. package/docs/webapi/seeCurrentUrlEquals.mustache +1 -1
  80. package/docs/webapi/seeElement.mustache +1 -1
  81. package/docs/webapi/seeElementInDOM.mustache +1 -1
  82. package/docs/webapi/seeInCurrentUrl.mustache +1 -1
  83. package/docs/webapi/seeInField.mustache +1 -1
  84. package/docs/webapi/seeInPopup.mustache +1 -1
  85. package/docs/webapi/seeInSource.mustache +1 -1
  86. package/docs/webapi/seeInTitle.mustache +1 -1
  87. package/docs/webapi/seeNumberOfElements.mustache +1 -1
  88. package/docs/webapi/seeNumberOfVisibleElements.mustache +1 -1
  89. package/docs/webapi/seeTextEquals.mustache +1 -1
  90. package/docs/webapi/seeTitleEquals.mustache +1 -1
  91. package/docs/webapi/selectOption.mustache +1 -1
  92. package/docs/webapi/setCookie.mustache +1 -1
  93. package/docs/webapi/setGeoLocation.mustache +1 -1
  94. package/docs/webapi/switchTo.mustache +1 -1
  95. package/docs/webapi/switchToNextTab.mustache +1 -1
  96. package/docs/webapi/switchToPreviousTab.mustache +1 -1
  97. package/docs/webapi/type.mustache +1 -1
  98. package/docs/webapi/uncheckOption.mustache +1 -1
  99. package/docs/webapi/wait.mustache +1 -1
  100. package/docs/webapi/waitForClickable.mustache +1 -1
  101. package/docs/webapi/waitForDetached.mustache +1 -1
  102. package/docs/webapi/waitForElement.mustache +1 -1
  103. package/docs/webapi/waitForEnabled.mustache +1 -1
  104. package/docs/webapi/waitForFunction.mustache +1 -1
  105. package/docs/webapi/waitForInvisible.mustache +1 -1
  106. package/docs/webapi/waitForText.mustache +1 -1
  107. package/docs/webapi/waitForValue.mustache +1 -1
  108. package/docs/webapi/waitForVisible.mustache +1 -1
  109. package/docs/webapi/waitInUrl.mustache +1 -1
  110. package/docs/webapi/waitNumberOfVisibleElements.mustache +1 -1
  111. package/docs/webapi/waitToHide.mustache +1 -1
  112. package/docs/webapi/waitUrlEquals.mustache +1 -1
  113. package/lib/command/configMigrate.js +1 -1
  114. package/lib/command/dryRun.js +2 -1
  115. package/lib/command/generate.js +35 -18
  116. package/lib/command/run-rerun.js +38 -0
  117. package/lib/command/utils.js +13 -3
  118. package/lib/config.js +2 -2
  119. package/lib/data/context.js +7 -0
  120. package/lib/helper/Appium.js +6 -4
  121. package/lib/helper/FileSystem.js +1 -1
  122. package/lib/helper/Nightmare.js +1 -1
  123. package/lib/helper/Playwright.js +48 -38
  124. package/lib/helper/Protractor.js +1 -1
  125. package/lib/helper/REST.js +2 -2
  126. package/lib/helper/TestCafe.js +1 -1
  127. package/lib/helper/WebDriver.js +7 -7
  128. package/lib/plugin/wdio.js +11 -2
  129. package/lib/utils.js +3 -0
  130. package/package.json +2 -2
  131. package/typings/index.d.ts +46 -46
  132. package/typings/types.d.ts +497 -443
  133. package/docs/wiki/.git/FETCH_HEAD +0 -1
  134. package/docs/wiki/.git/HEAD +0 -1
  135. package/docs/wiki/.git/ORIG_HEAD +0 -1
  136. package/docs/wiki/.git/config +0 -11
  137. package/docs/wiki/.git/description +0 -1
  138. package/docs/wiki/.git/hooks/applypatch-msg.sample +0 -15
  139. package/docs/wiki/.git/hooks/commit-msg.sample +0 -24
  140. package/docs/wiki/.git/hooks/fsmonitor-watchman.sample +0 -173
  141. package/docs/wiki/.git/hooks/post-update.sample +0 -8
  142. package/docs/wiki/.git/hooks/pre-applypatch.sample +0 -14
  143. package/docs/wiki/.git/hooks/pre-commit.sample +0 -49
  144. package/docs/wiki/.git/hooks/pre-merge-commit.sample +0 -13
  145. package/docs/wiki/.git/hooks/pre-push.sample +0 -53
  146. package/docs/wiki/.git/hooks/pre-rebase.sample +0 -169
  147. package/docs/wiki/.git/hooks/pre-receive.sample +0 -24
  148. package/docs/wiki/.git/hooks/prepare-commit-msg.sample +0 -42
  149. package/docs/wiki/.git/hooks/push-to-checkout.sample +0 -78
  150. package/docs/wiki/.git/hooks/update.sample +0 -128
  151. package/docs/wiki/.git/index +0 -0
  152. package/docs/wiki/.git/info/exclude +0 -6
  153. package/docs/wiki/.git/logs/HEAD +0 -1
  154. package/docs/wiki/.git/logs/refs/heads/master +0 -1
  155. package/docs/wiki/.git/logs/refs/remotes/origin/HEAD +0 -1
  156. package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.idx +0 -0
  157. package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.pack +0 -0
  158. package/docs/wiki/.git/packed-refs +0 -2
  159. package/docs/wiki/.git/refs/heads/master +0 -1
  160. package/docs/wiki/.git/refs/remotes/origin/HEAD +0 -1
@@ -6,4 +6,4 @@ I.switchTo(); // switch back to main page
6
6
  ```
7
7
 
8
8
  @param {?CodeceptJS.LocatorOrString} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
9
- [!] returns a _promise_ which is synchronized internally by recorder
9
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.switchToNextTab(2);
7
7
 
8
8
  @param {number} [num] (optional) number of tabs to switch forward, default: 1.
9
9
  @param {number | null} [sec] (optional) time in seconds to wait.
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.switchToPreviousTab(2);
7
7
 
8
8
  @param {number} [num] (optional) number of tabs to switch backward, default: 1.
9
9
  @param {number?} [sec] (optional) time in seconds to wait.
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -15,4 +15,4 @@ I.type(['T', 'E', 'X', 'T']);
15
15
 
16
16
  @param {string|string[]} key or array of keys to type.
17
17
  @param {?number} [delay=null] (optional) delay in ms between key presses
18
- [!] returns a _promise_ which is synchronized internally by recorder
18
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -10,4 +10,4 @@ I.uncheckOption('agree', '//form');
10
10
  ```
11
11
  @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
12
12
  @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
13
- [!] returns a _promise_ which is synchronized internally by recorder
13
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -5,4 +5,4 @@ I.wait(2); // wait 2 secs
5
5
  ```
6
6
 
7
7
  @param {number} sec number of second to wait.
8
- [!] returns a _promise_ which is synchronized internally by recorder
8
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -8,4 +8,4 @@ I.waitForClickable('.btn.continue', 5); // wait for 5 secs
8
8
 
9
9
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
10
10
  @param {number} [sec] (optional, `1` by default) time in seconds to wait
11
- [!] returns a _promise_ which is synchronized internally by recorder
11
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitForDetached('#popup');
7
7
 
8
8
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -8,4 +8,4 @@ I.waitForElement('.btn.continue', 5); // wait for 5 secs
8
8
 
9
9
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
10
10
  @param {number} [sec] (optional, `1` by default) time in seconds to wait
11
- [!] returns a _promise_ which is synchronized internally by recorder
11
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -3,4 +3,4 @@ Element can be located by CSS or XPath.
3
3
 
4
4
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
5
5
  @param {number} [sec=1] (optional) time in seconds to wait, 1 by default.
6
- [!] returns a _promise_ which is synchronized internally by recorder
6
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -14,4 +14,4 @@ I.waitForFunction((count) => window.requests == count, [3], 5) // pass args and
14
14
  @param {string|function} fn to be executed in browser context.
15
15
  @param {any[]|number} [argsOrSec] (optional, `1` by default) arguments for function or seconds.
16
16
  @param {number} [sec] (optional, `1` by default) time in seconds to wait
17
- [!] returns a _promise_ which is synchronized internally by recorder
17
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitForInvisible('#popup');
7
7
 
8
8
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -10,4 +10,4 @@ I.waitForText('Thank you, form has been submitted', 5, '#modal');
10
10
  @param {string }text to wait for.
11
11
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
12
12
  @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
13
- [!] returns a _promise_ which is synchronized internally by recorder
13
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitForValue('//input', "GoodValue");
7
7
  @param {LocatorOrString} field input field.
8
8
  @param {string }value expected value.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitForVisible('#popup');
7
7
 
8
8
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -6,4 +6,4 @@ I.waitInUrl('/info', 2);
6
6
 
7
7
  @param {string} urlPart value to check.
8
8
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
9
- [!] returns a _promise_ which is synchronized internally by recorder
9
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitNumberOfVisibleElements('a', 3);
7
7
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
8
8
  @param {number} num number of elements.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitToHide('#popup');
7
7
 
8
8
  @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -7,4 +7,4 @@ I.waitUrlEquals('http://127.0.0.1:8000/info');
7
7
 
8
8
  @param {string} urlPart value to check.
9
9
  @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
10
- [!] returns a _promise_ which is synchronized internally by recorder
10
+ ⚠️ returns a _promise_ which is synchronized internally by recorder
@@ -50,7 +50,7 @@ module.exports = function (initPath) {
50
50
  },
51
51
  ]).then((result) => {
52
52
  if (result.configFile) {
53
- const jsonConfigFile = path.join(testsPath, 'codecept.json');
53
+ const jsonConfigFile = path.join(testsPath, 'codecept.js');
54
54
  const config = JSON.parse(fs.readFileSync(jsonConfigFile, 'utf8'));
55
55
  config.name = testsPath.split(path.sep).pop();
56
56
 
@@ -27,7 +27,7 @@ module.exports = async function (test, options) {
27
27
  codecept = new Codecept(config, options);
28
28
  codecept.init(testRoot);
29
29
 
30
- if (options.bootstrap) await codecept.runBootstrap();
30
+ if (options.bootstrap) await codecept.bootstrap();
31
31
 
32
32
  codecept.loadTests();
33
33
  store.dryRun = true;
@@ -71,6 +71,7 @@ function printTests(files) {
71
71
  output.print('');
72
72
  output.success(` Total: ${numOfSuites} suites | ${numOfTests} tests `);
73
73
  printFooter();
74
+ process.exit(0);
74
75
  }
75
76
 
76
77
  function printFooter() {
@@ -3,13 +3,16 @@ const fs = require('fs');
3
3
  const inquirer = require('inquirer');
4
4
  const mkdirp = require('mkdirp');
5
5
  const path = require('path');
6
-
7
- const { fileExists, ucfirst, lcfirst } = require('../utils');
6
+ const {
7
+ fileExists, ucfirst, lcfirst, beautify,
8
+ } = require('../utils');
8
9
  const output = require('../output');
9
10
  const {
10
- getConfig, getTestRoot, safeFileWrite,
11
+ getConfig, getTestRoot, safeFileWrite, readConfig,
11
12
  } = require('./utils');
12
13
 
14
+ let extension = 'js';
15
+
13
16
  const testTemplate = `Feature('{{feature}}');
14
17
 
15
18
  Scenario('test something', ({ {{actor}} }) => {
@@ -26,7 +29,7 @@ module.exports.test = function (genPath) {
26
29
  output.print('Creating a new test...');
27
30
  output.print('----------------------');
28
31
 
29
- const defaultExt = config.tests.match(/([^\*/]*?)$/)[1] || '_test.js';
32
+ const defaultExt = config.tests.match(/([^\*/]*?)$/)[1] || `_test.${extension}`;
30
33
 
31
34
  return inquirer.prompt([
32
35
  {
@@ -79,25 +82,34 @@ module.exports.pageObject = function (genPath, opts) {
79
82
  const kind = opts.T || 'page';
80
83
  if (!config) return;
81
84
 
85
+ let configFile = path.join(testsPath, `codecept.conf.${extension}`);
86
+
87
+ if (!fileExists(configFile)) {
88
+ extension = 'ts';
89
+ configFile = path.join(testsPath, `codecept.conf.${extension}`);
90
+ }
82
91
  output.print(`Creating a new ${kind} object`);
83
92
  output.print('--------------------------');
84
93
 
85
- return inquirer.prompt([{
86
- type: 'input',
87
- name: 'name',
88
- message: `Name of a ${kind} object`,
89
- validate: (val) => !!val,
90
- }, {
91
- type: 'input',
92
- name: 'filename',
93
- message: 'Where should it be stored',
94
- default: answers => `./${kind}s/${answers.name}.js`,
95
- }]).then((result) => {
94
+ return inquirer.prompt([
95
+ {
96
+ type: 'input',
97
+ name: 'name',
98
+ message: `Name of a ${kind} object`,
99
+ validate: (val) => !!val,
100
+ },
101
+ {
102
+ type: 'input',
103
+ name: 'filename',
104
+ message: 'Where should it be stored',
105
+ default: answers => `./${kind}s/${answers.name}.${extension}`,
106
+ }]).then((result) => {
96
107
  const pageObjectFile = path.join(testsPath, result.filename);
97
108
  const dir = path.dirname(pageObjectFile);
98
109
  if (!fileExists(dir)) fs.mkdirSync(dir);
99
110
 
100
111
  let actor = 'actor';
112
+
101
113
  if (config.include.I) {
102
114
  let actorPath = config.include.I;
103
115
  if (actorPath.charAt(0) === '.') { // relative path
@@ -107,16 +119,21 @@ module.exports.pageObject = function (genPath, opts) {
107
119
  }
108
120
  if (!safeFileWrite(pageObjectFile, pageObjectTemplate.replace('{{actor}}', actor))) return;
109
121
  const name = lcfirst(result.name) + ucfirst(kind);
122
+ let data = readConfig(configFile);
110
123
  config.include[name] = result.filename;
124
+ data = data.replace(/include[\s\S][^\}]*/i, `include: ${JSON.stringify(config.include).slice(0, -1)}`);
125
+
126
+ fs.writeFileSync(configFile, beautify(data), 'utf-8');
111
127
 
112
128
  output.success(`${ucfirst(kind)} object for ${result.name} was created in ${pageObjectFile}`);
113
- output.print(`Update your config file (${colors.cyan('include')} section):
129
+ output.print(`Your config file (${colors.cyan('include')} section) has included the new created PO:
114
130
 
115
131
  include: {
132
+ ...
116
133
  ${name}: '${result.filename}',
117
134
  },`);
118
135
 
119
- output.print(`Use ${output.colors.bold(name)} as parameter in test scenarios to access this object`);
136
+ output.print(`Use ${output.colors.bold(colors.cyan(name))} as parameter in test scenarios to access this object`);
120
137
  });
121
138
  };
122
139
 
@@ -163,7 +180,7 @@ module.exports.helper = function (genPath) {
163
180
  type: 'input',
164
181
  name: 'filename',
165
182
  message: 'Where should it be stored',
166
- default: answers => `./${answers.name.toLowerCase()}_helper.js`,
183
+ default: answers => `./${answers.name.toLowerCase()}_helper.${extension}`,
167
184
  }]).then((result) => {
168
185
  const name = ucfirst(result.name);
169
186
  const helperFile = path.join(testsPath, result.filename);
@@ -0,0 +1,38 @@
1
+ const { getConfig, getTestRoot } = require('./utils');
2
+ const { printError, createOutputDir } = require('./utils');
3
+ const Config = require('../config');
4
+ const Codecept = require('../rerun');
5
+
6
+ module.exports = async function (test, options) {
7
+ // registering options globally to use in config
8
+ // Backward compatibility for --profile
9
+ process.profile = options.profile;
10
+ process.env.profile = options.profile;
11
+ const configFile = options.config;
12
+
13
+ let config = getConfig(configFile);
14
+ if (options.override) {
15
+ config = Config.append(JSON.parse(options.override));
16
+ }
17
+ const testRoot = getTestRoot(configFile);
18
+ createOutputDir(config, testRoot);
19
+
20
+ function processError(err) {
21
+ printError(err);
22
+ process.exit(1);
23
+ }
24
+ const codecept = new Codecept(config, options);
25
+
26
+ try {
27
+ codecept.init(testRoot);
28
+
29
+ await codecept.bootstrap();
30
+ codecept.loadTests(test);
31
+ await codecept.run();
32
+ } catch (err) {
33
+ printError(err);
34
+ process.exitCode = 1;
35
+ } finally {
36
+ await codecept.teardown();
37
+ }
38
+ };
@@ -18,6 +18,15 @@ module.exports.getConfig = function (configFile) {
18
18
  }
19
19
  };
20
20
 
21
+ module.exports.readConfig = function (configFile) {
22
+ try {
23
+ const data = fs.readFileSync(configFile, 'utf8');
24
+ return data;
25
+ } catch (err) {
26
+ output.error(err);
27
+ }
28
+ };
29
+
21
30
  function getTestRoot(currentPath) {
22
31
  if (!currentPath) currentPath = '.';
23
32
  if (!path.isAbsolute(currentPath)) currentPath = path.join(process.cwd(), currentPath);
@@ -33,11 +42,12 @@ function fail(msg) {
33
42
 
34
43
  module.exports.fail = fail;
35
44
 
36
- function updateConfig(testsPath, config, key) {
37
- const configFile = path.join(testsPath, 'codecept.conf.js');
45
+ function updateConfig(testsPath, config, key, extension = 'js') {
46
+ const configFile = path.join(testsPath, `codecept.conf.${extension}`);
38
47
  if (!fileExists(configFile)) {
39
48
  console.log();
40
- console.log(`${output.colors.bold.red('codecept.conf.js config can\'t be updated automatically')}`);
49
+ const msg = `codecept.conf.${extension} config can\'t be updated automatically`;
50
+ console.log(`${output.colors.bold.red(msg)}`);
41
51
  console.log('Please update it manually:');
42
52
  console.log();
43
53
  console.log(`${key}: ${config[key]}`);
package/lib/config.js CHANGED
@@ -41,7 +41,7 @@ let config = {};
41
41
  const configFileNames = [
42
42
  'codecept.config.js',
43
43
  'codecept.conf.js',
44
- 'codecept.json',
44
+ 'codecept.js',
45
45
  'codecept.config.ts',
46
46
  'codecept.conf.ts',
47
47
  ];
@@ -69,7 +69,7 @@ class Config {
69
69
  * If directory provided:
70
70
  * * try to load `codecept.config.js` from it
71
71
  * * try to load `codecept.conf.js` from it
72
- * * try to load `codecept.json` from it
72
+ * * try to load `codecept.js` from it
73
73
  * If none of above: fail.
74
74
  *
75
75
  * @param {string} configFile
@@ -1,6 +1,7 @@
1
1
  const { isGenerator } = require('../utils');
2
2
  const DataTable = require('./table');
3
3
  const DataScenarioConfig = require('./dataScenarioConfig');
4
+ const Secret = require('../secret');
4
5
 
5
6
  module.exports = function (context) {
6
7
  context.Data = function (dataTable) {
@@ -70,6 +71,12 @@ function replaceTitle(title, dataRow) {
70
71
  // it should be printed
71
72
  if (Object.prototype.toString.call(dataRow.data) === (Object()).toString()
72
73
  && dataRow.data.toString() !== (Object()).toString()) {
74
+ Object.entries(dataRow.data).forEach(entry => {
75
+ const [key, value] = entry;
76
+ if (value instanceof Secret) {
77
+ dataRow.data[key] = value.getMasked();
78
+ }
79
+ });
73
80
  return `${title} | ${dataRow.data}`;
74
81
  }
75
82
 
@@ -34,7 +34,7 @@ const webRoot = 'body';
34
34
  *
35
35
  * ## Helper configuration
36
36
  *
37
- * This helper should be configured in codecept.json or codecept.conf.js
37
+ * This helper should be configured in codecept.conf.ts or codecept.conf.js
38
38
  *
39
39
  * * `app`: Application path. Local path or remote URL to an .ipa or .apk file, or a .zip containing one of these. Alias to desiredCapabilities.appPackage
40
40
  * * `host`: (default: 'localhost') Appium host
@@ -788,9 +788,11 @@ class Appium extends Webdriver {
788
788
  * I.startActivity('io.selendroid.testapp', '.RegisterUserActivity');
789
789
  * ```
790
790
  *
791
- * @return {Promise<void>}
792
- *
793
791
  * Appium: support only Android
792
+ *
793
+ * @param {string} appPackage
794
+ * @param {string} appActivity
795
+ * @return {Promise<void>}
794
796
  */
795
797
  async startActivity(appPackage, appActivity) {
796
798
  onlyForApps.call(this, 'Android');
@@ -1458,7 +1460,7 @@ class Appium extends Webdriver {
1458
1460
  }
1459
1461
 
1460
1462
  /**
1461
- * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
1463
+ * Saves a screenshot to ouput folder (set in codecept.conf.ts or codecept.conf.js).
1462
1464
  * Filename is relative to output folder.
1463
1465
  *
1464
1466
  * ```js
@@ -13,7 +13,7 @@ const { fileEquals } = require('../assert/equal');
13
13
  *
14
14
  * ```js
15
15
  * I.amInPath('test');
16
- * I.seeFile('codecept.json');
16
+ * I.seeFile('codecept.js');
17
17
  * I.seeInThisFile('FileSystem');
18
18
  * I.dontSeeInThisFile("WebDriver");
19
19
  * ```
@@ -35,7 +35,7 @@ let withinStatus = false;
35
35
  *
36
36
  * ## Configuration
37
37
  *
38
- * This helper should be configured in codecept.json or codecept.conf.js
38
+ * This helper should be configured in codecept.conf.ts or codecept.conf.js
39
39
  *
40
40
  * * `url` - base url of website to be tested
41
41
  * * `restart` (optional, default: true) - restart browser between tests.
@@ -62,13 +62,14 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
62
62
  * @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
63
63
  * @prop {any} [emulate] - browser in device emulation mode.
64
64
  * @prop {boolean} [video=false] - enables video recording for failed tests; videos are saved into `output/videos` folder
65
+ * @prop {boolean} [keepVideoForPassedTests=false] - save videos for passed tests; videos are saved into `output/videos` folder
65
66
  * @prop {boolean} [trace=false] - record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
66
67
  * @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
67
68
  * @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
68
69
  * @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to 'session'.
69
70
  * @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to 'session'.
70
71
  * @prop {number} [waitForAction] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
71
- * @prop {number} [waitForNavigation] - When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle`. Choose one of those options is possible. See [Playwright API](https://github.com/microsoft/playwright/blob/main/docs/api.md#pagewaitfornavigationoptions).
72
+ * @prop {string} [waitForNavigation] - When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle`. Choose one of those options is possible. See [Playwright API](https://playwright.dev/docs/api/class-page#page-wait-for-navigation).
72
73
  * @prop {number} [pressKeyDelay=10] - Delay between key presses in ms. Used when calling Playwrights page.type(...) in fillField/appendField
73
74
  * @prop {number} [getPageTimeout] - config option to set maximum navigation time in milliseconds.
74
75
  * @prop {number} [waitForTimeout] - default wait* timeout in ms. Default: 1000.
@@ -548,22 +549,22 @@ class Playwright extends Helper {
548
549
  }
549
550
 
550
551
  /**
551
- * Use Playwright API inside a test.
552
- *
553
- * First argument is a description of an action.
554
- * Second argument is async function that gets this helper as parameter.
555
- *
556
- * { [`page`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md), [`browserContext`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsercontext.md) [`browser`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browser.md) } objects from Playwright API are available.
557
- *
558
- * ```js
559
- * I.usePlaywrightTo('emulate offline mode', async ({ browserContext }) => {
560
- * await browserContext.setOffline(true);
561
- * });
562
- * ```
563
- *
564
- * @param {string} description used to show in logs.
565
- * @param {function} fn async function that executed with Playwright helper as argumen
566
- */
552
+ * Use Playwright API inside a test.
553
+ *
554
+ * First argument is a description of an action.
555
+ * Second argument is async function that gets this helper as parameter.
556
+ *
557
+ * { [`page`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md), [`browserContext`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsercontext.md) [`browser`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browser.md) } objects from Playwright API are available.
558
+ *
559
+ * ```js
560
+ * I.usePlaywrightTo('emulate offline mode', async ({ browserContext }) => {
561
+ * await browserContext.setOffline(true);
562
+ * });
563
+ * ```
564
+ *
565
+ * @param {string} description used to show in logs.
566
+ * @param {function} fn async function that executed with Playwright helper as argumen
567
+ */
567
568
  usePlaywrightTo(description, fn) {
568
569
  return this._useTo(...arguments);
569
570
  }
@@ -2029,7 +2030,11 @@ class Playwright extends Helper {
2029
2030
  }
2030
2031
 
2031
2032
  if (this.options.recordVideo && this.page && this.page.video()) {
2033
+ const videoPath = `${global.output_dir}/videos/${clearString(test.title)}.failed.webm`;
2032
2034
  test.artifacts.video = await this.page.video().path();
2035
+ fs.rename(test.artifacts.video, videoPath, (() => {
2036
+ test.artifacts.video = videoPath;
2037
+ }));
2033
2038
  }
2034
2039
 
2035
2040
  if (this.options.trace) {
@@ -2041,8 +2046,13 @@ class Playwright extends Helper {
2041
2046
 
2042
2047
  async _passed(test) {
2043
2048
  if (this.options.recordVideo && this.page && this.page.video()) {
2049
+ const videoPath = `${global.output_dir}/videos/${clearString(test.title)}.passed.webm`;
2050
+
2044
2051
  if (this.options.keepVideoForPassedTests) {
2045
2052
  test.artifacts.video = await this.page.video().path();
2053
+ fs.rename(test.artifacts.video, videoPath, (() => {
2054
+ test.artifacts.video = videoPath;
2055
+ }));
2046
2056
  } else {
2047
2057
  this.page.video().delete().catch(e => {});
2048
2058
  }
@@ -2456,32 +2466,32 @@ class Playwright extends Helper {
2456
2466
  }
2457
2467
 
2458
2468
  /**
2459
- * Mocks network request using [`browserContext.route`](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) of Playwright
2460
- *
2461
- * ```js
2462
- * I.mockRoute(/(\.png$)|(\.jpg$)/, route => route.abort());
2463
- * ```
2464
- * This method allows intercepting and mocking requests & responses. [Learn more about it](https://playwright.dev/docs/network#handle-requests)
2465
- *
2466
- * @param {string|RegExp} [url] URL, regex or pattern for to match URL
2467
- * @param {function} [handler] a function to process reques
2468
- */
2469
+ * Mocks network request using [`browserContext.route`](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) of Playwright
2470
+ *
2471
+ * ```js
2472
+ * I.mockRoute(/(\.png$)|(\.jpg$)/, route => route.abort());
2473
+ * ```
2474
+ * This method allows intercepting and mocking requests & responses. [Learn more about it](https://playwright.dev/docs/network#handle-requests)
2475
+ *
2476
+ * @param {string|RegExp} [url] URL, regex or pattern for to match URL
2477
+ * @param {function} [handler] a function to process reques
2478
+ */
2469
2479
  async mockRoute(url, handler) {
2470
2480
  return this.browserContext.route(...arguments);
2471
2481
  }
2472
2482
 
2473
2483
  /**
2474
- * Stops network mocking created by `mockRoute`.
2475
- *
2476
- * ```js
2477
- * I.stopMockingRoute(/(\.png$)|(\.jpg$)/);
2478
- * I.stopMockingRoute(/(\.png$)|(\.jpg$)/, previouslySetHandler);
2479
- * ```
2480
- * If no handler is passed, all mock requests for the rote are disabled.
2481
- *
2482
- * @param {string|RegExp} [url] URL, regex or pattern for to match URL
2483
- * @param {function} [handler] a function to process reques
2484
- */
2484
+ * Stops network mocking created by `mockRoute`.
2485
+ *
2486
+ * ```js
2487
+ * I.stopMockingRoute(/(\.png$)|(\.jpg$)/);
2488
+ * I.stopMockingRoute(/(\.png$)|(\.jpg$)/, previouslySetHandler);
2489
+ * ```
2490
+ * If no handler is passed, all mock requests for the rote are disabled.
2491
+ *
2492
+ * @param {string|RegExp} [url] URL, regex or pattern for to match URL
2493
+ * @param {function} [handler] a function to process reques
2494
+ */
2485
2495
  async stopMockingRoute(url, handler) {
2486
2496
  return this.browserContext.unroute(...arguments);
2487
2497
  }
@@ -36,7 +36,7 @@ let Runner;
36
36
  *
37
37
  * ### Configuration
38
38
  *
39
- * This helper should be configured in codecept.json or codecept.conf.js
39
+ * This helper should be configured in codecept.conf.ts or codecept.conf.js
40
40
  *
41
41
  * * `url` - base url of website to be tested
42
42
  * * `browser` - browser in which perform testing
@@ -9,7 +9,7 @@ const { beautify } = require('../utils');
9
9
  *
10
10
  * @typedef RESTConfig
11
11
  * @type {object}
12
- * @prop {string} endpoint - API base URL
12
+ * @prop {string} [endpoint] - API base URL
13
13
  * @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs
14
14
  * @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default
15
15
  * @prop {object} [defaultHeaders] - a list of default headers
@@ -138,7 +138,7 @@ class REST extends Helper {
138
138
 
139
139
  if (request.data instanceof Secret) {
140
140
  _debugRequest.data = '*****';
141
- request.data = typeof request.data === 'object' ? { ...request.data.toString() } : request.data.toString();
141
+ request.data = (typeof request.data === 'object' && !(request.data instanceof Secret)) ? { ...request.data.toString() } : request.data.toString();
142
142
  }
143
143
 
144
144
  if ((typeof request.data) === 'string') {
@@ -42,7 +42,7 @@ const getHtmlSource = t => ClientFunction(() => document.getElementsByTagName('h
42
42
  *
43
43
  * ## Configuration
44
44
  *
45
- * This helper should be configured in codecept.json or codecept.conf.js
45
+ * This helper should be configured in codecept.conf.ts or codecept.conf.js
46
46
  *
47
47
  * * `url`: base url of website to be tested
48
48
  * * `show`: (optional, default: false) - show browser window.