codeceptjs 4.0.0-beta.1 → 4.0.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/bin/codecept.js +84 -81
  2. package/lib/actor.js +13 -13
  3. package/lib/ai.js +10 -13
  4. package/lib/assert/empty.js +20 -21
  5. package/lib/assert/equal.js +37 -39
  6. package/lib/assert/error.js +14 -14
  7. package/lib/assert/include.js +46 -47
  8. package/lib/assert/throws.js +13 -11
  9. package/lib/assert/truth.js +19 -22
  10. package/lib/assert.js +4 -2
  11. package/lib/cli.js +57 -49
  12. package/lib/codecept.js +142 -155
  13. package/lib/colorUtils.js +3 -3
  14. package/lib/command/configMigrate.js +58 -52
  15. package/lib/command/definitions.js +88 -89
  16. package/lib/command/dryRun.js +71 -68
  17. package/lib/command/generate.js +197 -188
  18. package/lib/command/gherkin/init.js +27 -16
  19. package/lib/command/gherkin/snippets.js +20 -20
  20. package/lib/command/gherkin/steps.js +8 -8
  21. package/lib/command/info.js +40 -38
  22. package/lib/command/init.js +290 -288
  23. package/lib/command/interactive.js +32 -32
  24. package/lib/command/list.js +26 -26
  25. package/lib/command/run-multiple/chunk.js +5 -5
  26. package/lib/command/run-multiple/collection.js +3 -3
  27. package/lib/command/run-multiple/run.js +6 -2
  28. package/lib/command/run-multiple.js +113 -93
  29. package/lib/command/run-rerun.js +20 -25
  30. package/lib/command/run-workers.js +64 -66
  31. package/lib/command/run.js +26 -29
  32. package/lib/command/utils.js +80 -65
  33. package/lib/command/workers/runTests.js +10 -10
  34. package/lib/config.js +10 -9
  35. package/lib/container.js +40 -48
  36. package/lib/data/context.js +60 -59
  37. package/lib/data/dataScenarioConfig.js +47 -47
  38. package/lib/data/dataTableArgument.js +29 -29
  39. package/lib/data/table.js +26 -20
  40. package/lib/event.js +163 -167
  41. package/lib/heal.js +13 -17
  42. package/lib/helper/AI.js +130 -41
  43. package/lib/helper/ApiDataFactory.js +73 -69
  44. package/lib/helper/Appium.js +413 -382
  45. package/lib/helper/ExpectHelper.js +40 -48
  46. package/lib/helper/FileSystem.js +80 -79
  47. package/lib/helper/GraphQL.js +44 -43
  48. package/lib/helper/GraphQLDataFactory.js +50 -50
  49. package/lib/helper/JSONResponse.js +65 -62
  50. package/lib/helper/Mochawesome.js +28 -28
  51. package/lib/helper/MockServer.js +12 -14
  52. package/lib/helper/Nightmare.js +662 -566
  53. package/lib/helper/Playwright.js +1361 -1216
  54. package/lib/helper/Protractor.js +663 -627
  55. package/lib/helper/Puppeteer.js +1231 -1128
  56. package/lib/helper/REST.js +159 -68
  57. package/lib/helper/SoftExpectHelper.js +2 -2
  58. package/lib/helper/TestCafe.js +490 -484
  59. package/lib/helper/WebDriver.js +1297 -1156
  60. package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
  61. package/lib/helper/errors/ConnectionRefused.js +1 -1
  62. package/lib/helper/errors/ElementAssertion.js +2 -2
  63. package/lib/helper/errors/ElementNotFound.js +2 -2
  64. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +1 -1
  65. package/lib/helper/extras/Console.js +1 -1
  66. package/lib/helper/extras/PlaywrightPropEngine.js +2 -2
  67. package/lib/helper/extras/PlaywrightReactVueLocator.js +1 -1
  68. package/lib/helper/extras/PlaywrightRestartOpts.js +21 -18
  69. package/lib/helper/extras/Popup.js +1 -1
  70. package/lib/helper/extras/React.js +3 -3
  71. package/lib/helper/network/actions.js +14 -7
  72. package/lib/helper/network/utils.js +3 -2
  73. package/lib/helper/scripts/blurElement.js +1 -1
  74. package/lib/helper/scripts/focusElement.js +1 -1
  75. package/lib/helper/scripts/highlightElement.js +1 -1
  76. package/lib/helper/scripts/isElementClickable.js +1 -1
  77. package/lib/helper/testcafe/testControllerHolder.js +1 -1
  78. package/lib/helper/testcafe/testcafe-utils.js +6 -7
  79. package/lib/helper.js +1 -3
  80. package/lib/history.js +6 -5
  81. package/lib/hooks.js +6 -6
  82. package/lib/html.js +7 -7
  83. package/lib/index.js +25 -41
  84. package/lib/interfaces/bdd.js +47 -64
  85. package/lib/interfaces/featureConfig.js +19 -19
  86. package/lib/interfaces/gherkin.js +124 -118
  87. package/lib/interfaces/scenarioConfig.js +29 -29
  88. package/lib/listener/artifacts.js +9 -9
  89. package/lib/listener/config.js +24 -24
  90. package/lib/listener/exit.js +12 -12
  91. package/lib/listener/helpers.js +42 -42
  92. package/lib/listener/mocha.js +11 -11
  93. package/lib/listener/retry.js +32 -30
  94. package/lib/listener/steps.js +50 -53
  95. package/lib/listener/timeout.js +54 -54
  96. package/lib/locator.js +6 -10
  97. package/lib/mochaFactory.js +18 -15
  98. package/lib/output.js +6 -10
  99. package/lib/parser.js +15 -12
  100. package/lib/pause.js +40 -33
  101. package/lib/plugin/allure.js +15 -15
  102. package/lib/plugin/autoDelay.js +29 -37
  103. package/lib/plugin/autoLogin.js +70 -65
  104. package/lib/plugin/commentStep.js +18 -18
  105. package/lib/plugin/coverage.js +115 -67
  106. package/lib/plugin/customLocator.js +21 -20
  107. package/lib/plugin/debugErrors.js +24 -24
  108. package/lib/plugin/eachElement.js +38 -38
  109. package/lib/plugin/fakerTransform.js +6 -6
  110. package/lib/plugin/heal.js +67 -108
  111. package/lib/plugin/pauseOnFail.js +11 -11
  112. package/lib/plugin/retryFailedStep.js +32 -39
  113. package/lib/plugin/retryTo.js +46 -40
  114. package/lib/plugin/screenshotOnFail.js +109 -87
  115. package/lib/plugin/selenoid.js +131 -118
  116. package/lib/plugin/standardActingHelpers.js +2 -8
  117. package/lib/plugin/stepByStepReport.js +110 -91
  118. package/lib/plugin/stepTimeout.js +24 -23
  119. package/lib/plugin/subtitles.js +34 -35
  120. package/lib/plugin/tryTo.js +40 -30
  121. package/lib/plugin/wdio.js +78 -75
  122. package/lib/recorder.js +14 -17
  123. package/lib/rerun.js +11 -10
  124. package/lib/scenario.js +25 -23
  125. package/lib/secret.js +4 -2
  126. package/lib/session.js +10 -10
  127. package/lib/step.js +12 -9
  128. package/lib/store.js +2 -3
  129. package/lib/transform.js +1 -1
  130. package/lib/translation.js +7 -8
  131. package/lib/ui.js +12 -14
  132. package/lib/utils.js +70 -72
  133. package/lib/within.js +10 -10
  134. package/lib/workerStorage.js +27 -25
  135. package/lib/workers.js +29 -32
  136. package/package.json +56 -57
  137. package/translations/de-DE.js +1 -1
  138. package/translations/fr-FR.js +1 -1
  139. package/translations/index.js +9 -13
  140. package/translations/it-IT.js +1 -1
  141. package/translations/ja-JP.js +1 -1
  142. package/translations/pl-PL.js +1 -1
  143. package/translations/pt-BR.js +1 -1
  144. package/translations/ru-RU.js +1 -1
  145. package/translations/zh-CN.js +1 -1
  146. package/translations/zh-TW.js +1 -1
  147. package/typings/index.d.ts +415 -65
  148. package/typings/promiseBasedTypes.d.ts +32 -0
  149. package/typings/types.d.ts +32 -0
  150. package/lib/dirname.js +0 -5
  151. package/lib/helper/Expect.js +0 -425
