codeceptjs 4.0.0-beta.2 → 4.0.0-beta.21

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 (209) 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 +73 -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 +262 -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 +301 -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 +109 -50
  39. package/lib/container.js +765 -261
  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 +54 -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/loaderCheck.js +124 -0
  157. package/lib/utils/mask_data.js +47 -0
  158. package/lib/utils/typescript.js +237 -0
  159. package/lib/utils.js +411 -228
  160. package/lib/workerStorage.js +37 -34
  161. package/lib/workers.js +532 -296
  162. package/package.json +124 -95
  163. package/translations/de-DE.js +5 -3
  164. package/translations/fr-FR.js +5 -4
  165. package/translations/index.js +22 -12
  166. package/translations/it-IT.js +4 -3
  167. package/translations/ja-JP.js +4 -3
  168. package/translations/nl-NL.js +76 -0
  169. package/translations/pl-PL.js +4 -3
  170. package/translations/pt-BR.js +4 -3
  171. package/translations/ru-RU.js +4 -3
  172. package/translations/utils.js +10 -0
  173. package/translations/zh-CN.js +4 -3
  174. package/translations/zh-TW.js +4 -3
  175. package/typings/index.d.ts +546 -185
  176. package/typings/promiseBasedTypes.d.ts +150 -875
  177. package/typings/types.d.ts +547 -992
  178. package/lib/cli.js +0 -249
  179. package/lib/dirname.js +0 -5
  180. package/lib/helper/Expect.js +0 -425
  181. package/lib/helper/ExpectHelper.js +0 -399
  182. package/lib/helper/MockServer.js +0 -223
  183. package/lib/helper/Nightmare.js +0 -1411
  184. package/lib/helper/Protractor.js +0 -1835
  185. package/lib/helper/SoftExpectHelper.js +0 -381
  186. package/lib/helper/TestCafe.js +0 -1410
  187. package/lib/helper/clientscripts/nightmare.js +0 -213
  188. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  189. package/lib/helper/testcafe/testcafe-utils.js +0 -63
  190. package/lib/interfaces/bdd.js +0 -98
  191. package/lib/interfaces/featureConfig.js +0 -69
  192. package/lib/interfaces/gherkin.js +0 -195
  193. package/lib/listener/artifacts.js +0 -19
  194. package/lib/listener/retry.js +0 -68
  195. package/lib/listener/timeout.js +0 -109
  196. package/lib/mochaFactory.js +0 -110
  197. package/lib/plugin/allure.js +0 -15
  198. package/lib/plugin/commentStep.js +0 -136
  199. package/lib/plugin/debugErrors.js +0 -67
  200. package/lib/plugin/eachElement.js +0 -127
  201. package/lib/plugin/fakerTransform.js +0 -49
  202. package/lib/plugin/retryTo.js +0 -121
  203. package/lib/plugin/selenoid.js +0 -371
  204. package/lib/plugin/standardActingHelpers.js +0 -9
  205. package/lib/plugin/tryTo.js +0 -105
  206. package/lib/plugin/wdio.js +0 -246
  207. package/lib/scenario.js +0 -222
  208. package/lib/ui.js +0 -238
  209. package/lib/within.js +0 -70
@@ -1,132 +1,134 @@
1
- import escapeStringRegexp from 'escape-string-regexp';
2
- import fs from 'fs';
3
- import Gherkin from '@cucumber/gherkin';
4
- import * as Messages from '@cucumber/messages';
5
- import glob from 'glob';
6
- import fsPath from 'path';
7
- import { getConfig, getTestRoot } from '../utils.js';
8
- import Codecept from '../../codecept.js';
9
- import * as output from '../../output.js';
10
- import { matchStep } from '../../interfaces/bdd.js';
1
+ import escapeStringRegexp from 'escape-string-regexp'
2
+ import fs from 'fs'
3
+ import Gherkin from '@cucumber/gherkin'
4
+ import { IdGenerator } from '@cucumber/messages'
5
+ import { globSync } from 'glob'
6
+ import fsPath from 'path'
11
7
 
