codeceptjs 4.0.0-beta.4 → 4.0.0-beta.6.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.
- package/README.md +89 -119
- package/bin/codecept.js +53 -54
- package/docs/webapi/clearCookie.mustache +1 -1
- package/lib/actor.js +70 -102
- package/lib/ai.js +131 -121
- package/lib/assert/empty.js +11 -12
- package/lib/assert/equal.js +16 -21
- package/lib/assert/error.js +2 -2
- package/lib/assert/include.js +11 -15
- package/lib/assert/throws.js +3 -5
- package/lib/assert/truth.js +10 -7
- package/lib/assert.js +18 -18
- package/lib/codecept.js +112 -101
- package/lib/colorUtils.js +48 -50
- package/lib/command/check.js +206 -0
- package/lib/command/configMigrate.js +13 -14
- package/lib/command/definitions.js +24 -36
- package/lib/command/dryRun.js +16 -16
- package/lib/command/generate.js +38 -39
- package/lib/command/gherkin/init.js +36 -38
- package/lib/command/gherkin/snippets.js +76 -74
- package/lib/command/gherkin/steps.js +21 -18
- package/lib/command/info.js +49 -15
- package/lib/command/init.js +41 -37
- package/lib/command/interactive.js +22 -13
- package/lib/command/list.js +11 -10
- package/lib/command/run-multiple/chunk.js +50 -47
- package/lib/command/run-multiple/collection.js +5 -5
- package/lib/command/run-multiple/run.js +3 -3
- package/lib/command/run-multiple.js +27 -47
- package/lib/command/run-rerun.js +6 -7
- package/lib/command/run-workers.js +15 -66
- package/lib/command/run.js +8 -8
- package/lib/command/utils.js +22 -21
- package/lib/command/workers/runTests.js +131 -241
- package/lib/config.js +111 -49
- package/lib/container.js +589 -244
- package/lib/data/context.js +16 -18
- package/lib/data/dataScenarioConfig.js +9 -9
- package/lib/data/dataTableArgument.js +7 -7
- package/lib/data/table.js +6 -12
- package/lib/effects.js +307 -0
- package/lib/els.js +160 -0
- package/lib/event.js +24 -19
- package/lib/globals.js +141 -0
- package/lib/heal.js +89 -81
- package/lib/helper/AI.js +3 -2
- package/lib/helper/ApiDataFactory.js +19 -19
- package/lib/helper/Appium.js +47 -51
- package/lib/helper/FileSystem.js +35 -15
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +4 -4
- package/lib/helper/JSONResponse.js +72 -45
- package/lib/helper/Mochawesome.js +14 -11
- package/lib/helper/Playwright.js +832 -434
- package/lib/helper/Puppeteer.js +393 -292
- package/lib/helper/REST.js +32 -27
- package/lib/helper/WebDriver.js +320 -219
- package/lib/helper/errors/ConnectionRefused.js +6 -6
- package/lib/helper/errors/ElementAssertion.js +11 -16
- package/lib/helper/errors/ElementNotFound.js +5 -9
- package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
- package/lib/helper/extras/Console.js +11 -11
- package/lib/helper/extras/PlaywrightLocator.js +110 -0
- package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
- package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
- package/lib/helper/extras/Popup.js +22 -22
- package/lib/helper/extras/React.js +29 -30
- package/lib/helper/network/actions.js +33 -48
- package/lib/helper/network/utils.js +76 -83
- package/lib/helper/scripts/blurElement.js +6 -6
- package/lib/helper/scripts/focusElement.js +6 -6
- package/lib/helper/scripts/highlightElement.js +9 -9
- package/lib/helper/scripts/isElementClickable.js +34 -34
- package/lib/helper.js +2 -1
- package/lib/history.js +23 -20
- package/lib/hooks.js +10 -10
- package/lib/html.js +90 -100
- package/lib/index.js +48 -21
- package/lib/listener/config.js +8 -9
- package/lib/listener/emptyRun.js +54 -0
- package/lib/listener/exit.js +10 -12
- package/lib/listener/{retry.js → globalRetry.js} +10 -10
- package/lib/listener/globalTimeout.js +166 -0
- package/lib/listener/helpers.js +43 -24
- package/lib/listener/mocha.js +4 -5
- package/lib/listener/result.js +11 -0
- package/lib/listener/steps.js +26 -23
- package/lib/listener/store.js +20 -0
- package/lib/locator.js +213 -192
- package/lib/mocha/asyncWrapper.js +264 -0
- package/lib/mocha/bdd.js +167 -0
- package/lib/mocha/cli.js +341 -0
- package/lib/mocha/factory.js +160 -0
- package/lib/{interfaces → mocha}/featureConfig.js +33 -13
- package/lib/{interfaces → mocha}/gherkin.js +75 -45
- package/lib/mocha/hooks.js +121 -0
- package/lib/mocha/index.js +21 -0
- package/lib/mocha/inject.js +46 -0
- package/lib/{interfaces → mocha}/scenarioConfig.js +32 -8
- package/lib/mocha/suite.js +89 -0
- package/lib/mocha/test.js +178 -0
- package/lib/mocha/types.d.ts +42 -0
- package/lib/mocha/ui.js +229 -0
- package/lib/output.js +86 -64
- package/lib/parser.js +44 -44
- package/lib/pause.js +160 -139
- package/lib/plugin/analyze.js +403 -0
- package/lib/plugin/{autoLogin.js → auth.js} +137 -43
- package/lib/plugin/autoDelay.js +19 -15
- package/lib/plugin/coverage.js +22 -27
- package/lib/plugin/customLocator.js +5 -5
- package/lib/plugin/customReporter.js +53 -0
- package/lib/plugin/heal.js +49 -17
- package/lib/plugin/pageInfo.js +140 -0
- package/lib/plugin/pauseOnFail.js +4 -3
- package/lib/plugin/retryFailedStep.js +60 -19
- package/lib/plugin/screenshotOnFail.js +80 -83
- package/lib/plugin/stepByStepReport.js +70 -31
- package/lib/plugin/stepTimeout.js +7 -13
- package/lib/plugin/subtitles.js +10 -9
- package/lib/recorder.js +167 -126
- package/lib/rerun.js +94 -50
- package/lib/result.js +161 -0
- package/lib/secret.js +18 -17
- package/lib/session.js +95 -89
- package/lib/step/base.js +239 -0
- package/lib/step/comment.js +10 -0
- package/lib/step/config.js +50 -0
- package/lib/step/func.js +46 -0
- package/lib/step/helper.js +50 -0
- package/lib/step/meta.js +99 -0
- package/lib/step/record.js +74 -0
- package/lib/step/retry.js +11 -0
- package/lib/step/section.js +55 -0
- package/lib/step.js +18 -332
- package/lib/steps.js +54 -0
- package/lib/store.js +37 -5
- package/lib/template/heal.js +2 -11
- package/lib/timeout.js +60 -0
- package/lib/transform.js +8 -8
- package/lib/translation.js +32 -18
- package/lib/utils.js +354 -250
- package/lib/workerStorage.js +16 -16
- package/lib/workers.js +366 -282
- package/package.json +107 -95
- package/translations/de-DE.js +5 -4
- package/translations/fr-FR.js +5 -4
- package/translations/index.js +23 -9
- package/translations/it-IT.js +5 -4
- package/translations/ja-JP.js +5 -4
- package/translations/nl-NL.js +76 -0
- package/translations/pl-PL.js +5 -4
- package/translations/pt-BR.js +5 -4
- package/translations/ru-RU.js +5 -4
- package/translations/utils.js +18 -0
- package/translations/zh-CN.js +5 -4
- package/translations/zh-TW.js +5 -4
- package/typings/index.d.ts +177 -186
- package/typings/promiseBasedTypes.d.ts +3573 -5941
- package/typings/types.d.ts +4042 -6370
- package/lib/cli.js +0 -256
- package/lib/helper/ExpectHelper.js +0 -391
- package/lib/helper/Nightmare.js +0 -1504
- package/lib/helper/Protractor.js +0 -1863
- package/lib/helper/SoftExpectHelper.js +0 -381
- package/lib/helper/TestCafe.js +0 -1414
- package/lib/helper/clientscripts/nightmare.js +0 -213
- package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
- package/lib/helper/testcafe/testControllerHolder.js +0 -42
- package/lib/helper/testcafe/testcafe-utils.js +0 -62
- package/lib/interfaces/bdd.js +0 -81
- package/lib/listener/artifacts.js +0 -19
- package/lib/listener/timeout.js +0 -109
- package/lib/mochaFactory.js +0 -113
- package/lib/plugin/allure.js +0 -15
- package/lib/plugin/commentStep.js +0 -136
- package/lib/plugin/debugErrors.js +0 -67
- package/lib/plugin/eachElement.js +0 -127
- package/lib/plugin/fakerTransform.js +0 -49
- package/lib/plugin/retryTo.js +0 -127
- package/lib/plugin/selenoid.js +0 -384
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/plugin/tryTo.js +0 -115
- package/lib/plugin/wdio.js +0 -249
- package/lib/scenario.js +0 -224
- package/lib/ui.js +0 -236
- package/lib/within.js +0 -70
package/lib/colorUtils.js
CHANGED
|
@@ -144,14 +144,14 @@ function convertColorNameToHex(color) {
|
|
|
144
144
|
whitesmoke: '#f5f5f5',
|
|
145
145
|
yellow: '#ffff00',
|
|
146
146
|
yellowgreen: '#9acd32',
|
|
147
|
-
}
|
|
147
|
+
}
|
|
148
148
|
|
|
149
|
-
const cColor = `${color}`.toLowerCase()
|
|
149
|
+
const cColor = `${color}`.toLowerCase()
|
|
150
150
|
if (typeof colors[cColor] !== 'undefined') {
|
|
151
|
-
return colors[cColor]
|
|
151
|
+
return colors[cColor]
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
-
return color
|
|
154
|
+
return color
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
/**
|
|
@@ -160,23 +160,23 @@ function convertColorNameToHex(color) {
|
|
|
160
160
|
*/
|
|
161
161
|
function convertHexColorToRgba(hex) {
|
|
162
162
|
// Expand shorthand form (e.g. "#03F") to full form (e.g. "#0033FF")
|
|
163
|
-
const shorthandRegex = /^#([a-f\d])([a-f\d])([a-f\d])$/i
|
|
163
|
+
const shorthandRegex = /^#([a-f\d])([a-f\d])([a-f\d])$/i
|
|
164
164
|
const hexFull = `${hex}`.replace(shorthandRegex, (m, r, g, b) => {
|
|
165
|
-
return r + r + g + g + b + b
|
|
166
|
-
})
|
|
165
|
+
return r + r + g + g + b + b
|
|
166
|
+
})
|
|
167
167
|
|
|
168
|
-
const result = /^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexFull)
|
|
168
|
+
const result = /^#([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hexFull)
|
|
169
169
|
if (!result) {
|
|
170
170
|
// Return untouched if not a hex code
|
|
171
|
-
return hex
|
|
171
|
+
return hex
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
const r = parseInt(result[1], 16)
|
|
175
|
-
const g = parseInt(result[2], 16)
|
|
176
|
-
const b = parseInt(result[3], 16)
|
|
177
|
-
const a = 1
|
|
174
|
+
const r = parseInt(result[1], 16)
|
|
175
|
+
const g = parseInt(result[2], 16)
|
|
176
|
+
const b = parseInt(result[3], 16)
|
|
177
|
+
const a = 1
|
|
178
178
|
|
|
179
|
-
return `rgba(${r}, ${g}, ${b}, ${a})
|
|
179
|
+
return `rgba(${r}, ${g}, ${b}, ${a})`
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
/**
|
|
@@ -190,29 +190,29 @@ function convertHexColorToRgba(hex) {
|
|
|
190
190
|
* @param {string} color Color as a string, i.e. rgb(85,0,0)
|
|
191
191
|
*/
|
|
192
192
|
function convertColorToRGBA(color) {
|
|
193
|
-
const cstr = `${color}`.toLowerCase().trim() || ''
|
|
193
|
+
const cstr = `${color}`.toLowerCase().trim() || ''
|
|
194
194
|
|
|
195
195
|
if (!/^rgba?\(.+?\)$/.test(cstr)) {
|
|
196
196
|
// Convert both color names and hex colors to rgba
|
|
197
|
-
const hexColor = convertColorNameToHex(color)
|
|
198
|
-
return convertHexColorToRgba(hexColor)
|
|
197
|
+
const hexColor = convertColorNameToHex(color)
|
|
198
|
+
return convertHexColorToRgba(hexColor)
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
// Convert rgb to rgba
|
|
202
|
-
const channels = cstr.match(/([\-0-9.]+)/g) || []
|
|
202
|
+
const channels = cstr.match(/([\-0-9.]+)/g) || []
|
|
203
203
|
|
|
204
204
|
switch (channels.length) {
|
|
205
205
|
case 3:
|
|
206
206
|
// Convert rgb to rgba
|
|
207
|
-
return `rgba(${channels.join(', ')}, 1)
|
|
207
|
+
return `rgba(${channels.join(', ')}, 1)`
|
|
208
208
|
|
|
209
209
|
case 4:
|
|
210
210
|
// Format rgba
|
|
211
|
-
return `rgba(${channels.join(', ')})
|
|
211
|
+
return `rgba(${channels.join(', ')})`
|
|
212
212
|
|
|
213
213
|
default:
|
|
214
214
|
// Unexpected color format. Leave it untouched (let the user handle it)
|
|
215
|
-
return color
|
|
215
|
+
return color
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
@@ -222,34 +222,32 @@ function convertColorToRGBA(color) {
|
|
|
222
222
|
* @param {string} prop CSS Property name
|
|
223
223
|
*/
|
|
224
224
|
function isColorProperty(prop) {
|
|
225
|
-
return
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
225
|
+
return (
|
|
226
|
+
[
|
|
227
|
+
'color',
|
|
228
|
+
'background',
|
|
229
|
+
'backgroundColor',
|
|
230
|
+
'background-color',
|
|
231
|
+
'borderColor',
|
|
232
|
+
'border-color',
|
|
233
|
+
'borderBottomColor',
|
|
234
|
+
'border-bottom-color',
|
|
235
|
+
'borderLeftColor',
|
|
236
|
+
'border-left-color',
|
|
237
|
+
'borderRightColor',
|
|
238
|
+
'borderTopColor',
|
|
239
|
+
'caretColor',
|
|
240
|
+
'columnRuleColor',
|
|
241
|
+
'outlineColor',
|
|
242
|
+
'textDecorationColor',
|
|
243
|
+
'border-right-color',
|
|
244
|
+
'border-top-color',
|
|
245
|
+
'caret-color',
|
|
246
|
+
'column-rule-color',
|
|
247
|
+
'outline-color',
|
|
248
|
+
'text-decoration-color',
|
|
249
|
+
].indexOf(prop) > -1
|
|
250
|
+
)
|
|
249
251
|
}
|
|
250
252
|
|
|
251
|
-
|
|
252
|
-
isColorProperty,
|
|
253
|
-
convertColorToRGBA,
|
|
254
|
-
convertColorNameToHex,
|
|
255
|
-
};
|
|
253
|
+
export { isColorProperty, convertColorToRGBA, convertColorNameToHex }
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { getConfig, getTestRoot } from './utils.js'
|
|
2
|
+
import Codecept from '../codecept.js'
|
|
3
|
+
import output from '../output.js'
|
|
4
|
+
import store from '../store.js'
|
|
5
|
+
import Container from '../container.js'
|
|
6
|
+
import figures from 'figures'
|
|
7
|
+
import chalk from 'chalk'
|
|
8
|
+
import { createTest } from '../mocha/test.js'
|
|
9
|
+
import { getMachineInfo } from './info.js'
|
|
10
|
+
import definitions from './definitions.js'
|
|
11
|
+
|
|
12
|
+
export default async function (options) {
|
|
13
|
+
const configFile = options.config
|
|
14
|
+
|
|
15
|
+
setTimeout(() => {
|
|
16
|
+
output.error("Something went wrong. Checks didn't pass and timed out. Please check your config and helpers.")
|
|
17
|
+
process.exit(1)
|
|
18
|
+
}, options.timeout || 50000)
|
|
19
|
+
|
|
20
|
+
const checks = {
|
|
21
|
+
config: false,
|
|
22
|
+
container: false,
|
|
23
|
+
pageObjects: false,
|
|
24
|
+
plugins: false,
|
|
25
|
+
ai: true, // we don't need to check AI
|
|
26
|
+
helpers: false,
|
|
27
|
+
setup: false,
|
|
28
|
+
teardown: false,
|
|
29
|
+
tests: false,
|
|
30
|
+
def: false,
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const testRoot = getTestRoot(configFile)
|
|
34
|
+
let config = await getConfig(configFile)
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
config = await getConfig(configFile)
|
|
38
|
+
checks['config'] = true
|
|
39
|
+
} catch (err) {
|
|
40
|
+
checks['config'] = err
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
printCheck('config', checks['config'], config.name)
|
|
44
|
+
|
|
45
|
+
let codecept
|
|
46
|
+
try {
|
|
47
|
+
codecept = new Codecept(config, options)
|
|
48
|
+
await codecept.init(testRoot)
|
|
49
|
+
await Container.started()
|
|
50
|
+
checks.container = true
|
|
51
|
+
} catch (err) {
|
|
52
|
+
checks.container = err
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const standardActingHelpers = Container.STANDARD_ACTING_HELPERS
|
|
56
|
+
|
|
57
|
+
printCheck('container', checks['container'])
|
|
58
|
+
|
|
59
|
+
if (codecept) {
|
|
60
|
+
try {
|
|
61
|
+
if (options.bootstrap) await codecept.bootstrap()
|
|
62
|
+
checks.bootstrap = true
|
|
63
|
+
} catch (err) {
|
|
64
|
+
checks.bootstrap = err
|
|
65
|
+
}
|
|
66
|
+
printCheck('bootstrap', checks['bootstrap'], options.bootstrap ? 'Bootstrap was executed' : 'No bootstrap command')
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let numTests = 0
|
|
70
|
+
if (codecept) {
|
|
71
|
+
try {
|
|
72
|
+
codecept.loadTests()
|
|
73
|
+
const files = codecept.testFiles
|
|
74
|
+
const mocha = Container.mocha()
|
|
75
|
+
mocha.files = files
|
|
76
|
+
mocha.loadFiles()
|
|
77
|
+
|
|
78
|
+
for (const suite of mocha.suite.suites) {
|
|
79
|
+
if (suite && suite.tests) {
|
|
80
|
+
numTests += suite.tests.length
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (numTests > 0) {
|
|
85
|
+
checks.tests = true
|
|
86
|
+
} else {
|
|
87
|
+
throw new Error('No tests found')
|
|
88
|
+
}
|
|
89
|
+
} catch (err) {
|
|
90
|
+
checks.tests = err
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (config?.ai?.request) {
|
|
95
|
+
checks.ai = true
|
|
96
|
+
printCheck('ai', checks['ai'], 'Configuration is enabled, request function is set')
|
|
97
|
+
} else {
|
|
98
|
+
printCheck('ai', checks['ai'], 'Disabled')
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
printCheck('tests', checks['tests'], `Total: ${numTests} tests`)
|
|
102
|
+
|
|
103
|
+
store.dryRun = true
|
|
104
|
+
|
|
105
|
+
const helpers = Container.helpers()
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
if (!Object.keys(helpers).length) throw new Error('No helpers found')
|
|
109
|
+
// load helpers
|
|
110
|
+
for (const helper of Object.values(helpers)) {
|
|
111
|
+
if (helper._init) await helper._init()
|
|
112
|
+
}
|
|
113
|
+
checks.helpers = true
|
|
114
|
+
} catch (err) {
|
|
115
|
+
checks.helpers = err
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
printCheck('helpers', checks['helpers'], `${Object.keys(helpers).join(', ')}`)
|
|
119
|
+
|
|
120
|
+
const pageObjects = Container.support()
|
|
121
|
+
|
|
122
|
+
try {
|
|
123
|
+
if (Object.keys(pageObjects).length) {
|
|
124
|
+
for (const pageObject of Object.values(pageObjects)) {
|
|
125
|
+
pageObject.name
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
checks.pageObjects = true
|
|
129
|
+
} catch (err) {
|
|
130
|
+
checks.pageObjects = err
|
|
131
|
+
}
|
|
132
|
+
printCheck('page objects', checks['pageObjects'], `Total: ${Object.keys(pageObjects).length} support objects`)
|
|
133
|
+
|
|
134
|
+
checks.plugins = true // how to check plugins?
|
|
135
|
+
printCheck('plugins', checks['plugins'], Object.keys(Container.plugins()).join(', '))
|
|
136
|
+
|
|
137
|
+
if (Object.keys(helpers).length) {
|
|
138
|
+
const suite = Container.mocha().suite
|
|
139
|
+
const test = createTest('test', () => {})
|
|
140
|
+
checks.setup = true
|
|
141
|
+
for (const helper of Object.values(helpers)) {
|
|
142
|
+
try {
|
|
143
|
+
if (helper._beforeSuite) await helper._beforeSuite(suite)
|
|
144
|
+
if (helper._before) await helper._before(test)
|
|
145
|
+
} catch (err) {
|
|
146
|
+
err.message = `${helper.constructor.name} helper: ${err.message}`
|
|
147
|
+
if (checks.setup instanceof Error) err.message = `${err.message}\n\n${checks.setup?.message || ''}`.trim()
|
|
148
|
+
checks.setup = err
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
printCheck('Helpers Before', checks['setup'], standardActingHelpers.some(h => Object.keys(helpers).includes(h)) ? 'Initializing browser' : '')
|
|
153
|
+
|
|
154
|
+
checks.teardown = true
|
|
155
|
+
for (const helper of Object.values(helpers).reverse()) {
|
|
156
|
+
try {
|
|
157
|
+
if (helper._passed) await helper._passed(test)
|
|
158
|
+
if (helper._after) await helper._after(test)
|
|
159
|
+
if (helper._finishTest) await helper._finishTest(suite)
|
|
160
|
+
if (helper._afterSuite) await helper._afterSuite(suite)
|
|
161
|
+
} catch (err) {
|
|
162
|
+
err.message = `${helper.constructor.name} helper: ${err.message}`
|
|
163
|
+
if (checks.teardown instanceof Error) err.message = `${err.message}\n\n${checks.teardown?.message || ''}`.trim()
|
|
164
|
+
checks.teardown = err
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
printCheck('Helpers After', checks['teardown'], standardActingHelpers.some(h => Object.keys(helpers).includes(h)) ? 'Closing browser' : '')
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
definitions(configFile, { dryRun: true })
|
|
173
|
+
checks.def = true
|
|
174
|
+
} catch (err) {
|
|
175
|
+
checks.def = err
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
printCheck('TypeScript Definitions', checks['def'])
|
|
179
|
+
|
|
180
|
+
output.print('')
|
|
181
|
+
|
|
182
|
+
if (!Object.values(checks).every(check => check === true)) {
|
|
183
|
+
output.error("Something went wrong. Checks didn't pass.")
|
|
184
|
+
output.print()
|
|
185
|
+
await getMachineInfo()
|
|
186
|
+
process.exit(1)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
output.print(output.styles.success('All checks passed'.toUpperCase()), 'Ready to run your tests 🚀')
|
|
190
|
+
process.exit(0)
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function printCheck(name, value, comment = '') {
|
|
194
|
+
let status = ''
|
|
195
|
+
if (value == true) {
|
|
196
|
+
status += chalk.bold.green(figures.tick)
|
|
197
|
+
} else {
|
|
198
|
+
status += chalk.bold.red(figures.cross)
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if (value instanceof Error) {
|
|
202
|
+
comment = `${comment} ${chalk.red(value.message)}`.trim()
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
output.print(status, name.toUpperCase(), chalk.dim(comment))
|
|
206
|
+
}
|
|
@@ -1,22 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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 util from 'util'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
|
|
8
|
+
import output from '../output.js'
|
|
9
|
+
const { print, success, error } = output
|
|
10
|
+
import { fileExists } from '../utils.js'
|
|
11
|
+
import { getTestRoot } from './utils.js'
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
export default function (initPath) {
|
|
13
14
|
const testsPath = getTestRoot(initPath)
|
|
14
15
|
|
|
15
16
|
print()
|
|
16
17
|
print(` Welcome to ${colors.magenta.bold('CodeceptJS')} configuration migration tool`)
|
|
17
|
-
print(
|
|
18
|
-
` It will help you switch from ${colors.cyan.bold('.json')} to ${colors.magenta.bold('.js')} config format at ease`,
|
|
19
|
-
)
|
|
18
|
+
print(` It will help you switch from ${colors.cyan.bold('.json')} to ${colors.magenta.bold('.js')} config format at ease`)
|
|
20
19
|
print()
|
|
21
20
|
|
|
22
21
|
if (!path) {
|
|
@@ -53,7 +52,7 @@ module.exports = function (initPath) {
|
|
|
53
52
|
default: true,
|
|
54
53
|
},
|
|
55
54
|
])
|
|
56
|
-
.then(
|
|
55
|
+
.then(result => {
|
|
57
56
|
if (result.configFile) {
|
|
58
57
|
const jsonConfigFile = path.join(testsPath, 'codecept.js')
|
|
59
58
|
const config = JSON.parse(fs.readFileSync(jsonConfigFile, 'utf8'))
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
import path from 'path'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const actingHelpers = [...
|
|
4
|
+
import { getConfig, getTestRoot } from './utils.js'
|
|
5
|
+
import Codecept from '../codecept.js'
|
|
6
|
+
import container from '../container.js'
|
|
7
|
+
import output from '../output.js'
|
|
8
|
+
const actingHelpers = [...container.STANDARD_ACTING_HELPERS, 'REST']
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Prepare data and generate content of definitions file
|
|
@@ -21,14 +21,7 @@ const actingHelpers = [...require('../plugin/standardActingHelpers'), 'REST']
|
|
|
21
21
|
*
|
|
22
22
|
* @returns {string}
|
|
23
23
|
*/
|
|
24
|
-
const getDefinitionsFileContent = ({
|
|
25
|
-
hasCustomHelper,
|
|
26
|
-
hasCustomStepsFile,
|
|
27
|
-
helperNames,
|
|
28
|
-
supportObject,
|
|
29
|
-
importPaths,
|
|
30
|
-
translations,
|
|
31
|
-
}) => {
|
|
24
|
+
const getDefinitionsFileContent = ({ hasCustomHelper, hasCustomStepsFile, helperNames, supportObject, importPaths, translations }) => {
|
|
32
25
|
const getHelperListFragment = ({ hasCustomHelper, hasCustomStepsFile }) => {
|
|
33
26
|
if (hasCustomHelper && hasCustomStepsFile) {
|
|
34
27
|
return `${['ReturnType<steps_file>', 'WithTranslation<Methods>'].join(', ')}`
|
|
@@ -73,13 +66,7 @@ const getDefinitionsFileContent = ({
|
|
|
73
66
|
*
|
|
74
67
|
* @returns {string}
|
|
75
68
|
*/
|
|
76
|
-
const generateDefinitionsContent = ({
|
|
77
|
-
importPathsFragment,
|
|
78
|
-
supportObjectsTypeFragment,
|
|
79
|
-
methodsTypeFragment,
|
|
80
|
-
helpersListFragment,
|
|
81
|
-
translatedActionsFragment,
|
|
82
|
-
}) => {
|
|
69
|
+
const generateDefinitionsContent = ({ importPathsFragment, supportObjectsTypeFragment, methodsTypeFragment, helpersListFragment, translatedActionsFragment }) => {
|
|
83
70
|
return `/// <reference types='codeceptjs' />
|
|
84
71
|
${importPathsFragment}
|
|
85
72
|
|
|
@@ -99,11 +86,11 @@ const helperNames = []
|
|
|
99
86
|
/** @type {Array<string>} */
|
|
100
87
|
const customHelpers = []
|
|
101
88
|
|
|
102
|
-
|
|
89
|
+
export default async function (genPath, options) {
|
|
103
90
|
const configFile = options.config || genPath
|
|
104
91
|
/** @type {string} */
|
|
105
92
|
const testsPath = getTestRoot(configFile)
|
|
106
|
-
const config = getConfig(configFile)
|
|
93
|
+
const config = await getConfig(configFile)
|
|
107
94
|
if (!config) return
|
|
108
95
|
|
|
109
96
|
/** @type {Object<string, string>} */
|
|
@@ -119,7 +106,8 @@ module.exports = function (genPath, options) {
|
|
|
119
106
|
const targetFolderPath = (options.output && getTestRoot(options.output)) || testsPath
|
|
120
107
|
|
|
121
108
|
const codecept = new Codecept(config, {})
|
|
122
|
-
codecept.init(testsPath)
|
|
109
|
+
await codecept.init(testsPath)
|
|
110
|
+
await container.started()
|
|
123
111
|
|
|
124
112
|
const helpers = container.helpers()
|
|
125
113
|
const translations = container.translation()
|
|
@@ -185,15 +173,12 @@ module.exports = function (genPath, options) {
|
|
|
185
173
|
namespaceTranslationAliases.push(`interface ${translations.vocabulary.I} extends WithTranslation<Methods> {}`)
|
|
186
174
|
|
|
187
175
|
namespaceTranslationAliases.push(' namespace Translation {')
|
|
188
|
-
definitionsFileContent = definitionsFileContent.replace(
|
|
189
|
-
'namespace Translation {',
|
|
190
|
-
namespaceTranslationAliases.join('\n'),
|
|
191
|
-
)
|
|
176
|
+
definitionsFileContent = definitionsFileContent.replace('namespace Translation {', namespaceTranslationAliases.join('\n'))
|
|
192
177
|
|
|
193
178
|
const translationAliases = []
|
|
194
179
|
|
|
195
180
|
if (translations.vocabulary.contexts) {
|
|
196
|
-
Object.keys(translations.vocabulary.contexts).forEach(
|
|
181
|
+
Object.keys(translations.vocabulary.contexts).forEach(k => {
|
|
197
182
|
translationAliases.push(`declare const ${translations.vocabulary.contexts[k]}: typeof ${k};`)
|
|
198
183
|
})
|
|
199
184
|
}
|
|
@@ -201,6 +186,8 @@ module.exports = function (genPath, options) {
|
|
|
201
186
|
definitionsFileContent += `\n${translationAliases.join('\n')}`
|
|
202
187
|
}
|
|
203
188
|
|
|
189
|
+
if (options.dryRun) return
|
|
190
|
+
|
|
204
191
|
fs.writeFileSync(path.join(targetFolderPath, 'steps.d.ts'), definitionsFileContent)
|
|
205
192
|
output.print('TypeScript Definitions provide autocompletion in Visual Studio Code and other IDEs')
|
|
206
193
|
output.print('Definitions were generated in steps.d.ts')
|
|
@@ -222,11 +209,7 @@ function getPath(originalPath, targetFolderPath, testsPath) {
|
|
|
222
209
|
if (!parsedPath.dir.startsWith('.')) return path.posix.join(parsedPath.dir, parsedPath.base)
|
|
223
210
|
const relativePath = path.posix.relative(
|
|
224
211
|
targetFolderPath.split(path.sep).join(path.posix.sep),
|
|
225
|
-
path.posix.join(
|
|
226
|
-
testsPath.split(path.sep).join(path.posix.sep),
|
|
227
|
-
parsedPath.dir.split(path.sep).join(path.posix.sep),
|
|
228
|
-
parsedPath.base.split(path.sep).join(path.posix.sep),
|
|
229
|
-
),
|
|
212
|
+
path.posix.join(testsPath.split(path.sep).join(path.posix.sep), parsedPath.dir.split(path.sep).join(path.posix.sep), parsedPath.base.split(path.sep).join(path.posix.sep)),
|
|
230
213
|
)
|
|
231
214
|
|
|
232
215
|
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`
|
|
@@ -247,7 +230,12 @@ function getImportString(testsPath, targetFolderPath, pathsToType, pathsToValue)
|
|
|
247
230
|
|
|
248
231
|
for (const name in pathsToType) {
|
|
249
232
|
const relativePath = getPath(pathsToType[name], targetFolderPath, testsPath)
|
|
250
|
-
|
|
233
|
+
// For ESM modules with default exports, we need to access the default export type
|
|
234
|
+
if (relativePath.endsWith('.js')) {
|
|
235
|
+
importStrings.push(`type ${name} = typeof import('${relativePath}')['default'];`)
|
|
236
|
+
} else {
|
|
237
|
+
importStrings.push(`type ${name} = typeof import('${relativePath}');`)
|
|
238
|
+
}
|
|
251
239
|
}
|
|
252
240
|
|
|
253
241
|
for (const name in pathsToValue) {
|
package/lib/command/dryRun.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
import { getConfig, getTestRoot } from './utils.js'
|
|
2
|
+
import Config from '../config.js'
|
|
3
|
+
import Codecept from '../codecept.js'
|
|
4
|
+
import output from '../output.js'
|
|
5
|
+
import event from '../event.js'
|
|
6
|
+
import store from '../store.js'
|
|
7
|
+
import Container from '../container.js'
|
|
8
|
+
|
|
9
|
+
export default async function (test, options) {
|
|
10
10
|
if (options.grep) process.env.grep = options.grep
|
|
11
11
|
const configFile = options.config
|
|
12
12
|
let codecept
|
|
13
13
|
|
|
14
14
|
const testRoot = getTestRoot(configFile)
|
|
15
|
-
let config = getConfig(configFile)
|
|
15
|
+
let config = await getConfig(configFile)
|
|
16
16
|
if (options.override) {
|
|
17
17
|
config = Config.append(JSON.parse(options.override))
|
|
18
18
|
}
|
|
@@ -27,7 +27,7 @@ module.exports = async function (test, options) {
|
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
29
|
codecept = new Codecept(config, options)
|
|
30
|
-
codecept.init(testRoot)
|
|
30
|
+
await codecept.init(testRoot)
|
|
31
31
|
|
|
32
32
|
if (options.bootstrap) await codecept.bootstrap()
|
|
33
33
|
|
|
@@ -35,20 +35,20 @@ module.exports = async function (test, options) {
|
|
|
35
35
|
store.dryRun = true
|
|
36
36
|
|
|
37
37
|
if (!options.steps && !options.verbose && !options.debug) {
|
|
38
|
-
printTests(codecept.testFiles)
|
|
38
|
+
await printTests(codecept.testFiles)
|
|
39
39
|
return
|
|
40
40
|
}
|
|
41
41
|
event.dispatcher.on(event.all.result, printFooter)
|
|
42
|
-
codecept.run(test)
|
|
42
|
+
await codecept.run(test)
|
|
43
43
|
} catch (err) {
|
|
44
44
|
console.error(err)
|
|
45
45
|
process.exit(1)
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
function printTests(files) {
|
|
50
|
-
const figures =
|
|
51
|
-
const colors =
|
|
49
|
+
async function printTests(files) {
|
|
50
|
+
const { default: figures } = await import('figures')
|
|
51
|
+
const { default: colors } = await import('chalk')
|
|
52
52
|
|
|
53
53
|
output.print(output.styles.debug(`Tests from ${global.codecept_dir}:`))
|
|
54
54
|
output.print()
|