codeceptjs 4.0.0-beta.1 → 4.0.0-beta.11.esm-aria

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 (207) hide show
  1. package/README.md +133 -120
  2. package/bin/codecept.js +107 -96
  3. package/bin/test-server.js +64 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/docs/webapi/click.mustache +5 -1
  6. package/lib/actor.js +71 -103
  7. package/lib/ai.js +159 -188
  8. package/lib/assert/empty.js +22 -24
  9. package/lib/assert/equal.js +30 -37
  10. package/lib/assert/error.js +14 -14
  11. package/lib/assert/include.js +43 -48
  12. package/lib/assert/throws.js +11 -11
  13. package/lib/assert/truth.js +22 -22
  14. package/lib/assert.js +20 -18
  15. package/lib/codecept.js +238 -162
  16. package/lib/colorUtils.js +50 -52
  17. package/lib/command/check.js +206 -0
  18. package/lib/command/configMigrate.js +56 -51
  19. package/lib/command/definitions.js +96 -109
  20. package/lib/command/dryRun.js +77 -79
  21. package/lib/command/generate.js +234 -194
  22. package/lib/command/gherkin/init.js +42 -33
  23. package/lib/command/gherkin/snippets.js +76 -74
  24. package/lib/command/gherkin/steps.js +20 -17
  25. package/lib/command/info.js +74 -38
  26. package/lib/command/init.js +300 -290
  27. package/lib/command/interactive.js +41 -32
  28. package/lib/command/list.js +28 -27
  29. package/lib/command/run-multiple/chunk.js +51 -48
  30. package/lib/command/run-multiple/collection.js +5 -5
  31. package/lib/command/run-multiple/run.js +5 -1
  32. package/lib/command/run-multiple.js +97 -97
  33. package/lib/command/run-rerun.js +19 -25
  34. package/lib/command/run-workers.js +68 -92
  35. package/lib/command/run.js +39 -27
  36. package/lib/command/utils.js +80 -64
  37. package/lib/command/workers/runTests.js +388 -226
  38. package/lib/config.js +124 -50
  39. package/lib/container.js +765 -260
  40. package/lib/data/context.js +60 -61
  41. package/lib/data/dataScenarioConfig.js +47 -47
  42. package/lib/data/dataTableArgument.js +32 -32
  43. package/lib/data/table.js +22 -22
  44. package/lib/effects.js +307 -0
  45. package/lib/element/WebElement.js +327 -0
  46. package/lib/els.js +160 -0
  47. package/lib/event.js +173 -163
  48. package/lib/globals.js +141 -0
  49. package/lib/heal.js +89 -85
  50. package/lib/helper/AI.js +131 -41
  51. package/lib/helper/ApiDataFactory.js +107 -75
  52. package/lib/helper/Appium.js +542 -404
  53. package/lib/helper/FileSystem.js +100 -79
  54. package/lib/helper/GraphQL.js +44 -43
  55. package/lib/helper/GraphQLDataFactory.js +52 -52
  56. package/lib/helper/JSONResponse.js +126 -88
  57. package/lib/helper/Mochawesome.js +54 -29
  58. package/lib/helper/Playwright.js +2547 -1316
  59. package/lib/helper/Puppeteer.js +1578 -1181
  60. package/lib/helper/REST.js +209 -68
  61. package/lib/helper/WebDriver.js +1482 -1342
  62. package/lib/helper/errors/ConnectionRefused.js +6 -6
  63. package/lib/helper/errors/ElementAssertion.js +11 -16
  64. package/lib/helper/errors/ElementNotFound.js +5 -9
  65. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  66. package/lib/helper/extras/Console.js +11 -11
  67. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  68. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  69. package/lib/helper/extras/PlaywrightReactVueLocator.js +17 -8
  70. package/lib/helper/extras/PlaywrightRestartOpts.js +25 -11
  71. package/lib/helper/extras/Popup.js +22 -22
  72. package/lib/helper/extras/React.js +27 -28
  73. package/lib/helper/network/actions.js +36 -42
  74. package/lib/helper/network/utils.js +78 -84
  75. package/lib/helper/scripts/blurElement.js +5 -5
  76. package/lib/helper/scripts/focusElement.js +5 -5
  77. package/lib/helper/scripts/highlightElement.js +8 -8
  78. package/lib/helper/scripts/isElementClickable.js +34 -34
  79. package/lib/helper.js +2 -3
  80. package/lib/history.js +23 -19
  81. package/lib/hooks.js +8 -8
  82. package/lib/html.js +94 -104
  83. package/lib/index.js +38 -27
  84. package/lib/listener/config.js +30 -23
  85. package/lib/listener/emptyRun.js +54 -0
  86. package/lib/listener/enhancedGlobalRetry.js +110 -0
  87. package/lib/listener/exit.js +16 -18
  88. package/lib/listener/globalRetry.js +70 -0
  89. package/lib/listener/globalTimeout.js +181 -0
  90. package/lib/listener/helpers.js +76 -51
  91. package/lib/listener/mocha.js +10 -11
  92. package/lib/listener/result.js +11 -0
  93. package/lib/listener/retryEnhancer.js +85 -0
  94. package/lib/listener/steps.js +71 -59
  95. package/lib/listener/store.js +20 -0
  96. package/lib/locator.js +214 -197
  97. package/lib/mocha/asyncWrapper.js +274 -0
  98. package/lib/mocha/bdd.js +167 -0
  99. package/lib/mocha/cli.js +341 -0
  100. package/lib/mocha/factory.js +163 -0
  101. package/lib/mocha/featureConfig.js +89 -0
  102. package/lib/mocha/gherkin.js +231 -0
  103. package/lib/mocha/hooks.js +121 -0
  104. package/lib/mocha/index.js +21 -0
  105. package/lib/mocha/inject.js +46 -0
  106. package/lib/{interfaces → mocha}/scenarioConfig.js +58 -34
  107. package/lib/mocha/suite.js +89 -0
  108. package/lib/mocha/test.js +184 -0
  109. package/lib/mocha/types.d.ts +42 -0
  110. package/lib/mocha/ui.js +242 -0
  111. package/lib/output.js +141 -71
  112. package/lib/parser.js +47 -44
  113. package/lib/pause.js +173 -145
  114. package/lib/plugin/analyze.js +403 -0
  115. package/lib/plugin/{autoLogin.js → auth.js} +178 -79
  116. package/lib/plugin/autoDelay.js +36 -40
  117. package/lib/plugin/coverage.js +131 -78
  118. package/lib/plugin/customLocator.js +22 -21
  119. package/lib/plugin/customReporter.js +53 -0
  120. package/lib/plugin/enhancedRetryFailedStep.js +99 -0
  121. package/lib/plugin/heal.js +101 -110
  122. package/lib/plugin/htmlReporter.js +3648 -0
  123. package/lib/plugin/pageInfo.js +140 -0
  124. package/lib/plugin/pauseOnFail.js +12 -11
  125. package/lib/plugin/retryFailedStep.js +82 -47
  126. package/lib/plugin/screenshotOnFail.js +111 -92
  127. package/lib/plugin/stepByStepReport.js +159 -101
  128. package/lib/plugin/stepTimeout.js +20 -25
  129. package/lib/plugin/subtitles.js +38 -38
  130. package/lib/recorder.js +193 -130
  131. package/lib/rerun.js +94 -49
  132. package/lib/result.js +238 -0
  133. package/lib/retryCoordinator.js +207 -0
  134. package/lib/secret.js +20 -18
  135. package/lib/session.js +95 -89
  136. package/lib/step/base.js +239 -0
  137. package/lib/step/comment.js +10 -0
  138. package/lib/step/config.js +50 -0
  139. package/lib/step/func.js +46 -0
  140. package/lib/step/helper.js +50 -0
  141. package/lib/step/meta.js +99 -0
  142. package/lib/step/record.js +74 -0
  143. package/lib/step/retry.js +11 -0
  144. package/lib/step/section.js +55 -0
  145. package/lib/step.js +18 -329
  146. package/lib/steps.js +54 -0
  147. package/lib/store.js +38 -7
  148. package/lib/template/heal.js +3 -12
  149. package/lib/template/prompts/generatePageObject.js +31 -0
  150. package/lib/template/prompts/healStep.js +13 -0
  151. package/lib/template/prompts/writeStep.js +9 -0
  152. package/lib/test-server.js +334 -0
  153. package/lib/timeout.js +60 -0
  154. package/lib/transform.js +8 -8
  155. package/lib/translation.js +34 -21
  156. package/lib/utils/mask_data.js +47 -0
  157. package/lib/utils.js +411 -228
  158. package/lib/workerStorage.js +37 -34
  159. package/lib/workers.js +532 -296
  160. package/package.json +115 -95
  161. package/translations/de-DE.js +5 -3
  162. package/translations/fr-FR.js +5 -4
  163. package/translations/index.js +22 -12
  164. package/translations/it-IT.js +4 -3
  165. package/translations/ja-JP.js +4 -3
  166. package/translations/nl-NL.js +76 -0
  167. package/translations/pl-PL.js +4 -3
  168. package/translations/pt-BR.js +4 -3
  169. package/translations/ru-RU.js +4 -3
  170. package/translations/utils.js +10 -0
  171. package/translations/zh-CN.js +4 -3
  172. package/translations/zh-TW.js +4 -3
  173. package/typings/index.d.ts +546 -185
  174. package/typings/promiseBasedTypes.d.ts +150 -879
  175. package/typings/types.d.ts +547 -996
  176. package/lib/cli.js +0 -249
  177. package/lib/dirname.js +0 -5
  178. package/lib/helper/Expect.js +0 -425
  179. package/lib/helper/ExpectHelper.js +0 -399
  180. package/lib/helper/MockServer.js +0 -223
  181. package/lib/helper/Nightmare.js +0 -1411
  182. package/lib/helper/Protractor.js +0 -1835
  183. package/lib/helper/SoftExpectHelper.js +0 -381
  184. package/lib/helper/TestCafe.js +0 -1410
  185. package/lib/helper/clientscripts/nightmare.js +0 -213
  186. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  187. package/lib/helper/testcafe/testcafe-utils.js +0 -63
  188. package/lib/interfaces/bdd.js +0 -98
  189. package/lib/interfaces/featureConfig.js +0 -69
  190. package/lib/interfaces/gherkin.js +0 -195
  191. package/lib/listener/artifacts.js +0 -19
  192. package/lib/listener/retry.js +0 -68
  193. package/lib/listener/timeout.js +0 -109
  194. package/lib/mochaFactory.js +0 -110
  195. package/lib/plugin/allure.js +0 -15
  196. package/lib/plugin/commentStep.js +0 -136
  197. package/lib/plugin/debugErrors.js +0 -67
  198. package/lib/plugin/eachElement.js +0 -127
  199. package/lib/plugin/fakerTransform.js +0 -49
  200. package/lib/plugin/retryTo.js +0 -121
  201. package/lib/plugin/selenoid.js +0 -371
  202. package/lib/plugin/standardActingHelpers.js +0 -9
  203. package/lib/plugin/tryTo.js +0 -105
  204. package/lib/plugin/wdio.js +0 -246
  205. package/lib/scenario.js +0 -222
  206. package/lib/ui.js +0 -238
  207. package/lib/within.js +0 -70
