codeceptjs 4.0.0-beta.3 → 4.0.0-beta.5

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 (155) hide show
  1. package/README.md +134 -119
  2. package/bin/codecept.js +12 -2
  3. package/bin/test-server.js +53 -0
  4. package/docs/webapi/clearCookie.mustache +1 -1
  5. package/lib/actor.js +66 -102
  6. package/lib/ai.js +130 -121
  7. package/lib/assert/empty.js +3 -5
  8. package/lib/assert/equal.js +4 -7
  9. package/lib/assert/include.js +4 -6
  10. package/lib/assert/throws.js +2 -4
  11. package/lib/assert/truth.js +2 -2
  12. package/lib/codecept.js +141 -86
  13. package/lib/command/check.js +201 -0
  14. package/lib/command/configMigrate.js +2 -4
  15. package/lib/command/definitions.js +8 -26
  16. package/lib/command/dryRun.js +30 -35
  17. package/lib/command/generate.js +10 -14
  18. package/lib/command/gherkin/snippets.js +75 -73
  19. package/lib/command/gherkin/steps.js +1 -1
  20. package/lib/command/info.js +42 -8
  21. package/lib/command/init.js +13 -12
  22. package/lib/command/interactive.js +10 -2
  23. package/lib/command/list.js +1 -1
  24. package/lib/command/run-multiple/chunk.js +48 -45
  25. package/lib/command/run-multiple.js +12 -35
  26. package/lib/command/run-workers.js +21 -58
  27. package/lib/command/utils.js +5 -6
  28. package/lib/command/workers/runTests.js +263 -222
  29. package/lib/container.js +386 -238
  30. package/lib/data/context.js +10 -13
  31. package/lib/data/dataScenarioConfig.js +8 -8
  32. package/lib/data/dataTableArgument.js +6 -6
  33. package/lib/data/table.js +5 -11
  34. package/lib/effects.js +223 -0
  35. package/lib/element/WebElement.js +327 -0
  36. package/lib/els.js +158 -0
  37. package/lib/event.js +21 -17
  38. package/lib/heal.js +88 -80
  39. package/lib/helper/AI.js +2 -1
  40. package/lib/helper/ApiDataFactory.js +4 -7
  41. package/lib/helper/Appium.js +50 -57
  42. package/lib/helper/FileSystem.js +3 -3
  43. package/lib/helper/GraphQLDataFactory.js +4 -4
  44. package/lib/helper/JSONResponse.js +75 -37
  45. package/lib/helper/Mochawesome.js +31 -9
  46. package/lib/helper/Nightmare.js +37 -58
  47. package/lib/helper/Playwright.js +267 -272
  48. package/lib/helper/Protractor.js +56 -87
  49. package/lib/helper/Puppeteer.js +247 -264
  50. package/lib/helper/REST.js +29 -17
  51. package/lib/helper/TestCafe.js +22 -47
  52. package/lib/helper/WebDriver.js +157 -368
  53. package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
  54. package/lib/helper/extras/Popup.js +22 -22
  55. package/lib/helper/network/utils.js +1 -1
  56. package/lib/helper/testcafe/testcafe-utils.js +27 -28
  57. package/lib/listener/emptyRun.js +55 -0
  58. package/lib/listener/exit.js +7 -10
  59. package/lib/listener/{retry.js → globalRetry.js} +5 -5
  60. package/lib/listener/globalTimeout.js +165 -0
  61. package/lib/listener/helpers.js +15 -15
  62. package/lib/listener/mocha.js +1 -1
  63. package/lib/listener/result.js +12 -0
  64. package/lib/listener/retryEnhancer.js +85 -0
  65. package/lib/listener/steps.js +32 -18
  66. package/lib/listener/store.js +20 -0
  67. package/lib/locator.js +1 -1
  68. package/lib/mocha/asyncWrapper.js +231 -0
  69. package/lib/{interfaces → mocha}/bdd.js +3 -3
  70. package/lib/mocha/cli.js +308 -0
  71. package/lib/mocha/factory.js +104 -0
  72. package/lib/{interfaces → mocha}/featureConfig.js +32 -12
  73. package/lib/{interfaces → mocha}/gherkin.js +26 -28
  74. package/lib/mocha/hooks.js +112 -0
  75. package/lib/mocha/index.js +12 -0
  76. package/lib/mocha/inject.js +29 -0
  77. package/lib/{interfaces → mocha}/scenarioConfig.js +31 -7
  78. package/lib/mocha/suite.js +82 -0
  79. package/lib/mocha/test.js +181 -0
  80. package/lib/mocha/types.d.ts +42 -0
  81. package/lib/mocha/ui.js +232 -0
  82. package/lib/output.js +93 -65
  83. package/lib/pause.js +160 -138
  84. package/lib/plugin/analyze.js +396 -0
  85. package/lib/plugin/auth.js +435 -0
  86. package/lib/plugin/autoDelay.js +8 -8
  87. package/lib/plugin/autoLogin.js +3 -338
  88. package/lib/plugin/commentStep.js +6 -1
  89. package/lib/plugin/coverage.js +10 -22
  90. package/lib/plugin/customLocator.js +3 -3
  91. package/lib/plugin/customReporter.js +52 -0
  92. package/lib/plugin/eachElement.js +1 -1
  93. package/lib/plugin/fakerTransform.js +1 -1
  94. package/lib/plugin/heal.js +36 -9
  95. package/lib/plugin/htmlReporter.js +1947 -0
  96. package/lib/plugin/pageInfo.js +140 -0
  97. package/lib/plugin/retryFailedStep.js +17 -18
  98. package/lib/plugin/retryTo.js +2 -113
  99. package/lib/plugin/screenshotOnFail.js +17 -58
  100. package/lib/plugin/selenoid.js +15 -35
  101. package/lib/plugin/standardActingHelpers.js +4 -1
  102. package/lib/plugin/stepByStepReport.js +56 -17
  103. package/lib/plugin/stepTimeout.js +5 -12
  104. package/lib/plugin/subtitles.js +4 -4
  105. package/lib/plugin/tryTo.js +3 -102
  106. package/lib/plugin/wdio.js +8 -10
  107. package/lib/recorder.js +155 -124
  108. package/lib/rerun.js +43 -42
  109. package/lib/result.js +161 -0
  110. package/lib/secret.js +1 -2
  111. package/lib/step/base.js +239 -0
  112. package/lib/step/comment.js +10 -0
  113. package/lib/step/config.js +50 -0
  114. package/lib/step/func.js +46 -0
  115. package/lib/step/helper.js +50 -0
  116. package/lib/step/meta.js +99 -0
  117. package/lib/step/record.js +74 -0
  118. package/lib/step/retry.js +11 -0
  119. package/lib/step/section.js +55 -0
  120. package/lib/step.js +21 -332
  121. package/lib/steps.js +50 -0
  122. package/lib/store.js +37 -5
  123. package/lib/template/heal.js +2 -11
  124. package/lib/test-server.js +323 -0
  125. package/lib/timeout.js +66 -0
  126. package/lib/utils.js +351 -218
  127. package/lib/within.js +75 -55
  128. package/lib/workerStorage.js +2 -1
  129. package/lib/workers.js +386 -277
  130. package/package.json +81 -75
  131. package/translations/de-DE.js +5 -3
  132. package/translations/fr-FR.js +5 -4
  133. package/translations/index.js +1 -0
  134. package/translations/it-IT.js +4 -3
  135. package/translations/ja-JP.js +4 -3
  136. package/translations/nl-NL.js +76 -0
  137. package/translations/pl-PL.js +4 -3
  138. package/translations/pt-BR.js +4 -3
  139. package/translations/ru-RU.js +4 -3
  140. package/translations/utils.js +9 -0
  141. package/translations/zh-CN.js +4 -3
  142. package/translations/zh-TW.js +4 -3
  143. package/typings/index.d.ts +197 -187
  144. package/typings/promiseBasedTypes.d.ts +53 -903
  145. package/typings/types.d.ts +372 -1042
  146. package/lib/cli.js +0 -257
  147. package/lib/helper/ExpectHelper.js +0 -391
  148. package/lib/helper/MockServer.js +0 -221
  149. package/lib/helper/SoftExpectHelper.js +0 -381
  150. package/lib/listener/artifacts.js +0 -19
  151. package/lib/listener/timeout.js +0 -109
  152. package/lib/mochaFactory.js +0 -113
  153. package/lib/plugin/debugErrors.js +0 -67
  154. package/lib/scenario.js +0 -224
  155. package/lib/ui.js +0 -236