@@ -1,19 +1,20 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import Container from '../container.js';
4
- import recorder from '../recorder.js';
5
- import * as event from '../event.js';
6
- import * as output from '../output.js';
7
- import { fileExists, clearString } from '../utils.js';
8
- import * as Codeceptjs from '../index.js';
1
+ const fs = require('fs')
2
+ const path = require('path')
9
3
 
10
- import supportedHelpers from './standardActingHelpers.js';
4
+ const Container = require('../container')
5
+ const recorder = require('../recorder')
6
+ const event = require('../event')
7
+ const output = require('../output')
8
+ const { fileExists, clearString } = require('../utils')
9
+ const Codeceptjs = require('../index')
11
10
 
12
11
  const defaultConfig = {
13
12
  uniqueScreenshotNames: false,
14
13
  disableScreenshots: false,
15
14
  fullPageScreenshots: false,
16
- };
15
+ }
16
+
17
+ const supportedHelpers = require('./standardActingHelpers')
17
18
 
18
19
  /**
19
20
  * Creates screenshot on failure. Screenshot is saved into `output` directory.
@@ -41,119 +42,140 @@ const defaultConfig = {
41
42
  *
42
43
  *
43
44
  */
44
- export default function (config) {
45
- const helpers = Container.helpers();
46
- let helper;
45
+ module.exports = function (config) {
46
+ const helpers = Container.helpers()
47
+ let helper
47
48
 
48
49
  for (const helperName of supportedHelpers) {
49
50
  if (Object.keys(helpers).indexOf(helperName) > -1) {
50
- helper = helpers[helperName];
51
+ helper = helpers[helperName]
51
52
  }
52
53
  }
53
54
 
54
- if (!helper) return; // no helpers for screenshot
55
+ if (!helper) return // no helpers for screenshot
55
56
 
56
- const options = Object.assign(defaultConfig, helper.options, config);
57
+ const options = Object.assign(defaultConfig, helper.options, config)
57
58
 
58
59
  if (helpers.Mochawesome) {
59
60
  if (helpers.Mochawesome.config) {
60
- options.uniqueScreenshotNames = helpers.Mochawesome.config.uniqueScreenshotNames;
61
+ options.uniqueScreenshotNames = helpers.Mochawesome.config.uniqueScreenshotNames
61
62
  }
62
63
  }
63
64
 
64
- if (Codeceptjs.container.mocha) {
65
- options.reportDir = Codeceptjs.container.mocha.options.reporterOptions
66
- && Codeceptjs.container.mocha.options.reporterOptions.reportDir;
65
+ if (Codeceptjs.container.mocha()) {
66
+ options.reportDir =
67
+ Codeceptjs.container.mocha().options.reporterOptions &&
68
+ Codeceptjs.container.mocha().options.reporterOptions.reportDir
67
69
  }
68
70
 
69
71
  if (options.disableScreenshots) {
70
72
  // old version of disabling screenshots
71
- return;
73
+ return
72
74
  }
73
75
 
74
76
  event.dispatcher.on(event.test.failed, (test) => {
75
77
  if (test.ctx?._runnable.title.includes('hook: ')) {
76
- output.output.plugin('screenshotOnFail', 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.');
78
+ output.plugin(
79
+ 'screenshotOnFail',
80
+ 'BeforeSuite/AfterSuite do not have any access to the browser, hence it could not take screenshot.',
81
+ )
77
82
  return
78
83
  }
79
-
80
- recorder.add('screenshot of failed test', async () => {
81
- let fileName = clearString(test.title);
82
- const dataType = 'image/png';
83
- // This prevents data driven to be included in the failed screenshot file name
84
- if (fileName.indexOf('{') !== -1) {
85
- fileName = fileName.substr(0, (fileName.indexOf('{') - 3)).trim();
86
- }
87
- if (test.ctx && test.ctx.test && test.ctx.test.type === 'hook') fileName = clearString(`${test.title}_${test.ctx.test.title}`);
88
- if (options.uniqueScreenshotNames && test) {
89
- const uuid = _getUUID(test);
90
- fileName = `${fileName.substring(0, 10)}_${uuid}.failed.png`;
91
- } else {
92
- fileName += '.failed.png';
93
- }
94
- output.output.plugin('screenshotOnFail', 'Test failed, try to save a screenshot');
95
-
96
- try {
97
- if (options.reportDir) {
98
- fileName = path.join(options.reportDir, fileName);
99
- const mochaReportDir = path.resolve(process.cwd(), options.reportDir);
100
- if (!fileExists(mochaReportDir)) {
101
- fs.mkdirSync(mochaReportDir);
102
- }
84
+ recorder.add(
85
+ 'screenshot of failed test',
86
+ async () => {
87
+ let fileName = clearString(test.title)
88
+ const dataType = 'image/png'
89
+ // 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()
103
92
  }
104
- await helper.saveScreenshot(fileName, options.fullPageScreenshots);
105
-
106
- if (!test.artifacts) test.artifacts = {};
107
- test.artifacts.screenshot = path.join(global.output_dir, fileName);
108
- if (Container.mocha().options.reporterOptions['mocha-junit-reporter'] && Container.mocha().options.reporterOptions['mocha-junit-reporter'].options.attachments) {
109
- test.attachments = [path.join(global.output_dir, fileName)];
93
+ if (test.ctx && test.ctx.test && test.ctx.test.type === 'hook')
94
+ fileName = clearString(`${test.title}_${test.ctx.test.title}`)
95
+ if (options.uniqueScreenshotNames && test) {
96
+ const uuid = _getUUID(test)
97
+ fileName = `${fileName.substring(0, 10)}_${uuid}.failed.png`
98
+ } else {
99
+ fileName += '.failed.png'
110
100
  }
101
+ output.plugin('screenshotOnFail', 'Test failed, try to save a screenshot')
102
+
103
+ try {
104
+ if (options.reportDir) {
105
+ fileName = path.join(options.reportDir, fileName)
106
+ const mochaReportDir = path.resolve(process.cwd(), options.reportDir)
107
+ if (!fileExists(mochaReportDir)) {
108
+ fs.mkdirSync(mochaReportDir)
109
+ }
110
+ }
111
+ await helper.saveScreenshot(fileName, options.fullPageScreenshots)
112
+
113
+ if (!test.artifacts) test.artifacts = {}
114
+ 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
+ ) {
119
+ test.attachments = [path.join(global.output_dir, fileName)]
120
+ }
111
121
 
112
- const allureReporter = Container.plugins('allure');
113
- if (allureReporter) {
114
- allureReporter.addAttachment('Main session - Last Seen Screenshot', fs.readFileSync(path.join(global.output_dir, fileName)), dataType);
115
-
116
- if (helper.activeSessionName) {
117
- for (const sessionName in helper.sessionPages) {
118
- const screenshotFileName = `${sessionName}_${fileName}`;
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);
122
+ const allureReporter = Container.plugins('allure')
123
+ if (allureReporter) {
124
+ allureReporter.addAttachment(
125
+ 'Main session - Last Seen Screenshot',
126
+ fs.readFileSync(path.join(global.output_dir, fileName)),
127
+ dataType,
128
+ )
129
+
130
+ if (helper.activeSessionName) {
131
+ const sessions = helper.sessionPages || helper.sessionWindows
132
+ for (const sessionName in sessions) {
133
+ 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
+ )
143
+ }
121
144
  }
122
145
  }
123
- }
124
146
 
125
- const cucumberReporter = Container.plugins('cucumberJsonReporter');
126
- if (cucumberReporter) {
127
- cucumberReporter.addScreenshot(test.artifacts.screenshot);
128
- }
129
- } catch (err) {
130
- output.output.plugin(err);
131
- if (
132
- err
133
- && err.type
134
- && err.type === 'RuntimeError'
135
- && err.message
136
- && (
137
- err.message.indexOf('was terminated due to') > -1
138
- || err.message.indexOf('no such window: target window already closed') > -1
139
- )
140
- ) {
141
- output.output.log(`Can't make screenshot, ${err}`);
142
- helper.isRunning = false;
147
+ const cucumberReporter = Container.plugins('cucumberJsonReporter')
148
+ if (cucumberReporter) {
149
+ cucumberReporter.addScreenshot(test.artifacts.screenshot)
150
+ }
151
+ } catch (err) {
152
+ 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
+ ) {
161
+ output.log(`Can't make screenshot, ${err}`)
162
+ helper.isRunning = false
163
+ }
143
164
  }
144
- }
145
- }, true);
146
- });
165
+ },
166
+ true,
167
+ )
168
+ })
147
169
 
148
170
  function _getUUID(test) {
149
171
  if (test.uuid) {
150
- return test.uuid;
172
+ return test.uuid
151
173
  }
152
174
 
153
- if (test.ctx && test.ctx.test?.uuid) {
154
- return test.ctx.test.uuid;
175
+ if (test.ctx && test.ctx.test.uuid) {
176
+ return test.ctx.test.uuid
155
177
  }
156
178
 
157
- return Math.floor(new Date().getTime() / 1000);
179
+ return Math.floor(new Date().getTime() / 1000)
158
180
  }
159
181
  }
@@ -1,13 +1,10 @@
1
- import util from 'util';
2
- import path from 'path';
3
- import fs from 'fs';
4
- import { default as axios } from 'axios';
5
- import { clearString, deepMerge } from '../utils.js';
6
- import {
7
- container, event, recorder, output,
8
- } from '../index.js';
9
-
10
- const exec = util.promisify(require('child_process').exec);
1
+ const util = require('util')
2
+ const path = require('path')
3
+ const fs = require('fs')
4
+ const axios = require('axios').default
5
+ const exec = util.promisify(require('child_process').exec)
6
+ const { clearString, deepMerge } = require('../utils')
7
+ const { container, event, recorder, output } = require('../index')
11
8
 
12
9
  const defaultBrowserConfig = {
13
10
  chrome: {
@@ -30,7 +27,7 @@ const defaultBrowserConfig = {
30
27
  },
31
28
  },
32
29
  },
33
- };
30
+ }
34
31
 