@@ -1,38 +1,46 @@
1
- import colors from 'chalk';
2
- import fs from 'fs';
3
- import inquirer from 'inquirer';
4
- import mkdirp from 'mkdirp';
5
- import path from 'path';
6
- import { inspect } from 'util';
7
- import spawn from 'cross-spawn';
8
- import * as output from '../output.js';
9
- import { fileExists, beautify, installedLocally } from '../utils.js';
10
- import { getTestRoot } from './utils.js';
11
- import generateDefinitions from './definitions.js';
12
- import { test as generateTest } from './generate.js';
13
- import * as translations0 from '../../translations/index.js';
14
-
15
- const isLocal = installedLocally();
1
+ import colors from 'chalk'
2
+ import fs from 'fs'
3
+ import inquirer from 'inquirer'
4
+ import { mkdirp } from 'mkdirp'
5
+ import path from 'path'
6
+ import { inspect } from 'util'
7
+ import spawn from 'cross-spawn'
8
+
9
+ import output from '../output.js'
10
+ const { print, success, error } = output
11
+ import { fileExists, beautify, installedLocally } from '../utils.js'
12
+ import { getTestRoot } from './utils.js'
13
+ import generateDefinitions from './definitions.js'
14
+ import { test as generateTest } from './generate.js'
15
+ const isLocal = installedLocally()
16
16
 