@@ -0,0 +1,140 @@
1
+ const path = require('path')
2
+ const fs = require('fs')
3
+ const Container = require('../container')
4
+ const recorder = require('../recorder')
5
+ const event = require('../event')
6
+ const supportedHelpers = Container.STANDARD_ACTING_HELPERS
7
+ const { scanForErrorMessages } = require('../html')
8
+ const { output } = require('..')
9
+ const { humanizeString, ucfirst } = require('../utils')
10
+ const { testToFileName } = require('../mocha/test')
11
+ const defaultConfig = {
12
+ errorClasses: ['error', 'warning', 'alert', 'danger'],
13
+ browserLogs: ['error'],
14
+ }
15
+
16
+ /**
17
+ * Collects information from web page after each failed test and adds it to the test as an artifact.
18
+ * It is suggested to enable this plugin if you run tests on CI and you need to debug failed tests.
19
+ * This plugin can be paired with `analyze` plugin to provide more context.
20
+ *
21
+ * It collects URL, HTML errors (by classes), and browser logs.
22
+ *
23
+ * Enable this plugin in config:
24
+ *
25
+ * ```js
26
+ * plugins: {
27
+ * pageInfo: {
28
+ * enabled: true,
29
+ * }
30
+ * ```
31
+ *
32
+ * Additional config options:
33
+ *
34
+ * * `errorClasses` - list of classes to search for errors (default: `['error', 'warning', 'alert', 'danger']`)
35
+ * * `browserLogs` - list of types of errors to search for in browser logs (default: `['error']`)
36
+ *
37
+ */
38
+ module.exports = function (config = {}) {
39
+ const helpers = Container.helpers()
40
+ let helper
41
+
42
+ config = Object.assign(defaultConfig, config)
43
+
44
+ for (const helperName of supportedHelpers) {
45
+ if (Object.keys(helpers).indexOf(helperName) > -1) {
46
+ helper = helpers[helperName]
47
+ }
48
+ }
49
+
50
+ if (!helper) return // no helpers for screenshot
51
+
52
+ event.dispatcher.on(event.test.failed, test => {
53
+ const pageState = {}
54
+
55
+ recorder.add('URL of failed test', async () => {
56
+ try {
57
+ const url = await helper.grabCurrentUrl()
58
+ pageState.url = url
59
+ } catch (err) {
60
+ // not really needed
61
+ }
62
+ })
63
+ recorder.add('HTML snapshot failed test', async () => {
64
+ try {
65
+ const html = await helper.grabHTMLFrom('body')
66
+
67
+ if (!html) return
68
+
69
+ const errors = scanForErrorMessages(html, config.errorClasses)
70
+ if (errors.length) {
71
+ output.debug('Detected errors in HTML code')
72
+ errors.forEach(error => output.debug(error))
73
+ pageState.htmlErrors = errors
74
+ }
75
+ } catch (err) {
76
+ // not really needed
77
+ }
78
+ })
79
+
80
+ recorder.add('Browser logs for failed test', async () => {
81
+ try {
82
+ const logs = await helper.grabBrowserLogs()
83
+
84
+ if (!logs) return
85
+
86
+ pageState.browserErrors = getBrowserErrors(logs, config.browserLogs)
87
+ } catch (err) {
88
+ // not really needed
89
+ }
90
+ })
91
+
92
+ recorder.add('Save page info', () => {
93
+ test.addNote('pageInfo', pageStateToMarkdown(pageState))
94
+
95
+ const pageStateFileName = path.join(global.output_dir, `${testToFileName(test)}.pageInfo.md`)
96
+ fs.writeFileSync(pageStateFileName, pageStateToMarkdown(pageState))
97
+ test.artifacts.pageInfo = pageStateFileName
98
+ return pageState
99
+ })
100
+ })
101
+ }
102
+
103
+ function pageStateToMarkdown(pageState) {
104
+ let markdown = ''
105
+
106
+ for (const [key, value] of Object.entries(pageState)) {
107
+ if (!value) continue
108
+ let result = ''
109
+
110
+ if (Array.isArray(value)) {
111
+ result = value.map(v => `- ${JSON.stringify(v, null, 2)}`).join('\n')
112
+ } else if (typeof value === 'string') {
113
+ result = `${value}`
114
+ } else {
115
+ result = JSON.stringify(value, null, 2)
116
+ }
117
+
118
+ if (!result.trim()) continue
119
+
120
+ markdown += `### ${ucfirst(humanizeString(key))}\n\n`
121
+ markdown += result
122
+ markdown += '\n\n'
123
+ }
124
+
125
+ return markdown
126
+ }
127
+
128
+ function getBrowserErrors(logs, type = ['error']) {
129
+ // Playwright & WebDriver console messages
130
+ let errors = logs
131
+ .map(log => {
132
+ if (typeof log === 'string') return log
133
+ if (!log.type) return null
134
+ return { type: log.type(), text: log.text() }
135
+ })
136
+ .filter(l => l && (typeof l === 'string' || type.includes(l.type)))
137
+ .map(l => (typeof l === 'string' ? l : l.text))
138
+
139
+ return errors
140
+ }
@@ -1,8 +1,6 @@
1
1
  const event = require('../event')