35
32
  const dockerCreateScriptArr = [
36
33
  'docker create --rm --name $name$',
@@ -42,29 +39,30 @@ const dockerCreateScriptArr = [
42
39
  `-e OVERRIDE_VIDEO_OUTPUT_DIR=${global.output_dir}/video/`,
43
40
  '$additionalParams$',
44
41
  'aerokube/selenoid:latest-release -log-output-dir /opt/selenoid/logs',
45
- ];
42
+ ]
46
43
 
47
44
  const dockerImageCheckScript = [
48
45
  'docker images',
49
- '--filter reference=\'selenoid/video-recorder\'',
50
- '--filter reference=\'selenoid/chrome:latest\'',
51
- '--filter reference=\'selenoid/firefox:latest\'',
52
- ].join(' ');
53
-
54
- let dockerCreateScript = dockerCreateScriptArr.join(' ');
55
- let dockerStartScript = 'docker start $name$';
56
- let dockerStopScript = 'docker stop $name$';
57
- let seleniumUrl = 'http://localhost:$port$';
58
-
59
- const supportedHelpers = ['WebDriver'];
60
- const SELENOID_START_TIMEOUT = 2000;
61
- const SELENOID_STOP_TIMEOUT = 10000;
62
- const wait = time => new Promise((res) => {
63
- setTimeout(() => {
64
- // @ts-ignore
65
- res();
66
- }, time);
67
- });
46
+ "--filter reference='selenoid/video-recorder'",
47
+ "--filter reference='selenoid/chrome:latest'",
48
+ "--filter reference='selenoid/firefox:latest'",
49
+ ].join(' ')
50
+
51
+ let dockerCreateScript = dockerCreateScriptArr.join(' ')
52
+ let dockerStartScript = 'docker start $name$'
53
+ let dockerStopScript = 'docker stop $name$'
54
+ let seleniumUrl = 'http://localhost:$port$'
55
+
56
+ const supportedHelpers = ['WebDriver']
57
+ const SELENOID_START_TIMEOUT = 2000
58
+ const SELENOID_STOP_TIMEOUT = 10000
59
+ const wait = (time) =>
60
+ new Promise((res) => {
61
+ setTimeout(() => {
62
+ // @ts-ignore
63
+ res()
64
+ }, time)
65
+ })
68
66
 
