codeceptjs 4.0.0-beta.2 → 4.0.0-beta.3

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