12
- const uuidFn = Messages.IdGenerator.uuid();
13
- const builder = new Gherkin.AstBuilder(uuidFn);
14
- const matcher = new Gherkin.GherkinClassicTokenMatcher();
15
- const parser = new Gherkin.Parser(builder, matcher);
16
- parser.stopAtFirstError = false;
8
+ import { getConfig, getTestRoot } from '../utils.js'
9
+ import Codecept from '../../codecept.js'
10
+ import output from '../../output.js'
11
+ import { matchStep } from '../../mocha/bdd.js'
17
12
 
18
- export default function (genPath, options) {
19
- const configFile = options.config || genPath;
20
- const testsPath = getTestRoot(configFile);
21
- const config = getConfig(configFile);
22
- if (!config) return;
13
+ const uuidFn = IdGenerator.uuid()
14
+ const builder = new Gherkin.AstBuilder(uuidFn)
15
+ const matcher = new Gherkin.GherkinClassicTokenMatcher()
16
+ const parser = new Gherkin.Parser(builder, matcher)
17
+ parser.stopAtFirstError = false
23
18
 
24
- const codecept = new Codecept(config, {});
25
- codecept.init(testsPath);
19
+ export default async function (genPath, options) {
20
+ const configFile = options.config || genPath
21
+ const testsPath = getTestRoot(configFile)
22
+ const config = await getConfig(configFile)
23
+ if (!config) return
24
+
25
+ const codecept = new Codecept(config, {})
26
+ await codecept.init(testsPath)
26
27
 
27
28
  if (!config.gherkin) {
28
- output.output.error('Gherkin is not enabled in config. Run `codecept gherkin:init` to enable it');
29
- process.exit(1);
29
+ output.error('Gherkin is not enabled in config. Run `codecept gherkin:init` to enable it')
30
+ process.exit(1)
30
31
  }
31
32
  if (!config.gherkin.steps || !config.gherkin.steps[0]) {
32
- output.output.error('No gherkin steps defined in config. Exiting');
33
- process.exit(1);
33
+ output.error('No gherkin steps defined in config. Exiting')
34
+ process.exit(1)
34
35
  }
35
36
  if (!options.feature && !config.gherkin.features) {
36
- output.output.error('No gherkin features defined in config. Exiting');
37
- process.exit(1);
37
+ output.error('No gherkin features defined in config. Exiting')
38
+ process.exit(1)
38
39
  }
39
40
  if (options.path && !config.gherkin.steps.includes(options.path)) {
40
- output.output.error(`You must include ${options.path} to the gherkin steps in your config file`);
41
- process.exit(1);
41
+ output.error(`You must include ${options.path} to the gherkin steps in your config file`)
42
+ process.exit(1)
42
43
  }
43
44
 
44
- const files = [];
45
- glob.sync(options.feature || config.gherkin.features, { cwd: options.feature ? '.' : global.codecept_dir }).forEach((file) => {
45
+ const files = []
46
+ globSync(options.feature || config.gherkin.features, { cwd: options.feature ? '.' : global.codecept_dir }).forEach(file => {
46
47
  if (!fsPath.isAbsolute(file)) {
47
- file = fsPath.join(global.codecept_dir, file);
48
+ file = fsPath.join(global.codecept_dir, file)
48
49
  }
49
- files.push(fsPath.resolve(file));
50
- });
51
- output.print(`Loaded ${files.length} files`);
50
+ files.push(fsPath.resolve(file))
51
+ })
52
+ output.print(`Loaded ${files.length} files`)
52
53
 
53
- const newSteps = new Map();
54
+ const newSteps = new Map()
54
55
 
55
- const parseSteps = (steps) => {
56
- const newSteps = [];
57
- let currentKeyword = '';
56
+ const parseSteps = steps => {
57
+ const newSteps = []
58
+ let currentKeyword = ''
58
59
  for (const step of steps) {
59
60
  if (step.keyword.trim() === 'And') {
60
- if (!currentKeyword) throw new Error(`There is no active keyword for step '${step.text}'`);
61
- step.keyword = currentKeyword;
61
+ if (!currentKeyword) throw new Error(`There is no active keyword for step '${step.text}'`)
62
+ step.keyword = currentKeyword
62
63
  }
63
- currentKeyword = step.keyword;
64
+ currentKeyword = step.keyword
64
65
  try {
65
- matchStep(step.text);
66
+ matchStep(step.text)
66
67
  } catch (err) {
67
- let stepLine;
68
+ let stepLine
68
69
  if (/[{}()/]/.test(step.text)) {
69
70
  stepLine = escapeStringRegexp(step.text)
70
71
  .replace(/\//g, '\\/')
71
72
  .replace(/\"(.*?)\"/g, '"(.*?)"')
72
73
  .replace(/(\d+\\\.\d+)/, '(\\d+\\.\\d+)')
73
- .replace(/ (\d+) /, ' (\\d+) ');
74
- stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: true });
74
+ .replace(/ (\d+) /, ' (\\d+) ')
75
+ stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: true })
75
76
  } else {
76
77
  stepLine = step.text
77
78
  .replace(/\"(.*?)\"/g, '{string}')
78
79
  .replace(/(\d+\.\d+)/, '{float}')
79
- .replace(/ (\d+) /, ' {int} ');
80
- stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: false });
80
+ .replace(/ (\d+) /, ' {int} ')
81
+ stepLine = Object.assign(stepLine, { type: step.keyword.trim(), location: step.location, regexp: false })
81
82
  }
82
- newSteps.push(stepLine);
83
+ newSteps.push(stepLine)
83
84
  }
84
85
  }
85
- return newSteps;
86
- };
86
+ return newSteps
87
+ }
87
88
 