69
67
  /**
70
68
  * [Selenoid](https://aerokube.com/selenoid/) plugin automatically starts browsers and video recording.
@@ -182,18 +180,18 @@ const wait = time => new Promise((res) => {
182
180
  */
183
181
 
184
182
  const selenoid = (config) => {
185
- const helpers = container.helpers();
186
- let helperName;
183
+ const helpers = container.helpers()
184
+ let helperName
187
185
 
188
186
  for (const name of supportedHelpers) {
189
187
  if (Object.keys(helpers).indexOf(name) > -1) {
190
- helperName = name;
188
+ helperName = name
191
189
  }
192
190
  }
193
191
 
194
192
  if (!helperName) {
195
- output.print(`Selenoid plugin supported only for: ${supportedHelpers.toString()}`);
196
- return; // no helpers for Selenoid
193
+ output.print(`Selenoid plugin supported only for: ${supportedHelpers.toString()}`)
194
+ return // no helpers for Selenoid
197
195
  }
198
196
 
199
197
  const {
@@ -203,169 +201,184 @@ const selenoid = (config) => {
203
201
  additionalParams = '',
204
202
  autoCreate = true,
205
203
  port = 4444,
206
- } = config;
207
- const passedTests = [];
204
+ } = config
205
+ const passedTests = []
208
206
 
209
- recorder.startUnlessRunning();
210
- replaceScriptConfig({ name, additionalParams, port });
207
+ recorder.startUnlessRunning()
208
+ replaceScriptConfig({ name, additionalParams, port })
211
209
 
212
210
  if (autoStart) {
213
211
  event.dispatcher.on(event.all.before, () => {
214
212
  recorder.add('Starting selenoid', () => {
215
- output.debug('Staring Selenoid... ');
213
+ output.debug('Staring Selenoid... ')
216
214
  return createAndStart(autoCreate)
217
215
  .then(() => output.debug('Selenoid started'))
218
- .catch((err) => { throw new Error(err.stack); });
219
- });
220
- });
216
+ .catch((err) => {
217
+ throw new Error(err.stack)
218
+ })
219
+ })
220
+ })
221
221
 
