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,121 +0,0 @@
1
- import recorder from '../recorder.js';
2
- import * as output from '../output.js';
3
-
4
- const defaultConfig = {
5
- registerGlobal: true,
6
- pollInterval: 200,
7
- };
8
-
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
- export default function (config) {
77
- config = Object.assign(defaultConfig, config);
78
-
79
- if (config.registerGlobal) {
80
- // @ts-ignore
81
- global.retryTo = retryTo;
82
- }
83
- return retryTo;
84
-
85
- function retryTo(callback, maxTries, pollInterval = undefined) {
86
- let tries = 1;
87
- if (!pollInterval) pollInterval = config.pollInterval;
88
-
89
- let err = null;
90
-
91
- return new Promise((done) => {
92
- const tryBlock = async () => {
93
- recorder.session.start(`retryTo ${tries}`);
94
- await callback(tries);
95
- recorder.add(() => {
96
- recorder.session.restore(`retryTo ${tries}`);
97
- done(null);
98
- });
99
- recorder.session.catch((e) => {
100
- err = e;
101
- recorder.session.restore(`retryTo ${tries}`);
102
- tries++;
103
- if (tries <= maxTries) {
104
- output.output.debug(`Error ${err}... Retrying`);
105
- err = null;
106
-
107
- recorder.add(`retryTo ${tries}`, () => setTimeout(tryBlock, pollInterval));
108
- } else {
109
- done(null);
110
- }
111
- });
112
- };
113
-
114
- recorder.add('retryTo', async () => {
115
- tryBlock();
116
- });
117
- }).then(() => {
118
- if (err) recorder.throw(err);
119
- });
120
- }
121
- }
@@ -1,371 +0,0 @@
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);
11
-
12
- const defaultBrowserConfig = {
13
- chrome: {
14
- default: 'latest',
15
- versions: {
16
- latest: {
17
- image: 'selenoid/chrome:latest',
18
- port: '4444',
19
- path: '/',
20
- },
21
- },
22
- },
23
- firefox: {
24
- default: 'latest',
25
- versions: {
26
- latest: {
27
- image: 'selenoid/firefox:latest',
28
- port: '4444',
29
- path: '/wd/hub',
30
- },
31
- },
32
- },
33
- };
34
-
35
- const dockerCreateScriptArr = [
36
- 'docker create --rm --name $name$',
37
- '-p $port$:4444',
38
- '-v /var/run/docker.sock:/var/run/docker.sock',
39
- `-v ${global.codecept_dir}/:/etc/selenoid/:ro`,
40
- `-v ${global.output_dir}/video/:/opt/selenoid/video/`,
41
- `-v ${global.output_dir}/logs/:/opt/selenoid/logs/`,
42
- `-e OVERRIDE_VIDEO_OUTPUT_DIR=${global.output_dir}/video/`,
43
- '$additionalParams$',
44
- 'aerokube/selenoid:latest-release -log-output-dir /opt/selenoid/logs',
45
- ];
46
-
47
- const dockerImageCheckScript = [
48
- '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
- });
68
-
69
- /**
70
- * [Selenoid](https://aerokube.com/selenoid/) plugin automatically starts browsers and video recording.
71
- * Works with WebDriver helper.
72
- *
73
- * ### Prerequisite
74
- *
75
- * This plugin **requires Docker** to be installed.
76
- *
77
- * > If you have issues starting Selenoid with this plugin consider using the official [Configuration Manager](https://aerokube.com/cm/latest/) tool from Selenoid
78
- *
79
- * ### Usage
80
- *
81
- * Selenoid plugin can be started in two ways:
82
- *
83
- * 1. **Automatic** - this plugin will create and manage selenoid container for you.
84
- * 2. **Manual** - you create the conatainer and configure it with a plugin (recommended).
85
- *
86
- * #### Automatic
87
- *
88
- * If you are new to Selenoid and you want plug and play setup use automatic mode.
89
- *
90
- * Add plugin configuration in `codecept.conf.js`:
91
- *
92
- * ```js
93
- * plugins: {
94
- * selenoid: {
95
- * enabled: true,
96
- * deletePassed: true,
97
- * autoCreate: true,
98
- * autoStart: true,
99
- * sessionTimeout: '30m',
100
- * enableVideo: true,
101
- * enableLog: true,
102
- * },
103
- * }
104
- * ```
105
- *
106
- * When `autoCreate` is enabled it will pull the [latest Selenoid from DockerHub](https://hub.docker.com/u/selenoid) and start Selenoid automatically.
107
- * It will also create `browsers.json` file required by Selenoid.
108
- *
109
- * In automatic mode the latest version of browser will be used for tests. It is recommended to specify exact version of each browser inside `browsers.json` file.
110
- *
111
- * > **If you are using Windows machine or if `autoCreate` does not work properly, create container manually**
112
- *
113
- * #### Manual
114
- *
115
- * While this plugin can create containers for you for better control it is recommended to create and launch containers manually.
116
- * This is especially useful for Continous Integration server as you can configure scaling for Selenoid containers.
117
- *
118
- * > Use [Selenoid Configuration Manager](https://aerokube.com/cm/latest/) to create and start containers semi-automatically.
119
- *
120
- * 1. Create `browsers.json` file in the same directory `codecept.conf.js` is located
121
- * [Refer to Selenoid documentation](https://aerokube.com/selenoid/latest/#_prepare_configuration) to know more about browsers.json.
122
- *
123
- * *Sample browsers.json*
124
- *
125
- * ```js
126
- * {
127
- * "chrome": {
128
- * "default": "latest",
129
- * "versions": {
130
- * "latest": {
131
- * "image": "selenoid/chrome:latest",
132
- * "port": "4444",
133
- * "path": "/"
134
- * }
135
- * }
136
- * }
137
- * }
138
- * ```
139
- *
140
- * > It is recommended to use specific versions of browsers in `browsers.json` instead of latest. This will prevent tests fail when browsers will be updated.
141
- *
142
- * **⚠ At first launch selenoid plugin takes extra time to download all Docker images before tests starts**.
143
- *
144
- * 2. Create Selenoid container
145
- *
146
- * Run the following command to create a container. To know more [refer here](https://aerokube.com/selenoid/latest/#_option_2_start_selenoid_container)
147
- *
148
- *
149
- * ```bash
150
- * docker create \
151
- * --name selenoid \
152
- * -p 4444:4444 \
153
- * -v /var/run/docker.sock:/var/run/docker.sock \
154
- * -v `pwd`/:/etc/selenoid/:ro \
155
- * -v `pwd`/output/video/:/opt/selenoid/video/ \
156
- * -e OVERRIDE_VIDEO_OUTPUT_DIR=`pwd`/output/video/ \
157
- * aerokube/selenoid:latest-release
158
- * ```
159
- *
160
- * ### Video Recording
161
- *
162
- * This plugin allows to record and save video per each executed tests.
163
- *
164
- * When `enableVideo` is `true` this plugin saves video in `output/videos` directory with each test by name
165
- * To save space videos for all succesful tests are deleted. This can be changed by `deletePassed` option.
166
- *
167
- * When `allure` plugin is enabled a video is attached to report automatically.
168
- *
169
- * ### Options:
170
- *
171
- * | Param | Description |
172
- * |--|--|
173
- * | name | Name of the container (default : selenoid) |
174
- * | port | Port of selenium server (default : 4444) |
175
- * | autoCreate | Will automatically create container (Linux only) (default : true)|
176
- * | autoStart | If disabled start the container manually before running tests (default : true)|
177
- * | enableVideo | Enable video recording and use `video` folder of output (default: false) |
178
- * | enableLog | Enable log recording and use `logs` folder of output (default: false) |
179
- * | deletePassed | Delete video and logs of passed tests (default : true)|
180
- * | additionalParams | example: `additionalParams: '--env TEST=test'` [Refer here](https://docs.docker.com/engine/reference/commandline/create/) to know more |
181
- *
182
- */
183
-
184
- const selenoid = (config) => {
185
- const helpers = container.helpers();
186
- let helperName;
187
-
188
- for (const name of supportedHelpers) {
189
- if (Object.keys(helpers).indexOf(name) > -1) {
190
- helperName = name;
191
- }
192
- }
193
-
194
- if (!helperName) {
195
- output.print(`Selenoid plugin supported only for: ${supportedHelpers.toString()}`);
196
- return; // no helpers for Selenoid
197
- }
198
-
199
- const {
200
- autoStart,
201
- name = 'selenoid',
202
- deletePassed = true,
203
- additionalParams = '',
204
- autoCreate = true,
205
- port = 4444,
206
- } = config;
207
- const passedTests = [];
208
-
209
- recorder.startUnlessRunning();
210
- replaceScriptConfig({ name, additionalParams, port });
211
-
212
- if (autoStart) {
213
- event.dispatcher.on(event.all.before, () => {
214
- recorder.add('Starting selenoid', () => {
215
- output.debug('Staring Selenoid... ');
216
- return createAndStart(autoCreate)
217
- .then(() => output.debug('Selenoid started'))
218
- .catch((err) => { throw new Error(err.stack); });
219
- });
220
- });
221
-
222
- event.dispatcher.on(event.all.after, () => {
223
- recorder.add('Stopping selenoid', () => {
224
- output.debug('Stopping Selenoid...');
225
- return wait(SELENOID_STOP_TIMEOUT)
226
- .then(() => deletePassedTests(passedTests))
227
- .then(stopSelenoid)
228
- .then(() => output.debug('Selenoid stopped'))
229
- .catch((err) => { throw new Error(err.stack); });
230
- });
231
- });
232
- }
233
-
234
- event.dispatcher.on(event.all.before, () => {
235
- switch (helperName) {
236
- case 'WebDriver': setOptionsForWebdriver(config); break;
237
- }
238
- });
239
-
240
- event.dispatcher.on(event.test.before, (test) => {
241
- switch (helperName) {
242
- case 'WebDriver': setTestConfigForWebdriver(test); break;
243
- }
244
- });
245
-
246
- if (config.enableVideo) {
247
- event.dispatcher.on(event.test.passed, (test) => {
248
- if (deletePassed) {
249
- passedTests.push(test.title);
250
- } else {
251
- test.artifacts.video = videoSaved(test);
252
- }
253
- });
254
-
255
- event.dispatcher.on(event.test.failed, (test) => {
256
- test.artifacts.video = videoSaved(test);
257
- });
258
- }
259
- };
260
-
261
- export default selenoid;
262
-
263
- 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');
268
- if (allureReporter) {
269
- allureReporter.addAttachment('Video', fs.readFileSync(videoFile), 'video/mp4');
270
- }
271
- return videoFile;
272
- }
273
-
274
- const createSelenoidConfig = () => {
275
- const configPath = path.join(global.codecept_dir, 'browsers.json');
276
- return new Promise((res, rej) => {
277
- try {
278
- if (fs.existsSync(configPath)) {
279
- res(true);
280
- } else {
281
- const data = new Uint8Array(Buffer.from(JSON.stringify(defaultBrowserConfig)));
282
- fs.writeFileSync(configPath, data);
283
- res(true);
284
- }
285
- } catch (err) {
286
- rej(err.stack);
287
- }
288
- });
289
- };
290
-
291
- const createSelenoid = () => exec(dockerCreateScript);
292
-
293
- const startSelenoid = () => exec(dockerStartScript);
294
-
295
- const stopSelenoid = () => exec(dockerStopScript);
296
-
297
- const checkDockerImage = () => exec(dockerImageCheckScript);
298
-
299
- const pullImage = async () => {
300
- const { stdout } = await checkDockerImage();
301
- const pulls = [];
302
- let resultPromise;
303
-
304
- output.print('Pulling in Selenoid containers. This may take a while when running the first time...');
305
-
306
- console.time('Pulled containers');
307
- 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);
312
- }
313
- 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);
318
- }
319
- 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);
324
- }
325
-
326
- return Promise.all(pulls).then(() => {
327
- console.timeEnd('Pulled containers');
328
- });
329
- };
330
-
331
- function createAndStart(autoCreate) {
332
- const selenoidCreated = autoCreate ? createSelenoidConfig().then(createSelenoid).then(pullImage) : Promise.resolve();
333
- return selenoidCreated.then(startSelenoid).then(() => wait(SELENOID_START_TIMEOUT));
334
- }
335
-
336
- 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`));
339
-
340
- return Promise.all(deleteVideoPromiseList.concat(deleteLogPromiseList))
341
- .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}`));
343
- }
344
-
345
- function setOptionsForWebdriver(config) {
346
- const WebDriver = container.helpers('WebDriver');
347
- WebDriver._setConfig(deepMerge(WebDriver.options, {
348
- capabilities: { 'selenoid:options': config },
349
- }));
350
- }
351
-
352
- function setTestConfigForWebdriver(test) {
353
- const WebDriver = container.helpers('WebDriver');
354
- const fileName = clearString(test.title);
355
- const { options } = WebDriver;
356
- 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
- });
362
- }
363
-
364
- function replaceScriptConfig(config) {
365
- for (const key of Object.keys(config)) {
366
- dockerCreateScript = dockerCreateScript.replace(new RegExp(`\\$${key}\\$`, 'g'), config[key]);
367
- }
368
- dockerStartScript = dockerStartScript.replace('$name$', config.name);
369
- dockerStopScript = dockerStopScript.replace('$name$', config.name);
370
- seleniumUrl = seleniumUrl.replace('$port$', config.port);
371
- }
@@ -1,9 +0,0 @@
1
- const standardActingHelpers = [
2
- 'Playwright',
3
- 'WebDriver',
4
- 'Puppeteer',
5
- 'Appium',
6
- 'TestCafe',
7
- ];
8
-
9
- export default standardActingHelpers;
@@ -1,105 +0,0 @@
1
- import recorder from '../recorder.js';
2
- import * as output from '../output.js';
3
-
4
- const defaultConfig = {
5
- registerGlobal: true,
6
- };
7
-
8
- /**
9
- *
10
- *
11
- * Adds global `tryTo` function in which all failed steps won't fail a test but will return true/false.
12
- *
13
- * Enable this plugin in `codecept.conf.js` (enabled by default for new setups):
14
- *
15
- * ```js
16
- * plugins: {
17
- * tryTo: {
18
- * enabled: true
19
- * }
20
- * }
21
- * ```
22
- * Use it in your tests:
23
- *
24
- * ```js
25
- * const result = await tryTo(() => I.see('Welcome'));
26
- *
27
- * // if text "Welcome" is on page, result => true
28
- * // if text "Welcome" is not on page, result => false
29
- * ```
30
- *
31
- * Disables retryFailedStep plugin for steps inside a block;
32
- *
33
- * Use this plugin if:
34
- *
35
- * * you need to perform multiple assertions inside a test
36
- * * there is A/B testing on a website you test
37
- * * there is "Accept Cookie" banner which may surprisingly appear on a page.
38
- *
39
- * #### Usage
40
- *
41
- * #### Multiple Conditional Assertions
42
- *
43
- * ```js
44
- *
45
- * Add assert requires first:
46
- * ```js
47
- * const assert = require('assert');
48
- * ```
49
- * Then use the assertion:
50
- * const result1 = await tryTo(() => I.see('Hello, user'));
51
- * const result2 = await tryTo(() => I.seeElement('.welcome'));
52
- * assert.ok(result1 && result2, 'Assertions were not succesful');
53
- * ```
54
- *
55
- * ##### Optional click
56
- *
57
- * ```js
58
- * I.amOnPage('/');
59
- * tryTo(() => I.click('Agree', '.cookies'));
60
- * ```
61
- *
62
- * #### Configuration
63
- *
64
- * * `registerGlobal` - to register `tryTo` function globally, true by default
65
- *
66
- * If `registerGlobal` is false you can use tryTo from the plugin:
67
- *
68
- * ```js
69
- * const tryTo = codeceptjs.container.plugins('tryTo');
70
- * ```
71
- *
72
- */
73
- export default function (config) {
74
- config = Object.assign(defaultConfig, config);
75
-
76
- if (config.registerGlobal) {
77
- global.tryTo = tryTo;
78
- }
79
- return tryTo;
80
- }
81
-
82
- export function tryTo(callback) {
83
- let result = false;
84
- return recorder.add('tryTo', () => {
85
- recorder.session.start('tryTo');
86
- process.env.TRY_TO = 'true';
87
- callback();
88
- recorder.add(() => {
89
- result = true;
90
- recorder.session.restore('tryTo');
91
- return result;
92
- });
93
- recorder.session.catch((err) => {
94
- result = false;
95
- const msg = err.inspect ? err.inspect() : err.toString();
96
- output.output.debug(`Unsuccessful try > ${msg}`);
97
- recorder.session.restore('tryTo');
98
- return result;
99
- });
100
- return recorder.add('result', () => {
101
- process.env.TRY_TO = undefined;
102
- return result;
103
- }, true, false);
104
- }, false, false);
105
- }