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