88
- const parseFile = (file) => {
89
- console.log(file);
90
- const ast = parser.parse(fs.readFileSync(file).toString());
89
+ const parseFile = file => {
90
+ const ast = parser.parse(fs.readFileSync(file).toString())
91
91
  for (const child of ast.feature.children) {
92
- if (child.scenario.keyword === 'Scenario Outline') continue; // skip scenario outline
93
- parseSteps(child.scenario.steps).map((step) => {
94
- return Object.assign(step, { file: file.replace(global.codecept_dir, '').slice(1) });
95
- }).map((step) => newSteps.set(`${step.type}(${step})`, step));
92
+ if (child.scenario.keyword === 'Scenario Outline') continue // skip scenario outline
93
+ parseSteps(child.scenario.steps)
94
+ .map(step => {
95
+ return Object.assign(step, { file: file.replace(global.codecept_dir, '').slice(1) })
96
+ })
97
+ .map(step => newSteps.set(`${step.type}(${step})`, step))
96
98
  }
97
- };
99
+ }
98
100
 
99
- files.forEach(file => parseFile(file));
101
+ files.forEach(file => parseFile(file))
100
102
 
101
- let stepFile = options.path || config.gherkin.steps[0];
103
+ let stepFile = options.path || config.gherkin.steps[0]
102
104
  if (!fs.existsSync(stepFile)) {
103
- output.output.error(`Please enter a valid step file path ${stepFile}`);
104
- process.exit(1);
105
+ output.error(`Please enter a valid step file path ${stepFile}`)
106
+ process.exit(1)
105
107
  }
106
108
 
107
109
  if (!fsPath.isAbsolute(stepFile)) {
108
- stepFile = fsPath.join(global.codecept_dir, stepFile);
110
+ stepFile = fsPath.join(global.codecept_dir, stepFile)
109
111
  }
110
112
 
111
113
  const snippets = [...newSteps.values()]
112
114
  .filter((value, index, self) => self.indexOf(value) === index)