222
222
  event.dispatcher.on(event.all.after, () => {
223
223
  recorder.add('Stopping selenoid', () => {
224
- output.debug('Stopping Selenoid...');
224
+ output.debug('Stopping Selenoid...')
225
225
  return wait(SELENOID_STOP_TIMEOUT)
226
226
  .then(() => deletePassedTests(passedTests))
227
227
  .then(stopSelenoid)
228
228
  .then(() => output.debug('Selenoid stopped'))
229
- .catch((err) => { throw new Error(err.stack); });
230
- });
231
- });
229
+ .catch((err) => {
230
+ throw new Error(err.stack)
231
+ })
232
+ })
233
+ })
232
234
  }
233
235
 
234
236
  event.dispatcher.on(event.all.before, () => {
235
237
  switch (helperName) {
236
- case 'WebDriver': setOptionsForWebdriver(config); break;
238
+ case 'WebDriver':
239
+ setOptionsForWebdriver(config)
240
+ break
237
241
  }
238
- });
242
+ })
239
243
 
240
244
  event.dispatcher.on(event.test.before, (test) => {
241
245
  switch (helperName) {
242
- case 'WebDriver': setTestConfigForWebdriver(test); break;
246
+ case 'WebDriver':
247
+ setTestConfigForWebdriver(test)
248
+ break
243
249
  }
244
- });
250
+ })
245
251
 