2
2
  const recorder = require('../recorder')
3
- const container = require('../container')
4
- const { log } = require('../output')
5
-
3
+ const store = require('../store')
6
4
  const defaultConfig = {
7
5
  retries: 3,
8
6
  defaultIgnoredSteps: ['amOnPage', 'wait*', 'send*', 'execute*', 'run*', 'have*'],
@@ -70,34 +68,29 @@ const defaultConfig = {
70
68
  * Use scenario configuration to disable plugin for a test
71
69
  *
72
70
  * ```js
73
- * Scenario('scenario tite', () => {
71
+ * Scenario('scenario tite', { disableRetryFailedStep: true }, () => {
74
72
  * // test goes here
75
- * }).config(test => test.disableRetryFailedStep = true)
73
+ * })
76
74
  * ```
77
75
  *
78
76
  */
79
- module.exports = (config) => {
77
+ module.exports = config => {
80
78
  config = Object.assign(defaultConfig, config)
81
79
  config.ignoredSteps = config.ignoredSteps.concat(config.defaultIgnoredSteps)
82
80
  const customWhen = config.when
83
81
 
84
82
  let enableRetry = false
85
83
 
86
- const when = (err) => {
84
+ const when = err => {
87
85
  if (!enableRetry) return
88
- const store = require('../store')
89
86
  if (store.debugMode) return false
87
+ if (!store.autoRetries) return false
90
88
  if (customWhen) return customWhen(err)
91
89
  return true
92
90
  }
93
91
  config.when = when
94
92
 
95
- event.dispatcher.on(event.step.started, (step) => {
96
- if (process.env.TRY_TO === 'true') {
97
- log('Info: RetryFailedStep plugin is disabled inside tryTo block')
98
- return
99
- }
100
-
93
+ event.dispatcher.on(event.step.started, step => {
101
94
  // if a step is ignored - return
102
95
  for (const ignored of config.ignoredSteps) {
103
96
  if (step.name === ignored) return
@@ -112,10 +105,16 @@ module.exports = (config) => {
112
105
  enableRetry = false
113
106
  })
114
107
 
115
- event.dispatcher.on(event.test.before, (test) => {
116
- if (test && test.disableRetryFailedStep) return // disable retry when a test is not active
117
- // this env var is used to set the retries inside _before() block of helpers
118
- process.env.FAILED_STEP_RETRIES = config.retries
108
+ event.dispatcher.on(event.test.before, test => {
109
+ // pass disableRetryFailedStep is a preferred way to disable retries
110
+ // test.disableRetryFailedStep is used for backward compatibility
111
+ if (test.opts.disableRetryFailedStep || test.disableRetryFailedStep) {
112
+ store.autoRetries = false
113
+ return // disable retry when a test is not active
114
+ }
115
+ // this option is used to set the retries inside _before() block of helpers
116
+ store.autoRetries = true
117
+ test.opts.conditionalRetries = config.retries
119
118
  recorder.retry(config)
120
119
  })
121
120
  }
@@ -1,123 +1,12 @@
1
- const recorder = require('../recorder')
2
- const { debug } = require('../output')
1
+ const { retryTo } = require('../effects')
3
2
 
4
3
  const defaultConfig = {
5
4
  registerGlobal: true,
6
- pollInterval: 200,
7
5
  }
8
6
 
9
- /**
10
- *
11
- *
12
- * Adds global `retryTo` which retries steps a few times before failing.
13
- *
14
- * Enable this plugin in `codecept.conf.js` (enabled by default for new setups):
15
- *
16
- * ```js
17
- * plugins: {
18
- * retryTo: {
19
- * enabled: true
20
- * }
21
- * }
22
- * ```
23
- *
24
- * Use it in your tests:
25
- *
26
- * ```js
27
- * // retry these steps 5 times before failing
28
- * await retryTo((tryNum) => {
29
- * I.switchTo('#editor frame');
30
- * I.click('Open');
31
- * I.see('Opened')
32
- * }, 5);
33
- * ```
34
- * Set polling interval as 3rd argument (200ms by default):
35
- *
36
- * ```js
37
- * // retry these steps 5 times before failing
38
- * await retryTo((tryNum) => {
39
- * I.switchTo('#editor frame');
40
- * I.click('Open');
41
- * I.see('Opened')
42
- * }, 5, 100);
43
- * ```
44
- *
45
- * Default polling interval can be changed in a config:
46
- *
47
- * ```js
48
- * plugins: {
49
- * retryTo: {
50
- * enabled: true,
51
- * pollInterval: 500,
52
- * }
53
- * }
54
- * ```
55
- *
56
- * Disables retryFailedStep plugin for steps inside a block;
57
- *
58
- * Use this plugin if:
59
- *
60
- * * you need repeat a set of actions in flaky tests
61
- * * iframe was not rendered and you need to retry switching to it
62
- *
63
- *
64
- * #### Configuration
65
- *
66
- * * `pollInterval` - default interval between retries in ms. 200 by default.
67
- * * `registerGlobal` - to register `retryTo` function globally, true by default
68
- *
69
- * If `registerGlobal` is false you can use retryTo from the plugin:
70
- *
71
- * ```js
72
- * const retryTo = codeceptjs.container.plugins('retryTo');
73
- * ```
74
- *
75
- */
76
7
  module.exports = function (config) {
77
8
  config = Object.assign(defaultConfig, config)
78
- function retryTo(callback, maxTries, pollInterval = config.pollInterval) {
79
- return new Promise((done, reject) => {
80
- let tries = 1
81
-
82
- function handleRetryException(err) {
83
- recorder.throw(err)
84
- reject(err)
85
- }
86
-
87
- const tryBlock = async () => {
88
- tries++
89
- recorder.session.start(`retryTo ${tries}`)
90
- try {
91
- await callback(tries)
92
- } catch (err) {
93
- handleRetryException(err)
94
- }
95
-
96
- // Call done if no errors
97
- recorder.add(() => {
98
- recorder.session.restore(`retryTo ${tries}`)
99
- done(null)
100
- })
101
-
102
- // Catch errors and retry
103
- recorder.session.catch((err) => {
104
- recorder.session.restore(`retryTo ${tries}`)
105
- if (tries <= maxTries) {
106
- debug(`Error ${err}... Retrying`)
107
- recorder.add(`retryTo ${tries}`, () => setTimeout(tryBlock, pollInterval))
108
- } else {
109
- // if maxTries reached
110
- handleRetryException(err)
111
- }
112
- })
113
- }
114
-
115
- recorder.add('retryTo', tryBlock).catch((err) => {
116
- console.error('An error occurred:', err)
117
- done(null)
118
- })
119
- })
120
- }
9
+ console.log(`Deprecation Warning: 'retryTo' has been moved to the 'codeceptjs/effects' module. Disable retryTo plugin to remove this warning.`)
121
10
 
122
11
  if (config.registerGlobal) {
123
12
  global.retryTo = retryTo
@@ -5,8 +5,9 @@ const Container = require('../container')
5
5
  const recorder = require('../recorder')
6
6
  const event = require('../event')
7
7
  const output = require('../output')
8
- const { fileExists, clearString } = require('../utils')
8
+ const { fileExists } = require('../utils')
9
9
  const Codeceptjs = require('../index')
10
+ const { testToFileName } = require('../mocha/test')
10
11
 
11
12
  const defaultConfig = {
12
13
  uniqueScreenshotNames: false,
@@ -14,7 +15,7 @@ const defaultConfig = {
14
15
  fullPageScreenshots: false,
15
16
  }
16
17
 
17
- const supportedHelpers = require('./standardActingHelpers')
18
+ const supportedHelpers = Container.STANDARD_ACTING_HELPERS
18
19
 
19
20
  /**
20
21
  * Creates screenshot on failure. Screenshot is saved into `output` directory.
@@ -63,9 +64,7 @@ module.exports = function (config) {
63
64
  }
64
65
 
65
66
  if (Codeceptjs.container.mocha()) {
66
- options.reportDir =
67
- Codeceptjs.container.mocha().options.reporterOptions &&
68
- Codeceptjs.container.mocha().options.reporterOptions.reportDir
67
+ options.reportDir = Codeceptjs.container.mocha()?.options?.reporterOptions && Codeceptjs.container.mocha()?.options?.reporterOptions?.reportDir
69
68
  }
70
69
 
71
70
  if (options.disableScreenshots) {
@@ -73,30 +72,23 @@ module.exports = function (config) {
73
72
  return
74
73
  }
75
74
 
76
- event.dispatcher.on(event.test.failed, (test) => {
77
- if (test.ctx?._runnable.title.includes('hook: ')) {
78
- output.plugin(
79
- 'screenshotOnFail',
80
- 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.',
81
- )
75
+ event.dispatcher.on(event.test.failed, (test, _err, hookName) => {
76
+ if (hookName === 'BeforeSuite' || hookName === 'AfterSuite') {
77
+ // no browser here
82
78
  return
83
79
  }
80
+
84
81
  recorder.add(
85
82
  'screenshot of failed test',
86
83
  async () => {
87
- let fileName = clearString(test.title)
88
84
  const dataType = 'image/png'
89
85
  // This prevents data driven to be included in the failed screenshot file name
90
- if (fileName.indexOf('{') !== -1) {
91
- fileName = fileName.substr(0, fileName.indexOf('{') - 3).trim()
92
- }
93
- if (test.ctx && test.ctx.test && test.ctx.test.type === 'hook')
94
- fileName = clearString(`${test.title}_${test.ctx.test.title}`)
86
+ let fileName
87
+
95
88
  if (options.uniqueScreenshotNames && test) {
96
- const uuid = _getUUID(test)
97
- fileName = `${fileName.substring(0, 10)}_${uuid}.failed.png`
89
+ fileName = `${testToFileName(test, { unique: true })}.failed.png`
98
90
  } else {
99
- fileName += '.failed.png'
91
+ fileName = `${testToFileName(test)}.failed.png`
100
92
  }
101
93
  output.plugin('screenshotOnFail', 'Test failed, try to save a screenshot')
102
94
 
@@ -112,34 +104,20 @@ module.exports = function (config) {
112
104
 
113
105
  if (!test.artifacts) test.artifacts = {}
114
106
  test.artifacts.screenshot = path.join(global.output_dir, fileName)
115
- if (
116
- Container.mocha().options.reporterOptions['mocha-junit-reporter'] &&
117
- Container.mocha().options.reporterOptions['mocha-junit-reporter'].options.attachments
118
- ) {
107
+ if (Container.mocha().options.reporterOptions['mocha-junit-reporter'] && Container.mocha().options.reporterOptions['mocha-junit-reporter'].options.attachments) {
119
108
  test.attachments = [path.join(global.output_dir, fileName)]
120
109
  }
121
110
 
122
111
  const allureReporter = Container.plugins('allure')
123
112
  if (allureReporter) {
124
- allureReporter.addAttachment(
125
- 'Main session - Last Seen Screenshot',
126
- fs.readFileSync(path.join(global.output_dir, fileName)),
127
- dataType,
128
- )
113
+ allureReporter.addAttachment('Main session - Last Seen Screenshot', fs.readFileSync(path.join(global.output_dir, fileName)), dataType)
129
114
 
130
115
  if (helper.activeSessionName) {
131
116
  const sessions = helper.sessionPages || helper.sessionWindows
132
117
  for (const sessionName in sessions) {
133
118
  const screenshotFileName = `${sessionName}_${fileName}`
134
- test.artifacts[`${sessionName.replace(/ /g, '_')}_screenshot`] = path.join(
135
- global.output_dir,
136
- screenshotFileName,
137
- )
138
- allureReporter.addAttachment(
139
- `${sessionName} - Last Seen Screenshot`,
140
- fs.readFileSync(path.join(global.output_dir, screenshotFileName)),
141
- dataType,
142
- )
119
+ test.artifacts[`${sessionName.replace(/ /g, '_')}_screenshot`] = path.join(global.output_dir, screenshotFileName)
120
+ allureReporter.addAttachment(`${sessionName} - Last Seen Screenshot`, fs.readFileSync(path.join(global.output_dir, screenshotFileName)), dataType)
143
121
  }
144
122
  }
145
123
  }
@@ -150,14 +128,7 @@ module.exports = function (config) {
150
128
  }
151
129
  } catch (err) {
152
130
  output.plugin(err)
153
- if (
154
- err &&
155
- err.type &&
156
- err.type === 'RuntimeError' &&
157
- err.message &&
158
- (err.message.indexOf('was terminated due to') > -1 ||
159
- err.message.indexOf('no such window: target window already closed') > -1)
160
- ) {
131
+ if (err && err.type && err.type === 'RuntimeError' && err.message && (err.message.indexOf('was terminated due to') > -1 || err.message.indexOf('no such window: target window already closed') > -1)) {
161
132
  output.log(`Can't make screenshot, ${err}`)
162
133
  helper.isRunning = false
163
134
  }
@@ -166,16 +137,4 @@ module.exports = function (config) {
166
137
  true,
167
138
  )
168
139
  })
169
-
170
- function _getUUID(test) {
171
- if (test.uuid) {
172
- return test.uuid
173
- }
174
-
175
- if (test.ctx && test.ctx.test.uuid) {
176
- return test.ctx.test.uuid
177
- }
178
-
179
- return Math.floor(new Date().getTime() / 1000)
180
- }
181
140
  }
@@ -41,12 +41,7 @@ const dockerCreateScriptArr = [
41
41
  'aerokube/selenoid:latest-release -log-output-dir /opt/selenoid/logs',
42
42
  ]
43
43
 
44
- const dockerImageCheckScript = [
45
- 'docker images',
46
- "--filter reference='selenoid/video-recorder'",
47
- "--filter reference='selenoid/chrome:latest'",
48
- "--filter reference='selenoid/firefox:latest'",
49
- ].join(' ')
44
+ const dockerImageCheckScript = ['docker images', "--filter reference='selenoid/video-recorder'", "--filter reference='selenoid/chrome:latest'", "--filter reference='selenoid/firefox:latest'"].join(' ')
50
45
 
51
46
  let dockerCreateScript = dockerCreateScriptArr.join(' ')
52
47
  let dockerStartScript = 'docker start $name$'
@@ -56,8 +51,8 @@ let seleniumUrl = 'http://localhost:$port$'
56
51
  const supportedHelpers = ['WebDriver']
57
52
  const SELENOID_START_TIMEOUT = 2000
58
53
  const SELENOID_STOP_TIMEOUT = 10000
59
- const wait = (time) =>
60
- new Promise((res) => {
54
+ const wait = time =>
55
+ new Promise(res => {
61
56
  setTimeout(() => {
62
57
  // @ts-ignore
63
58
  res()
@@ -179,7 +174,7 @@ const wait = (time) =>
179
174
  *
180
175
  */
181
176
 
182
- const selenoid = (config) => {
177
+ const selenoid = config => {
183
178
  const helpers = container.helpers()
184
179
  let helperName
185
180
 
@@ -194,14 +189,7 @@ const selenoid = (config) => {
194
189
  return // no helpers for Selenoid
195
190
  }
196
191
 
197
- const {
198
- autoStart,
199
- name = 'selenoid',
200
- deletePassed = true,
201
- additionalParams = '',
202
- autoCreate = true,
203
- port = 4444,
204
- } = config
192
+ const { autoStart, name = 'selenoid', deletePassed = true, additionalParams = '', autoCreate = true, port = 4444 } = config
205
193
  const passedTests = []
206
194
 
207
195
  recorder.startUnlessRunning()
@@ -213,7 +201,7 @@ const selenoid = (config) => {
213
201
  output.debug('Staring Selenoid... ')
214
202
  return createAndStart(autoCreate)
215
203
  .then(() => output.debug('Selenoid started'))
216
- .catch((err) => {
204
+ .catch(err => {
217
205
  throw new Error(err.stack)
218
206
  })
219
207
  })
@@ -226,7 +214,7 @@ const selenoid = (config) => {
226
214
  .then(() => deletePassedTests(passedTests))
227
215
  .then(stopSelenoid)
228
216
  .then(() => output.debug('Selenoid stopped'))
229
- .catch((err) => {
217
+ .catch(err => {
230
218
  throw new Error(err.stack)
231
219
  })
232
220
  })
@@ -241,7 +229,7 @@ const selenoid = (config) => {
241
229
  }
242
230
  })
243
231
 
244
- event.dispatcher.on(event.test.before, (test) => {
232
+ event.dispatcher.on(event.test.before, test => {
245
233
  switch (helperName) {
246
234
  case 'WebDriver':
247
235
  setTestConfigForWebdriver(test)
@@ -250,7 +238,7 @@ const selenoid = (config) => {
250
238
  })
251
239
 
252
240
  if (config.enableVideo) {
253
- event.dispatcher.on(event.test.passed, (test) => {
241
+ event.dispatcher.on(event.test.passed, test => {
254
242
  if (deletePassed) {
255
243
  passedTests.push(test.title)
256
244
  } else {
@@ -258,7 +246,7 @@ const selenoid = (config) => {
258
246
  }
259
247
  })
260
248
 
261
- event.dispatcher.on(event.test.failed, (test) => {
249
+ event.dispatcher.on(event.test.failed, test => {
262
250
  test.artifacts.video = videoSaved(test)
263
251
  })
264
252
  }
@@ -312,16 +300,12 @@ const pullImage = async () => {
312
300
  console.time('Pulled containers')
313
301
  if (!stdout.includes('selenoid/video-recorder')) {
314
302
  output.debug('Pulling selenoid/video-recorder...')
315
- resultPromise = exec('docker pull selenoid/video-recorder:latest-release').then(() =>
316
- output.debug('Pulled in selenoid/video-recorder'),
317
- )
303
+ resultPromise = exec('docker pull selenoid/video-recorder:latest-release').then(() => output.debug('Pulled in selenoid/video-recorder'))
318
304
  pulls.push(resultPromise)
319
305
  }
320
306
  if (!stdout.includes('selenoid/chrome')) {
321
307
  output.debug('Pulling selenoid/chrome...')
322
- resultPromise = exec('docker pull selenoid/chrome:latest').then(() =>
323
- output.debug('Pulled in selenoid/video-recorder'),
324
- )
308
+ resultPromise = exec('docker pull selenoid/chrome:latest').then(() => output.debug('Pulled in selenoid/video-recorder'))
325
309
  pulls.push(resultPromise)
326
310
  }
327
311
  if (!stdout.includes('selenoid/firefox')) {
@@ -341,16 +325,12 @@ function createAndStart(autoCreate) {
341
325
  }
342
326
 
343
327
  function deletePassedTests(passedTests) {
344
- const deleteVideoPromiseList = passedTests
345
- .map(clearString)
346
- .map((test) => axios.delete(`${seleniumUrl}/video/${test}.mp4`))
347
- const deleteLogPromiseList = passedTests
348
- .map(clearString)
349
- .map((test) => axios.delete(`${seleniumUrl}/logs/${test}.log`))
328
+ const deleteVideoPromiseList = passedTests.map(clearString).map(test => axios.delete(`${seleniumUrl}/video/${test}.mp4`))
329
+ const deleteLogPromiseList = passedTests.map(clearString).map(test => axios.delete(`${seleniumUrl}/logs/${test}.log`))
350
330
 
351
331
  return Promise.all(deleteVideoPromiseList.concat(deleteLogPromiseList))
352
332
  .then(() => output.debug('Deleted videos and logs for all passed tests'))
353
- .catch((err) => output.error(`Error while deleting video and log files ${err.stack}`))
333
+ .catch(err => output.error(`Error while deleting video and log files ${err.stack}`))
354
334
  }
355
335
 
356
336
  function setOptionsForWebdriver(config) {
@@ -1,3 +1,6 @@
1
- const standardActingHelpers = ['Playwright', 'WebDriver', 'Puppeteer', 'Appium', 'TestCafe']
1
+ const Container = require('../container')
2
+ // due to using this in internal tooling we won't post deprecation warning
3
+ // but please switch to Container.STANDARD_ACTING_HELPERS
4
+ const standardActingHelpers = Container.STANDARD_ACTING_HELPERS
2
5
 
3
6
  module.exports = standardActingHelpers