113
- .map((step) => {
115
+ .map(step => {
114
116
  return `
115
117
  ${step.type}(${step.regexp ? '/^' : "'"}${step}${step.regexp ? '$/' : "'"}, () => {
116
118
  // From "${step.file}" ${JSON.stringify(step.location)}
117
119
  throw new Error('Not implemented yet');
118
- });`;
119
- });
120
+ });`
121
+ })
120
122
 
121
123
  if (!snippets.length) {
122
- output.print('No new snippets found');
123
- return;
124
+ output.print('No new snippets found')
125
+ return
124
126
  }
125
- output.output.success(`Snippets generated: ${snippets.length}`);
126
- output.print(snippets.join('\n'));
127
+ output.success(`Snippets generated: ${snippets.length}`)
128
+ output.print(snippets.join('\n'))
127
129
 
128
130
  if (!options.dryRun) {
129
- output.output.success(`Snippets added to ${output.output.colors.bold(stepFile)}`);
130
- fs.writeFileSync(stepFile, fs.readFileSync(stepFile).toString() + snippets.join('\n') + '\n'); // eslint-disable-line
131
+ output.success(`Snippets added to ${output.colors.bold(stepFile)}`)
132
+ fs.writeFileSync(stepFile, fs.readFileSync(stepFile).toString() + snippets.join('\n') + '\n')
131
133
  }
132
134
  }
@@ -1,25 +1,28 @@
1
- import { getConfig, getTestRoot } from '../utils.js';
2
- import Codecept from '../../codecept.js';
3
- import * as output from '../../output.js';
4
- import { getSteps } from '../../interfaces/bdd.js';
1
+ import { getConfig, getTestRoot } from '../utils.js'
2
+ import Codecept from '../../codecept.js'
3
+ import output from '../../output.js'
4
+ import { getSteps, clearSteps } from '../../mocha/bdd.js'
5
5
 
6
- export default function (genPath, options) {
7
- const configFile = options.config || genPath;
8
- const testsPath = getTestRoot(configFile);
9
- const config = getConfig(configFile);
10
- if (!config) return;
6
+ export default async function (genPath, options) {
7
+ const configFile = options.config || genPath
8
+ const testsPath = getTestRoot(configFile)
9
+ const config = await getConfig(configFile)
10
+ if (!config) return
11
11
 
12
- const codecept = new Codecept(config, {});
13
- codecept.init(testsPath);
12
+ // Clear any previously loaded steps
13
+ clearSteps()
14
+
15
+ const codecept = new Codecept(config, {})
16
+ await codecept.init(testsPath)
14
17
 
15
- output.print('Gherkin Step Definitions:');
16
- output.print();
17
- const steps = getSteps();
18
+ output.print('Gherkin Step Definitions:')
19
+ output.print()
20
+ const steps = getSteps()
18
21
  for (const step of Object.keys(steps)) {
19
- output.print(` ${output.output.colors.bold(step)} ${output.output.colors.green(steps[step].line || '')}`);
22
+ output.print(` ${output.colors.bold(step)} ${output.colors.green(steps[step].line || '')}`)
20
23
  }
21
- output.print();
24
+ output.print()
22
25
  if (!Object.keys(steps).length) {
23
- output.output.error('No Gherkin steps defined');
26
+ output.error('No Gherkin steps defined')
24
27
  }
25
28
  }
@@ -1,44 +1,79 @@
1
- import envinfo from 'envinfo';
2
- import { getConfig, getTestRoot } from './utils.js';
3
- import Codecept from '../codecept.js';
4
- import * as codeceptInstance from '../codecept.js';
5
- import * as output from '../output.js';
1
+ import envinfo from 'envinfo'
2
+
3
+ import { getConfig, getTestRoot } from './utils.js'
4
+ import Codecept from '../codecept.js'
5
+ import output from '../output.js'
6
+ import { execSync } from 'child_process'
7
+
8
+ async function getPlaywrightBrowsers() {
9
+ try {
10
+ const regex = /(chromium|firefox|webkit)\s+version\s+([\d.]+)/gi
11
+ let versions = []
12
+
13
+ const info = execSync('npx playwright install --dry-run').toString().trim()
14
+
15
+ const matches = [...info.matchAll(regex)]
16
+
17
+ matches.forEach(match => {
18
+ const browser = match[1]
19
+ const version = match[2]
20
+ versions.push(`${browser}: ${version}`)
21
+ })
22
+
23
+ return versions.join(', ')
24
+ } catch (err) {
25
+ return 'Playwright not installed'
26
+ }
27
+ }
28
+
29
+ async function getOsBrowsers() {
30
+ const chromeInfo = await envinfo.helpers.getChromeInfo()
31
+ const edgeInfo = await envinfo.helpers.getEdgeInfo()
32
+ const firefoxInfo = await envinfo.helpers.getFirefoxInfo()
33
+ const safariInfo = await envinfo.helpers.getSafariInfo()
34
+
35
+ return [
36
+ `chrome: ${chromeInfo ? chromeInfo[1] : 'not installed'}`,
37
+ `edge: ${edgeInfo ? edgeInfo[1] : 'not installed'}`,
38
+ `firefox: ${firefoxInfo ? firefoxInfo[1] : 'not installed'}`,
39
+ `safari: ${safariInfo ? safariInfo[1] : 'not installed'}`,
40
+ ].join(', ')
41
+ }
6
42
 
7
43
  export default async function (path) {
8
- const testsPath = getTestRoot(path);
9
- const config = getConfig(testsPath);
10
- const codecept = new Codecept(config, {});
11
- codecept.init(testsPath);
12
-
13
- output.print('\n Environment information:-\n');
14
- const info = {};
15
- info.codeceptVersion = codeceptInstance.version();
16
- info.nodeInfo = await envinfo.helpers.getNodeInfo();
17
- info.osInfo = await envinfo.helpers.getOSInfo();
18
- info.cpuInfo = await envinfo.helpers.getCPUInfo();
19
- info.chromeInfo = await envinfo.helpers.getChromeInfo();
20
- info.edgeInfo = await envinfo.helpers.getEdgeInfo();
21
- info.firefoxInfo = await envinfo.helpers.getFirefoxInfo();
22
- info.safariInfo = await envinfo.helpers.getSafariInfo();
23
- const { helpers, plugins } = config;
24
- info.helpers = helpers || "You don't use any helpers";
25
- info.plugins = plugins || "You don't have any enabled plugins";
44
+ const testsPath = getTestRoot(path)
45
+ const config = await getConfig(testsPath)
46
+ const codecept = new Codecept(config, {})
47
+ codecept.init(testsPath)
48
+
49
+ output.print('\n Environment information: \n')
50
+ const info = {}
51
+ info.codeceptVersion = Codecept.version()
52
+ info.nodeInfo = await envinfo.helpers.getNodeInfo()
53
+ info.osInfo = await envinfo.helpers.getOSInfo()
54
+ info.cpuInfo = await envinfo.helpers.getCPUInfo()
55
+ info.osBrowsers = await getOsBrowsers()
56
+ info.playwrightBrowsers = await getPlaywrightBrowsers()
57
+
58
+ const { helpers, plugins } = config
59
+ info.helpers = helpers || "You don't use any helpers"
60
+ info.plugins = plugins || "You don't have any enabled plugins"
26
61
 
27
62
  for (const [key, value] of Object.entries(info)) {
28
63
  if (Array.isArray(value)) {
29
- output.print(`${key}: ${value[1]}`);
64
+ output.print(`${key}: ${value[1]}`)
30
65
  } else {
31
- output.print(`${key}: ${JSON.stringify(value, null, ' ')}`);
66
+ output.print(`${key}: ${JSON.stringify(value, null, ' ')}`)
32
67
  }
33
68
  }
34
- output.print('***************************************');
35
- output.print('If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs');
36
- output.print('Or ask them on our discussion board: https://codecept.discourse.group/');
37
- output.print('Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues');
38
- output.print('***************************************');
69
+ output.print('***************************************')
70
+ output.print('If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs')
71
+ output.print('Or ask them on our discussion board: https://codecept.discourse.group/')
72
+ output.print('Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues')
73
+ output.print('***************************************')
39
74
  }
40
75
 
41
- export async function getMachineInfo() {
76
+ export const getMachineInfo = async () => {
42
77
  const info = {
43
78
  nodeInfo: await envinfo.helpers.getNodeInfo(),
44
79
  osInfo: await envinfo.helpers.getOSInfo(),
@@ -47,17 +82,18 @@ export async function getMachineInfo() {
47
82
  edgeInfo: await envinfo.helpers.getEdgeInfo(),
48
83
  firefoxInfo: await envinfo.helpers.getFirefoxInfo(),
49
84
  safariInfo: await envinfo.helpers.getSafariInfo(),
50
- };
85
+ playwrightBrowsers: await getPlaywrightBrowsers(),
86
+ }
51
87
 
52
- output.print('***************************************');
88
+ output.print('***************************************')
53
89
  for (const [key, value] of Object.entries(info)) {
54
90
  if (Array.isArray(value)) {
55
- output.print(`${key}: ${value[1]}`);
91
+ output.print(`${key}: ${value[1]}`)
56
92
  } else {
57
- output.print(`${key}: ${JSON.stringify(value, null, ' ')}`);
93
+ output.print(`${key}: ${JSON.stringify(value, null, ' ')}`)
58
94
  }
59
95
  }
60
- output.print('If you need more detailed info, just run this: npx codeceptjs info');
61
- output.print('***************************************');
62
- return info;
96
+ output.print('If you need more detailed info, just run this: npx codeceptjs info')
97
+ output.print('***************************************')
98
+ return info
63
99
  }