246
252
  if (config.enableVideo) {
247
253
  event.dispatcher.on(event.test.passed, (test) => {
248
254
  if (deletePassed) {
249
- passedTests.push(test.title);
255
+ passedTests.push(test.title)
250
256
  } else {
251
- test.artifacts.video = videoSaved(test);
257
+ test.artifacts.video = videoSaved(test)
252
258
  }
253
- });
259
+ })
254
260
 
255
261
  event.dispatcher.on(event.test.failed, (test) => {
256
- test.artifacts.video = videoSaved(test);
257
- });
262
+ test.artifacts.video = videoSaved(test)
263
+ })
258
264
  }
259
- };
265
+ }
260
266
 
261
- export default selenoid;
267
+ module.exports = selenoid
262
268
 
263
269
  function videoSaved(test) {
264
- const fileName = `${clearString(test.title)}.mp4`;
265
- const videoFile = path.join(global.output_dir, 'video', fileName);
266
- output.debug(`Video has been saved to file://${videoFile}`);
267
- const allureReporter = container.plugins('allure');
270
+ const fileName = `${clearString(test.title)}.mp4`
271
+ const videoFile = path.join(global.output_dir, 'video', fileName)
272
+ output.debug(`Video has been saved to file://${videoFile}`)
273
+ const allureReporter = container.plugins('allure')
268
274
  if (allureReporter) {
269
- allureReporter.addAttachment('Video', fs.readFileSync(videoFile), 'video/mp4');
275
+ allureReporter.addAttachment('Video', fs.readFileSync(videoFile), 'video/mp4')
270
276
  }
271
- return videoFile;
277
+ return videoFile
272
278
  }