17
17
  const defaultConfig = {
18
18
  tests: './*_test.js',
19
19
  output: '',
20
20
  helpers: {},
21
21
  include: {},
22
- };
22
+ plugins: {
23
+ htmlReporter: {
24
+ enabled: true,
25
+ },
26
+ },
27
+ }
23
28
 
24
- const helpers = ['Playwright', 'WebDriver', 'Puppeteer', 'REST', 'GraphQL', 'Appium', 'TestCafe'];
25
- const translations = Object.keys(translations0);
29
+ const helpers = ['Playwright', 'WebDriver', 'Puppeteer', 'REST', 'GraphQL', 'Appium']
30
+ const noTranslation = 'English (no localization)'
26
31
 
27
- const noTranslation = 'English (no localization)';
28
- translations.unshift(noTranslation);
32
+ async function getTranslations() {
33
+ const translationsModule = await import('../../translations/index.js')
34
+ const translations = Object.keys(translationsModule.default || translationsModule)
35
+ translations.unshift(noTranslation)
36
+ return translations
37
+ }
29
38
 
30
- const packages = [];
31
- let isTypeScript = false;
32
- let extension = 'js';
39
+ const packages = []
40
+ let isTypeScript = false
41
+ let extension = 'js'
33
42
 
34
- const requireCodeceptConfigure = "const { setHeadlessWhen, setCommonPlugins } = require('@codeceptjs/configure');";
35
- const importCodeceptConfigure = "import { setHeadlessWhen, setCommonPlugins } from '@codeceptjs/configure';";
43
+ const importCodeceptConfigure = "import { setHeadlessWhen, setCommonPlugins } from '@codeceptjs/configure';"
36
44
 
37
45
  const configHeader = `
38
46
  // turn on headless mode when running with HEADLESS=true environment variable
@@ -42,11 +50,11 @@ setHeadlessWhen(process.env.HEADLESS);
42
50
  // enable all common plugins https://github.com/codeceptjs/configure#setcommonplugins
43
51
  setCommonPlugins();
44
52
 
45
- `;
53
+ `
46
54
 
47
55
  const defaultActor = `// in this file you can append custom step methods to 'I' object
48
56
 