273
279
 
274
280
  const createSelenoidConfig = () => {
275
- const configPath = path.join(global.codecept_dir, 'browsers.json');
281
+ const configPath = path.join(global.codecept_dir, 'browsers.json')
276
282
  return new Promise((res, rej) => {
277
283
  try {
278
284
  if (fs.existsSync(configPath)) {
279
- res(true);
285
+ res(true)
280
286
  } else {
281
- const data = new Uint8Array(Buffer.from(JSON.stringify(defaultBrowserConfig)));
282
- fs.writeFileSync(configPath, data);
283
- res(true);
287
+ const data = new Uint8Array(Buffer.from(JSON.stringify(defaultBrowserConfig)))
288
+ fs.writeFileSync(configPath, data)
289
+ res(true)
284
290
  }
285
291
  } catch (err) {
286
- rej(err.stack);
292
+ rej(err.stack)
287
293
  }
288
- });
289
- };
294
+ })
295
+ }
290
296
 
291
- const createSelenoid = () => exec(dockerCreateScript);
297
+ const createSelenoid = () => exec(dockerCreateScript)
292
298
 
293
- const startSelenoid = () => exec(dockerStartScript);
299
+ const startSelenoid = () => exec(dockerStartScript)
294
300
 
295
- const stopSelenoid = () => exec(dockerStopScript);
301
+ const stopSelenoid = () => exec(dockerStopScript)
296
302
 
297
- const checkDockerImage = () => exec(dockerImageCheckScript);
303
+ const checkDockerImage = () => exec(dockerImageCheckScript)
298
304
 
299
305
  const pullImage = async () => {
300
- const { stdout } = await checkDockerImage();
301
- const pulls = [];
302
- let resultPromise;
306
+ const { stdout } = await checkDockerImage()
307
+ const pulls = []
308
+ let resultPromise
303
309
 
304
- output.print('Pulling in Selenoid containers. This may take a while when running the first time...');
310
+ output.print('Pulling in Selenoid containers. This may take a while when running the first time...')
305
311
 
306
- console.time('Pulled containers');
312
+ console.time('Pulled containers')
307
313
  if (!stdout.includes('selenoid/video-recorder')) {
308
- output.debug('Pulling selenoid/video-recorder...');
309
- resultPromise = exec('docker pull selenoid/video-recorder:latest-release')
310
- .then(() => output.debug('Pulled in selenoid/video-recorder'));
311
- pulls.push(resultPromise);
314
+ 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
+ )
318
+ pulls.push(resultPromise)
312
319
  }
313
320
  if (!stdout.includes('selenoid/chrome')) {
314
- output.debug('Pulling selenoid/chrome...');
315
- resultPromise = exec('docker pull selenoid/chrome:latest')
316
- .then(() => output.debug('Pulled in selenoid/video-recorder'));
317
- pulls.push(resultPromise);
321
+ output.debug('Pulling selenoid/chrome...')
322
+ resultPromise = exec('docker pull selenoid/chrome:latest').then(() =>
323
+ output.debug('Pulled in selenoid/video-recorder'),
324
+ )
325
+ pulls.push(resultPromise)
318
326
  }
319
327
  if (!stdout.includes('selenoid/firefox')) {
320
- output.debug('Pulling selenoid/firefox...');
321
- resultPromise = exec('docker pull selenoid/firefox:latest')
322
- .then(() => output.debug('Pulled in selenoid/chrome'));
323
- pulls.push(resultPromise);
328
+ output.debug('Pulling selenoid/firefox...')
329
+ resultPromise = exec('docker pull selenoid/firefox:latest').then(() => output.debug('Pulled in selenoid/chrome'))
330
+ pulls.push(resultPromise)
324
331
  }
325
332
 
326
333
  return Promise.all(pulls).then(() => {
327
- console.timeEnd('Pulled containers');
328
- });
329
- };
334
+ console.timeEnd('Pulled containers')
335
+ })
336
+ }
330
337
 
331
338
  function createAndStart(autoCreate) {
332
- const selenoidCreated = autoCreate ? createSelenoidConfig().then(createSelenoid).then(pullImage) : Promise.resolve();
333
- return selenoidCreated.then(startSelenoid).then(() => wait(SELENOID_START_TIMEOUT));
339
+ const selenoidCreated = autoCreate ? createSelenoidConfig().then(createSelenoid).then(pullImage) : Promise.resolve()
340
+ return selenoidCreated.then(startSelenoid).then(() => wait(SELENOID_START_TIMEOUT))
334
341
  }
335
342
 
336
343
  function deletePassedTests(passedTests) {
337
- const deleteVideoPromiseList = passedTests.map(clearString).map(test => axios.delete(`${seleniumUrl}/video/${test}.mp4`));
338
- const deleteLogPromiseList = passedTests.map(clearString).map(test => axios.delete(`${seleniumUrl}/logs/${test}.log`));
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`))
339
350
 
340
351
  return Promise.all(deleteVideoPromiseList.concat(deleteLogPromiseList))
341
352
  .then(() => output.debug('Deleted videos and logs for all passed tests'))
342
- .catch(err => output.output.error(`Error while deleting video and log files ${err.stack}`));
353
+ .catch((err) => output.error(`Error while deleting video and log files ${err.stack}`))
343
354
  }
344
355
 
345
356
  function setOptionsForWebdriver(config) {
346
- const WebDriver = container.helpers('WebDriver');
347
- WebDriver._setConfig(deepMerge(WebDriver.options, {
348
- capabilities: { 'selenoid:options': config },
349
- }));
357
+ const WebDriver = container.helpers('WebDriver')
358
+ WebDriver._setConfig(
359
+ deepMerge(WebDriver.options, {
360
+ capabilities: { 'selenoid:options': config },
361
+ }),
362
+ )
350
363
  }
351
364
 
352
365
  function setTestConfigForWebdriver(test) {
353
- const WebDriver = container.helpers('WebDriver');
354
- const fileName = clearString(test.title);
355
- const { options } = WebDriver;
366
+ const WebDriver = container.helpers('WebDriver')
367
+ const fileName = clearString(test.title)
368
+ const { options } = WebDriver
356
369
  recorder.add('setting selenoid capabilities', () => {
357
- options.capabilities['selenoid:options'].name = test.title;
358
- options.capabilities['selenoid:options'].videoName = `${fileName}.mp4`;
359
- options.capabilities['selenoid:options'].logName = `${fileName}.log`;
360
- WebDriver._setConfig(options);
361
- });
370
+ options.capabilities['selenoid:options'].name = test.title
371
+ options.capabilities['selenoid:options'].videoName = `${fileName}.mp4`
372
+ options.capabilities['selenoid:options'].logName = `${fileName}.log`
373
+ WebDriver._setConfig(options)
374
+ })
362
375
  }
363
376
 
364
377
  function replaceScriptConfig(config) {
365
378
  for (const key of Object.keys(config)) {
366
- dockerCreateScript = dockerCreateScript.replace(new RegExp(`\\$${key}\\$`, 'g'), config[key]);
379
+ dockerCreateScript = dockerCreateScript.replace(new RegExp(`\\$${key}\\$`, 'g'), config[key])
367
380
  }
368
- dockerStartScript = dockerStartScript.replace('$name$', config.name);
369
- dockerStopScript = dockerStopScript.replace('$name$', config.name);
370
- seleniumUrl = seleniumUrl.replace('$port$', config.port);
381
+ dockerStartScript = dockerStartScript.replace('$name$', config.name)
382
+ dockerStopScript = dockerStopScript.replace('$name$', config.name)
383
+ seleniumUrl = seleniumUrl.replace('$port$', config.port)
371
384
  }
@@ -1,9 +1,3 @@
1
- const standardActingHelpers = [
2
- 'Playwright',
3
- 'WebDriver',
4
- 'Puppeteer',
5
- 'Appium',
6
- 'TestCafe',
7
- ];
1
+ const standardActingHelpers = ['Playwright', 'WebDriver', 'Puppeteer', 'Appium', 'TestCafe']
8
2
 
9
- export default standardActingHelpers;
3
+ module.exports = standardActingHelpers