49
- module.exports = function() {
57
+ export default function() {
50
58
  return actor({
51
59
 
52
60
  // Define custom steps here, use 'this' to access default methods of I.
@@ -54,7 +62,7 @@ module.exports = function() {
54
62
 
55
63
  });
56
64
  }
57
- `;
65
+ `
58
66
 
59
67
  const defaultActorTs = `// in this file you can append custom step methods to 'I' object
60
68
 
@@ -66,354 +74,356 @@ export = function() {
66
74
 
67
75
  });
68
76
  }
69
- `;
70
-
71
- export default function (initPath) {
72
- const testsPath = getTestRoot(initPath);
73
-
74
- print();
75
- print(` Welcome to ${colors.magenta.bold('CodeceptJS')} initialization tool`);
76
- print(' It will prepare and configure a test environment for you');
77
- print();
78
- print(' Useful links:');
79
- print();
80
- print(' 👉 How to start testing ASAP: https://codecept.io/quickstart/#init');
81
- print(' 👉 How to select helper: https://codecept.io/basics/#architecture');
82
- print(' 👉 TypeScript setup: https://codecept.io/typescript/#getting-started');
83
- print();
77
+ `
78
+
79
+ export default async function (initPath) {
80
+ const testsPath = getTestRoot(initPath)
81
+ const translations = await getTranslations()
82
+
83
+ print()
84
+ print(` Welcome to ${colors.magenta.bold('CodeceptJS')} initialization tool`)
85
+ print(' It will prepare and configure a test environment for you')
86
+ print()
87
+ print(' Useful links:')
88
+ print()
89
+ print(' 👉 How to start testing ASAP: https://codecept.io/quickstart/#init')
90
+ print(' 👉 How to select helper: https://codecept.io/basics/#architecture')
91
+ print(' 👉 TypeScript setup: https://codecept.io/typescript/#getting-started')
92
+ print()
84
93
 
85
94
  if (!path) {
86
- print('No test root specified.');
87
- print(`Test root is assumed to be ${colors.yellow.bold(testsPath)}`);
88
- print('----------------------------------');
95
+ print('No test root specified.')
96
+ print(`Test root is assumed to be ${colors.yellow.bold(testsPath)}`)
97
+ print('----------------------------------')
89
98
  } else {
90
- print(`Installing to ${colors.bold(testsPath)}`);
99
+ print(`Installing to ${colors.bold(testsPath)}`)
91
100
  }
92
101
 
93
102
  if (!fileExists(testsPath)) {
94
- print(`Directory ${testsPath} does not exist, creating...`);
95
- mkdirp.sync(testsPath);
103
+ print(`Directory ${testsPath} does not exist, creating...`)
104
+ mkdirp.sync(testsPath)
96
105
  }
97
106
 
98
- const configFile = path.join(testsPath, 'codecept.conf.js');
107
+ const configFile = path.join(testsPath, 'codecept.conf.js')
99
108
  if (fileExists(configFile)) {
100
- error(`Config is already created at ${configFile}`);
101
- return;
109
+ error(`Config is already created at ${configFile}`)
110
+ return
102
111
  }
103
112
 
104
- const typeScriptconfigFile = path.join(testsPath, 'codecept.conf.ts');
113
+ const typeScriptconfigFile = path.join(testsPath, 'codecept.conf.ts')
105
114
  if (fileExists(typeScriptconfigFile)) {
106
- error(`Config is already created at ${typeScriptconfigFile}`);
107
- return;
115
+ error(`Config is already created at ${typeScriptconfigFile}`)
116
+ return
108
117
  }
109
118
 
110
- inquirer.prompt([
111
- {
112
- name: 'typescript',
113
- type: 'confirm',
114
- default: false,
115
- message: 'Do you plan to write tests in TypeScript?',
116
- },
117
- {
118
- name: 'tests',
119
- type: 'input',
120
- default: (answers) => `./*_test.${answers.typescript ? 'ts' : 'js'}`,
121
- message: 'Where are your tests located?',
122
- },
123
- {
124
- name: 'helper',
125
- type: 'list',
126
- choices: helpers,
127
- default: 'Playwright',
128
- message: 'What helpers do you want to use?',
129
- },
130
- {
131
- name: 'jsonResponse',
132
- type: 'confirm',
133
- default: true,
134
- message: 'Do you want to use JSONResponse helper for assertions on JSON responses? http://bit.ly/3ASVPy9',
135
- when: (answers) => ['GraphQL', 'REST'].includes(answers.helper) === true,
136
- },
137
- {
138
- name: 'output',
139
- default: './output',
140
- message: 'Where should logs, screenshots, and reports to be stored?',
141
- },
142
- {
143
- name: 'translation',
144
- type: 'list',
145
- message: 'Do you want to enable localization for tests? http://bit.ly/3GNUBbh',
146
- choices: translations,
147
- },
148
- ]).then((result) => {
149
- if (result.typescript === true) {
150
- isTypeScript = true;
151
- extension = isTypeScript === true ? 'ts' : 'js';
152
- packages.push('typescript');
153
- packages.push('ts-node');
154
- packages.push('@types/node');
155
- }
156
-
157
- const config = defaultConfig;
158
- config.name = testsPath.split(path.sep).pop();
159
- config.output = result.output;
160
-
161
- config.tests = result.tests;
162
- if (isTypeScript) {
163
- config.tests = `${config.tests.replace(/\.js$/, `.${extension}`)}`;
164
- }
119
+ inquirer
120
+ .prompt([
121
+ {
122
+ name: 'typescript',
123
+ type: 'confirm',
124
+ default: false,
125
+ message: 'Do you plan to write tests in TypeScript?',
126
+ },
127
+ {
128
+ name: 'tests',
129
+ type: 'input',
130
+ default: answers => `./*_test.${answers.typescript ? 'ts' : 'js'}`,
131
+ message: 'Where are your tests located?',
132
+ },
133
+ {
134
+ name: 'helper',
135
+ type: 'list',
136
+ choices: helpers,
137
+ default: 'Playwright',
138
+ message: 'What helpers do you want to use?',
139
+ },
140
+ {
141
+ name: 'jsonResponse',
142
+ type: 'confirm',
143
+ default: true,
144
+ message: 'Do you want to use JSONResponse helper for assertions on JSON responses? http://bit.ly/3ASVPy9',
145
+ when: answers => ['GraphQL', 'REST'].includes(answers.helper) === true,
146
+ },
147
+ {
148
+ name: 'output',
149
+ default: './output',
150
+ message: 'Where should logs, screenshots, and reports to be stored?',
151
+ },
152
+ {
153
+ name: 'translation',
154
+ type: 'list',
155
+ message: 'Do you want to enable localization for tests? http://bit.ly/3GNUBbh',
156
+ choices: translations,
157
+ },
158
+ ])
159
+ .then(async result => {
160
+ if (result.typescript === true) {
161
+ isTypeScript = true
162
+ extension = isTypeScript === true ? 'ts' : 'js'
163
+ packages.push('typescript')
164
+ packages.push('ts-node')
165
+ packages.push('@types/node')
166
+ }
165
167
 
166
- // create a directory tests if it is included in tests path
167
- const matchResults = config.tests.match(/[^*.]+/);
168
- if (matchResults) {
169
- mkdirp.sync(path.join(testsPath, matchResults[0]));
170
- }
168
+ const config = defaultConfig
169
+ config.name = testsPath.split(path.sep).pop()
170
+ config.output = result.output
171
171
 
172
- if (result.translation !== noTranslation) config.translation = result.translation;
172
+ config.tests = result.tests
173
+ if (isTypeScript) {
174
+ config.tests = `${config.tests.replace(/\.js$/, `.${extension}`)}`
175
+ }
173
176
 
174
- const helperName = result.helper;
175
- config.helpers[helperName] = {};
177
+ // create a directory tests if it is included in tests path
178
+ const matchResults = config.tests.match(/[^*.]+/)
179
+ if (matchResults) {
180
+ mkdirp.sync(path.join(testsPath, matchResults[0]))
181
+ }
176
182
 
177
- if (result.jsonResponse === true) {
178
- config.helpers.JSONResponse = {};
179
- }
183
+ if (result.translation !== noTranslation) config.translation = result.translation
180
184
 
181
- let helperConfigs = [];
185
+ const helperName = result.helper
186
+ config.helpers[helperName] = {}
182
187
 
183
- try {
184
- const Helper = require(`../helper/${helperName}`);
185
- if (Helper._checkRequirements) {
186
- packages.concat(Helper._checkRequirements());
188
+ if (result.jsonResponse === true) {
189
+ config.helpers.JSONResponse = {}
187
190
  }
188
191
 
189
- if (!Helper._config()) return;
190
- helperConfigs = helperConfigs.concat(Helper._config().map((config) => {
191
- config.message = `[${helperName}] ${config.message}`;
192
- config.name = `${helperName}_${config.name}`;
193
- config.type = config.type || 'input';
194
- return config;
195
- }));
196
- } catch (err) {
197
- error(err);
198
- }
192
+ let helperConfigs = []
199
193
 
200
- const finish = async () => {
201
- // create steps file by default
202
- // no extra step file for typescript (as it doesn't match TS conventions)
203
- const stepFile = `./steps_file.${extension}`;
204
- fs.writeFileSync(path.join(testsPath, stepFile), extension === 'ts' ? defaultActorTs : defaultActor);
194
+ try {
195
+ const HelperModule = await import(`../helper/${helperName}.js`)
196
+ const Helper = HelperModule.default || HelperModule
197
+ if (Helper._checkRequirements) {
198
+ packages.concat(Helper._checkRequirements())
199
+ }
205
200
 
206
- if (isTypeScript) {
207
- config.include = _actorTranslation('./steps_file', config.translation);
208
- } else {
209
- config.include = _actorTranslation(stepFile, config.translation);
201
+ if (!Helper._config()) return
202
+ helperConfigs = helperConfigs.concat(
203
+ Helper._config().map(config => {
204
+ config.message = `[${helperName}] ${config.message}`
205
+ config.name = `${helperName}_${config.name}`
206
+ config.type = config.type || 'input'
207
+ return config
208
+ }),
209
+ )
210
+ } catch (err) {
211
+ error(err)
210
212
  }
211
213
 
212
- print(`Steps file created at ${stepFile}`);
213
-
214
- let configSource;
215
- const hasConfigure = isLocal && !initPath;
214
+ const finish = async () => {
215
+ // create steps file by default
216
+ // no extra step file for typescript (as it doesn't match TS conventions)
217
+ const stepFile = `./steps_file.${extension}`
218
+ fs.writeFileSync(path.join(testsPath, stepFile), extension === 'ts' ? defaultActorTs : defaultActor)
216
219
 
217
- if (isTypeScript) {
218
- configSource = beautify(`export const config : CodeceptJS.MainConfig = ${inspect(config, false, 4, false)}`);
220
+ if (isTypeScript) {
221
+ config.include = await _actorTranslation('./steps_file', config.translation, translations)
222
+ } else {
223
+ config.include = await _actorTranslation(stepFile, config.translation, translations)
224
+ }
219
225
 
220
- if (hasConfigure) configSource = importCodeceptConfigure + configHeader + configSource;
226
+ print(`Steps file created at ${stepFile}`)
221
227
 
222
- fs.writeFileSync(typeScriptconfigFile, configSource, 'utf-8');
223
- print(`Config created at ${typeScriptconfigFile}`);
224
- } else {
225
- configSource = beautify(`/** @type {CodeceptJS.MainConfig} */\nexports.config = ${inspect(config, false, 4, false)}`);
228
+ let configSource
229
+ const hasConfigure = isLocal && !initPath
226
230
 
227
- if (hasConfigure) configSource = requireCodeceptConfigure + configHeader + configSource;
231
+ if (isTypeScript) {
232
+ configSource = beautify(`export const config : CodeceptJS.MainConfig = ${inspect(config, false, 4, false)}`)
228
233
 
229
- fs.writeFileSync(configFile, configSource, 'utf-8');
230
- print(`Config created at ${configFile}`);
231
- }
234
+ if (hasConfigure) configSource = importCodeceptConfigure + configHeader + configSource
232
235
 
233
- if (config.output) {
234
- if (!fileExists(config.output)) {
235
- mkdirp.sync(path.join(testsPath, config.output));
236
- print(`Directory for temporary output files created at '${config.output}'`);
236
+ fs.writeFileSync(typeScriptconfigFile, configSource, 'utf-8')
237
+ print(`Config created at ${typeScriptconfigFile}`)
237
238
  } else {
238
- print(`Directory for temporary output files is already created at '${config.output}'`);
239
+ configSource = beautify(`/** @type {CodeceptJS.MainConfig} */\nexport const config = ${inspect(config, false, 4, false)}`)
240
+
241
+ if (hasConfigure) configSource = importCodeceptConfigure + configHeader + configSource
242
+
243
+ fs.writeFileSync(configFile, configSource, 'utf-8')
244
+ print(`Config created at ${configFile}`)
239
245
  }
240
- }
241
246
 
242
- const jsconfig = {
243
- compilerOptions: {
244
- allowJs: true,
245
- },
246
- };
247
-
248
- const tsconfig = {
249
- 'ts-node': {
250
- files: true,
251
- },
252
- compilerOptions: {
253
- target: 'es2018',
254
- lib: ['es2018', 'DOM'],
255
- esModuleInterop: true,
256
- module: 'commonjs',
257
- strictNullChecks: false,
258
- types: ['codeceptjs', 'node'],
259
- declaration: true,
260
- skipLibCheck: true,
261
- },
262
- exclude: ['node_modules'],
263
- };
247
+ if (config.output) {
248
+ if (!fileExists(config.output)) {
249
+ mkdirp.sync(path.join(testsPath, config.output))
250
+ print(`Directory for temporary output files created at '${config.output}'`)
251
+ } else {
252
+ print(`Directory for temporary output files is already created at '${config.output}'`)
253
+ }
254
+ }
264
255
 
265
- if (isTypeScript) {
266
- const tsconfigJson = beautify(JSON.stringify(tsconfig));
267
- const tsconfigFile = path.join(testsPath, 'tsconfig.json');
268
- if (fileExists(tsconfigFile)) {
269
- print(`tsconfig.json already exists at ${tsconfigFile}`);
270
- } else {
271
- fs.writeFileSync(tsconfigFile, tsconfigJson);
256
+ const jsconfig = {
257
+ compilerOptions: {
258
+ allowJs: true,
259
+ },
260
+ }
261
+
262
+ const tsconfig = {
263
+ 'ts-node': {
264
+ files: true,
265
+ },
266
+ compilerOptions: {
267
+ target: 'es2018',
268
+ lib: ['es2018', 'DOM'],
269
+ esModuleInterop: true,
270
+ module: 'commonjs',
271
+ strictNullChecks: false,
272
+ types: ['codeceptjs', 'node'],
273
+ declaration: true,
274
+ skipLibCheck: true,
275
+ },
276
+ exclude: ['node_modules'],
272
277
  }
273
- } else {
274
- const jsconfigJson = beautify(JSON.stringify(jsconfig));
275
- const jsconfigFile = path.join(testsPath, 'jsconfig.json');
276
- if (fileExists(jsconfigFile)) {
277
- print(`jsconfig.json already exists at ${jsconfigFile}`);
278
+
279
+ if (isTypeScript) {
280
+ const tsconfigJson = beautify(JSON.stringify(tsconfig))
281
+ const tsconfigFile = path.join(testsPath, 'tsconfig.json')
282
+ if (fileExists(tsconfigFile)) {
283
+ print(`tsconfig.json already exists at ${tsconfigFile}`)
284
+ } else {
285
+ fs.writeFileSync(tsconfigFile, tsconfigJson)
286
+ }
278
287
  } else {
279
- fs.writeFileSync(jsconfigFile, jsconfigJson);
280
- print(`Intellisense enabled in ${jsconfigFile}`);
288
+ const jsconfigJson = beautify(JSON.stringify(jsconfig))
289
+ const jsconfigFile = path.join(testsPath, 'jsconfig.json')
290
+ if (fileExists(jsconfigFile)) {
291
+ print(`jsconfig.json already exists at ${jsconfigFile}`)
292
+ } else {
293
+ fs.writeFileSync(jsconfigFile, jsconfigJson)
294
+ print(`Intellisense enabled in ${jsconfigFile}`)
295
+ }
281
296
  }
282
- }
283
297
 
284
- const generateDefinitionsManually = colors.bold(`To get auto-completion support, please generate type definitions: ${colors.green('npx codeceptjs def')}`);
298
+ const generateDefinitionsManually = colors.bold(`To get auto-completion support, please generate type definitions: ${colors.green('npx codeceptjs def')}`)
299
+
300
+ if (packages) {
301
+ try {
302
+ install(packages)
303
+ } catch (err) {
304
+ print(colors.bold.red(err.toString()))
305
+ print()
306
+ print(colors.bold.red('Please install next packages manually:'))
307
+ print(`npm i ${packages.join(' ')} --save-dev`)
308
+ print()
309
+ print('Things to do after missing packages installed:')
310
+ print('☑', generateDefinitionsManually)
311
+ print('☑ Create first test:', colors.green('npx codeceptjs gt'))
312
+ print(colors.bold.magenta('Find more information at https://codecept.io'))
313
+ return
314
+ }
315
+ }
285
316
 
286
- if (packages) {
287
317
  try {
288
- install(packages);
318
+ generateDefinitions(testsPath, {})
289
319
  } catch (err) {
290
- print(colors.bold.red(err.toString()));
291
- print();
292
- print(colors.bold.red('Please install next packages manually:'));
293
- print(`npm i ${packages.join(' ')} --save-dev`);
294
- print();
295
- print('Things to do after missing packages installed:');
296
- print('☑', generateDefinitionsManually);
297
- print('☑ Create first test:', colors.green('npx codeceptjs gt'));
298
- print(colors.bold.magenta('Find more information at https://codecept.io'));
299
- return;
320
+ print(colors.bold.red("Couldn't generate type definitions"))
321
+ print(colors.red(err.toString()))
322
+ print('Skipping type definitions...')
323
+ print(generateDefinitionsManually)
300
324
  }
301
- }
302
325
 
303
- try {
304
- generateDefinitions(testsPath, {});
305
- } catch (err) {
306
- print(colors.bold.red('Couldn\'t generate type definitions'));
307
- print(colors.red(err.toString()));
308
- print('Skipping type definitions...');
309
- print(generateDefinitionsManually);
326
+ print('')
327
+ success(' Almost ready... Next step:')
328
+
329
+ const generatedTest = generateTest(testsPath)
330
+ if (!generatedTest) return
331
+ generatedTest.then(() => {
332
+ print('\n--')
333
+ print(colors.bold.green('CodeceptJS Installed! Enjoy supercharged testing! 🤩'))
334
+ print(colors.bold.magenta('Find more information at https://codecept.io'))
335
+ print()
336
+ })
310
337
  }
311
338
 
312
- print('');
313
- success(' Almost ready... Next step:');
314
-
315
- const generatedTest = generateTest(testsPath);
316
- if (!generatedTest) return;
317
- generatedTest.then(() => {
318
- print('\n--');
319
- print(colors.bold.green('CodeceptJS Installed! Enjoy supercharged testing! 🤩'));
320
- print(colors.bold.magenta('Find more information at https://codecept.io'));
321
- print();
322
- });
323
- };
324
-
325
- print('Configure helpers...');
326
- inquirer.prompt(helperConfigs).then(async (helperResult) => {
327
- if (helperResult.Playwright_browser === 'electron') {
328
- delete helperResult.Playwright_url;
329
- delete helperResult.Playwright_show;
330
-
331
- helperResult.Playwright_electron = {
332
- executablePath: '// require("electron") or require("electron-forge")',
333
- args: ['path/to/your/main.js'],
334
- };
335
- }
339
+ print('Configure helpers...')
340
+ inquirer.prompt(helperConfigs).then(async helperResult => {
341
+ if (helperResult.Playwright_browser === 'electron') {
342
+ delete helperResult.Playwright_url
343
+ delete helperResult.Playwright_show
336
344
 
337
- Object.keys(helperResult).forEach((key) => {
338
- const parts = key.split('_');
339
- const helperName = parts[0];
340
- const configName = parts[1];
341
- if (!configName) return;
342
- config.helpers[helperName][configName] = helperResult[key];
343
- });
344
-
345
- print('');
346
- await finish();
347
- });
348
- });
345
+ helperResult.Playwright_electron = {
346
+ executablePath: '// require("electron") or require("electron-forge")',
347
+ args: ['path/to/your/main.js'],
348
+ }
349
+ }
350
+
351
+ Object.keys(helperResult).forEach(key => {
352
+ const parts = key.split('_')
353
+ const helperName = parts[0]
354
+ const configName = parts[1]
355
+ if (!configName) return
356
+ config.helpers[helperName][configName] = helperResult[key]
357
+ })
358
+
359
+ print('')
360
+ await finish()
361
+ })
362
+ })
349
363
  }
350
364
 
351
365
  function install(dependencies) {
352
- let command;
353
- let args;
366
+ let command
367
+ let args
354
368
 
355
369
  if (!fs.existsSync(path.join(process.cwd(), 'package.json'))) {
356
- dependencies.push('codeceptjs');
357
- throw new Error("Error: 'package.json' file not found. Generate it with 'npm init -y' command.");
370
+ dependencies.push('codeceptjs')
371
+ throw new Error("Error: 'package.json' file not found. Generate it with 'npm init -y' command.")
358
372
  }
359
373
 
360
374
  if (!installedLocally()) {
361
- console.log('CodeceptJS should be installed locally');
362
- dependencies.push('codeceptjs');
375
+ console.log('CodeceptJS should be installed locally')
376
+ dependencies.push('codeceptjs')
363
377
  }
364
378
 
365
- console.log('Installing packages: ', colors.green(dependencies.join(', ')));
379
+ console.log('Installing packages: ', colors.green(dependencies.join(', ')))
366
380
 
367
381
  if (fileExists('yarn.lock')) {
368
- command = 'yarnpkg';
369
- args = ['add', '-D', '--exact'];
370
- [].push.apply(args, dependencies);
382
+ command = 'yarnpkg'
383
+ args = ['add', '-D', '--exact']
384
+ ;[].push.apply(args, dependencies)
371
385
 
372
- args.push('--cwd');
373
- args.push(process.cwd());
386
+ args.push('--cwd')
387
+ args.push(process.cwd())
374
388
  } else {
375
- command = 'npm';
376
- args = [
377
- 'install',
378
- '--save-dev',
379
- '--loglevel',
380
- 'error',
381
- ].concat(dependencies);
389
+ command = 'npm'
390
+ args = ['install', '--save-dev', '--loglevel', 'error'].concat(dependencies)
382
391
  }
383
392
 
384
393
  if (process.env._INIT_DRY_RUN_INSTALL) {
385
- args.push('--dry-run');
394
+ args.push('--dry-run')
386
395
  }
387
396
 
388
- const { status } = spawn.sync(command, args, { stdio: 'inherit' });
397
+ const { status } = spawn.sync(command, args, { stdio: 'inherit' })
389
398
  if (status !== 0) {
390
- throw new Error(`${command} ${args.join(' ')} failed`);
399
+ throw new Error(`${command} ${args.join(' ')} failed`)
391
400
  }
392
- return true;
401
+ return true
393
402
  }
394
403
 
395
- function _actorTranslation(stepFile, translationSelected) {
396
- let actor;
404
+ async function _actorTranslation(stepFile, translationSelected, translations) {
405
+ let actor
397
406
 
398
407
  for (const translationAvailable of translations) {
399
408
  if (actor) {
400
- break;
409
+ break
401
410
  }
402
411
 
403
412
  if (translationSelected === translationAvailable) {
404
- const nameOfActor = require('../../translations')[translationAvailable].I;
413
+ const translationsModule = await import('../../translations/index.js')
414
+ const nameOfActor = (translationsModule.default || translationsModule)[translationAvailable].I
405
415
 
406
416
  actor = {
407
417
  [nameOfActor]: stepFile,
408
- };
418
+ }
409
419
  }
410
420
  }
411
421
 
412
422
  if (!actor) {
413
423
  actor = {
414
424
  I: stepFile,
415
- };
425
+ }
416
426
  }
417
427
 
418
- return actor;
428
+ return actor
419
429
  }