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,246 +0,0 @@
1
- import debug from 'debug';
2
-
3
- import container from '../container.js';
4
- import mainConfig from '../config.js';
5
- import recorder from '../recorder.js';
6
- import * as event from '../event.js';
7
- import * as output from '../output.js';
8
-
9
- debug('codeceptjs:plugin:wdio');
10
-
11
- const defaultConfig = {
12
- services: [],
13
- capabilities: {},
14
- };
15
-
16
- let restartsSession;
17
-
18
- /**
19
- * Webdriverio services runner.
20
- *
21
- * This plugin allows to run webdriverio services like:
22
- *
23
- * * selenium-standalone
24
- * * sauce
25
- * * testingbot
26
- * * browserstack
27
- * * appium
28
- *
29
- * A complete list of all available services can be found on [webdriverio website](https://webdriver.io).
30
- *
31
- * #### Setup
32
- *
33
- * 1. Install a webdriverio service
34
- * 2. Enable `wdio` plugin in config
35
- * 3. Add service name to `services` array inside wdio plugin config.
36
- *
37
- * See examples below:
38
- *
39
- * #### Selenium Standalone Service
40
- *
41
- * Install ` @wdio/selenium-standalone-service` package, as [described here](https://webdriver.io/docs/selenium-standalone-service.html).
42
- * It is important to make sure it is compatible with current webdriverio version.
43
- *
44
- * Enable `wdio` plugin in plugins list and add `selenium-standalone` service:
45
- *
46
- * ```js
47
- * plugins: {
48
- * wdio: {
49
- * enabled: true,
50
- * services: ['selenium-standalone']
51
- * // additional config for service can be passed here
52
- * }
53
- * }
54
- * ```
55
- *
56
- *
57
- * #### Sauce Service
58
- *
59
- * Install `@wdio/sauce-service` package, as [described here](https://webdriver.io/docs/sauce-service.html).
60
- * It is important to make sure it is compatible with current webdriverio version.
61
- *
62
- * Enable `wdio` plugin in plugins list and add `sauce` service:
63
- *
64
- * ```js
65
- * plugins: {
66
- * wdio: {
67
- * enabled: true,
68
- * services: ['sauce'],
69
- * user: ... ,// saucelabs username
70
- * key: ... // saucelabs api key
71
- * // additional config, from sauce service
72
- * }
73
- * }
74
- * ```
75
- *
76
- * ---
77
- *
78
- * In the same manner additional services from webdriverio can be installed, enabled, and configured.
79
- *
80
- * #### Configuration
81
- *
82
- * * `services` - list of enabled services
83
- * * ... - additional configuration passed into services.
84
- *
85
- */
86
- export default (config) => {
87
- // Keep initial configs to pass as options to wdio services
88
- const wdioOptions = { ...config };
89
- const webDriver = container.helpers('WebDriver');
90
- if (webDriver) {
91
- config = Object.assign(webDriver.options, config);
92
- restartsSession = !!config.restart;
93
- }
94
- config = Object.assign(defaultConfig, config);
95
- const seleniumInstallArgs = { ...config.seleniumInstallArgs };
96
- const seleniumArgs = { ...config.seleniumArgs };
97
-
98
- const services = [];
99
- const launchers = [];
100
-
101
- for (const name of config.services) {
102
- const Service = safeRequire(`@wdio/${name.toLowerCase()}-service`);
103
- if (Service) {
104
- if (Service.launcher && typeof Service.launcher === 'function') {
105
- const Launcher = Service.launcher;
106
-
107
- const options = {
108
- logPath: global.output_dir, installArgs: seleniumInstallArgs, args: seleniumArgs, ...wdioOptions,
109
- };
110
- launchers.push(new Launcher(options, [config.capabilities], config));
111
- }
112
- if (typeof Service === 'function') {
113
- services.push(new Service(config, config.capabilities));
114
- }
115
- continue;
116
- }
117
-
118
- throw new Error(`Couldn't initialize service ${name} from wdio plugin config.\nIt should be available either in '@wdio/${name.toLowerCase()}-service' package`);
119
- }
120
-
121
- debug(`services ${services}, launchers ${launchers}`);
122
-
123
- recorder.startUnlessRunning();
124
-
125
- for (const launcher of launchers) {
126
- registerLauncher(launcher);
127
- }
128
-
129
- for (const service of services) {
130
- registerService(service);
131
- }
132
-
133
- function registerService(service) {
134
- const name = service.constructor.name;
135
- if (service.beforeSession) {
136
- event.dispatcher.on(event.all.before, () => {
137
- recorder.add(`service ${name} all.before`, async () => {
138
- await service.beforeSession(config, config.capabilities);
139
- });
140
- });
141
- }
142
-
143
- if (service.afterSession) {
144
- event.dispatcher.on(event.all.result, (result) => {
145
- recorder.add(`service ${name} all.after`, async () => {
146
- await service.afterSession(result);
147
- });
148
- });
149
- }
150
-
151
- if (service.beforeSuite) {
152
- event.dispatcher.on(event.suite.before, (suite) => {
153
- debug(`suite started: ${suite.title}`);
154
- recorder.add(`service ${name} suite.before`, () => service.beforeSuite(suite));
155
- });
156
- }
157
-
158
- if (service.afterSuite) {
159
- event.dispatcher.on(event.suite.after, (suite) => {
160
- debug(`suite finished: ${suite.title}`);
161
- recorder.add(`service ${name} suite.after`, () => service.afterSuite(suite));
162
- });
163
- }
164
-
165
- if (service.beforeTest) {
166
- event.dispatcher.on(event.test.started, async (test) => {
167
- if (test.parent) {
168
- test.parent.toString = () => test.parent.title;
169
- }
170
- // test.parent = test.parent ? test.parent.title : null;
171
- debug(`test started: ${test.title}`);
172
- if (webDriver) {
173
- global.browser = webDriver.browser;
174
- global.browser.config = Object.assign(mainConfig.get('test', 1), global.browser.config);
175
- }
176
- await service.beforeTest(test);
177
- });
178
- }
179
-
180
- if (service.afterTest) {
181
- event.dispatcher.on(event.test.finished, async (test) => {
182
- debug(`test finished: ${test.title}`);
183
- await service.afterTest(test);
184
- });
185
- }
186
-
187
- if (restartsSession && service.before) {
188
- event.dispatcher.on(event.test.started, () => service.before());
189
- }
190
-
191
- if (restartsSession && service.after) {
192
- event.dispatcher.on(event.test.finished, () => service.after());
193
- }
194
-
195
- if (!restartsSession && service.before) {
196
- let initializedBrowser = false;
197
- event.dispatcher.on(event.test.started, async () => {
198
- if (!initializedBrowser) {
199
- await service.before();
200
- initializedBrowser = true;
201
- }
202
- });
203
- }
204
-
205
- if (!restartsSession && service.after) {
206
- event.dispatcher.on(event.all.result, result => service.after(result));
207
- }
208
- }
209
-
210
- function registerLauncher(launcher) {
211
- const name = launcher.constructor.name;
212
- if (launcher.onPrepare) {
213
- event.dispatcher.on(event.all.before, () => {
214
- recorder.add(`launcher ${name} start`, async () => {
215
- // browserstack-service expects capabilities as array
216
- if (launcher.constructor.name === 'BrowserstackLauncherService') {
217
- await launcher.onPrepare(config, [config.capabilities]);
218
- } else {
219
- await launcher.onPrepare(config, config.capabilities);
220
- }
221
- output.debug(`Started ${name}`);
222
- });
223
- });
224
- }
225
-
226
- if (launcher.onComplete) {
227
- event.dispatcher.on(event.all.after, () => {
228
- recorder.add(`launcher ${name} start`, async () => {
229
- await launcher.onComplete(process.exitCode, config, config.capabilities);
230
- output.debug(`Stopped ${name}`);
231
- });
232
- });
233
- }
234
- }
235
- };
236
-
237
- function safeRequire(name) {
238
- try {
239
- return require(name);
240
- } catch (e) {
241
- if (!e.message.match(`Cannot find module '${name}'`)) {
242
- throw new Error(`Couldn't initialise "${name}".\n${e.stack}`);
243
- }
244
- return null;
245
- }
246
- }
package/lib/scenario.js DELETED
@@ -1,222 +0,0 @@
1
- import promiseRetry from 'promise-retry';
2
- import * as event from './event.js';
3
- import recorder from './recorder.js';
4
- import assertThrown from './assert/throws.js';
5
- import { ucfirst, isAsyncFunction } from './utils.js';
6
- import * as parser from './parser.js';
7
- import Container from './container.js';
8
-
9
- const injectHook = function (inject, suite) {
10
- try {
11
- inject();
12
- } catch (err) {
13
- recorder.throw(err);
14
- }
15
- recorder.catch((err) => {
16
- event.emit(event.test.failed, suite, err);
17
- throw err;
18
- });
19
- return recorder.promise();
20
- };
21
-
22
- function makeDoneCallableOnce(done) {
23
- let called = false;
24
- return function (err) {
25
- if (called) {
26
- return;
27
- }
28
- called = true;
29
- return done(err);
30
- };
31
- }
32
- /**
33
- * Wraps test function, injects support objects from container,
34
- * starts promise chain with recorder, performs before/after hooks
35
- * through event system.
36
- */
37
- export function test(test) {
38
- const testFn = test.fn;
39
- if (!testFn) {
40
- return test;
41
- }
42
-
43
- test.steps = [];
44
- test.timeout(0);
45
- test.async = true;
46
-
47
- test.fn = function (done) {
48
- const doneFn = makeDoneCallableOnce(done);
49
- recorder.errHandler((err) => {
50
- recorder.session.start('teardown');
51
- recorder.cleanAsyncErr();
52
- if (test.throws) {
53
- // check that test should actually fail
54
- try {
55
- assertThrown(err, test.throws);
56
- event.emit(event.test.passed, test);
57
- event.emit(event.test.finished, test);
58
- recorder.add(doneFn);
59
- return;
60
- } catch (newErr) {
61
- err = newErr;
62
- }
63
- }
64
- event.emit(event.test.failed, test, err);
65
- event.emit(event.test.finished, test);
66
- recorder.add(() => doneFn(err));
67
- });
68
-
69
- if (isAsyncFunction(testFn)) {
70
- event.emit(event.test.started, test);
71
- testFn
72
- .call(test, getInjectedArguments(testFn, test))
73
- .then(() => {
74
- recorder.add('fire test.passed', () => {
75
- event.emit(event.test.passed, test);
76
- event.emit(event.test.finished, test);
77
- });
78
- recorder.add('finish test', doneFn);
79
- })
80
- .catch((err) => {
81
- recorder.throw(err);
82
- })
83
- .finally(() => {
84
- recorder.catch();
85
- });
86
- return;
87
- }
88
-
89
- try {
90
- event.emit(event.test.started, test);
91
- testFn.call(test, getInjectedArguments(testFn, test));
92
- } catch (err) {
93
- recorder.throw(err);
94
- } finally {
95
- recorder.add('fire test.passed', () => {
96
- event.emit(event.test.passed, test);
97
- event.emit(event.test.finished, test);
98
- });
99
- recorder.add('finish test', doneFn);
100
- recorder.catch();
101
- }
102
- };
103
- return test;
104
- }
105
-
106
- /**
107
- * Injects arguments to function from controller
108
- */
109
- export function injected(fn, suite, hookName) {
110
- return function (done) {
111
- const doneFn = makeDoneCallableOnce(done);
112
- const errHandler = (err) => {
113
- recorder.session.start('teardown');
114
- recorder.cleanAsyncErr();
115
- event.emit(event.test.failed, suite, err);
116
- if (hookName === 'after') event.emit(event.test.after, suite);
117
- if (hookName === 'afterSuite') event.emit(event.suite.after, suite);
118
- recorder.add(() => doneFn(err));
119
- };
120
-
121
- recorder.errHandler((err) => {
122
- errHandler(err);
123
- });
124
-
125
- if (!fn) throw new Error('fn is not defined');
126
-
127
- event.emit(event.hook.started, suite);
128
-
129
- this.test.body = fn.toString();
130
-
131
- if (!recorder.isRunning()) {
132
- recorder.errHandler((err) => {
133
- errHandler(err);
134
- });
135
- }
136
-
137
- const opts = suite.opts || {};
138
- const retries = opts[`retry${ucfirst(hookName)}`] || 0;
139
-
140
- promiseRetry(
141
- async (retry, number) => {
142
- try {
143
- recorder.startUnlessRunning();
144
- await fn.call(this, getInjectedArguments(fn));
145
- await recorder.promise().catch((err) => retry(err));
146
- } catch (err) {
147
- retry(err);
148
- } finally {
149
- if (number < retries) {
150
- recorder.stop();
151
- recorder.start();
152
- }
153
- }
154
- },
155
- { retries },
156
- )
157
- .then(() => {
158
- recorder.add('fire hook.passed', () => event.emit(event.hook.passed, suite));
159
- recorder.add(`finish ${hookName} hook`, doneFn);
160
- recorder.catch();
161
- })
162
- .catch((e) => {
163
- recorder.throw(e);
164
- recorder.catch((e) => {
165
- const err = recorder.getAsyncErr() === null ? e : recorder.getAsyncErr();
166
- errHandler(err);
167
- });
168
- recorder.add('fire hook.failed', () => event.emit(event.hook.failed, suite, e));
169
- });
170
- };
171
- }
172
-
173
- /**
174
- * Starts promise chain, so helpers could enqueue their hooks
175
- */
176
- export function setup(suite) {
177
- return injectHook(() => {
178
- recorder.startUnlessRunning();
179
- event.emit(event.test.before, suite && suite.ctx && suite.ctx.currentTest);
180
- }, suite);
181
- }
182
-
183
- export function teardown(suite) {
184
- return injectHook(() => {
185
- recorder.startUnlessRunning();
186
- event.emit(event.test.after, suite && suite.ctx && suite.ctx.currentTest);
187
- }, suite);
188
- }
189
-
190
- export function suiteSetup(suite) {
191
- return injectHook(() => {
192
- recorder.startUnlessRunning();
193
- event.emit(event.suite.before, suite);
194
- }, suite);
195
- }
196
-
197
- export function suiteTeardown(suite) {
198
- return injectHook(() => {
199
- recorder.startUnlessRunning();
200
- event.emit(event.suite.after, suite);
201
- }, suite);
202
- }
203
-
204
- export function getInjectedArguments(fn, test) {
205
- const testArgs = {};
206
- const params = parser.getParams(fn) || [];
207
- const objects = Container.support();
208
- for (const key of params) {
209
- testArgs[key] = {};
210
- if (test && test.inject && test.inject[key]) {
211
- // @FIX: need fix got inject
212
- testArgs[key] = test.inject[key];
213
- continue;
214
- }
215
- if (!objects[key]) {
216
- throw new Error(`Object of type ${key} is not defined in container`);
217
- }
218
- testArgs[key] = Container.support(key);
219
- }
220
-
221
- return testArgs;
222
- }
package/lib/ui.js DELETED
@@ -1,238 +0,0 @@
1
- import escapeRe from 'escape-string-regexp';
2
- import Suite from 'mocha/lib/suite.js';
3
- import Test from 'mocha/lib/test.js';
4
- import mocha0 from 'mocha/lib/interfaces/common.js';
5
- import * as scenario from './scenario.js';
6
- import ScenarioConfig from './interfaces/scenarioConfig.js';
7
- import FeatureConfig from './interfaces/featureConfig.js';
8
- import addDataContext from './data/context.js';
9
- import container from './container.js';
10
-
11
- const setContextTranslation = (context) => {
12
- const contexts = container.translation().value('contexts');
13
-
14
- if (contexts) {
15
- for (const key of Object.keys(contexts)) {
16
- if (context[key]) {
17
- context[contexts[key]] = context[key];
18
- }
19
- }
20
- }
21
- };
22
-
23
- /**
24
- * Codecept-style interface:
25
- *
26
- * Feature('login');
27
- *
28
- * Scenario('login as regular user', ({I}) {
29
- * I.fillField();
30
- * I.click();
31
- * I.see('Hello, '+data.login);
32
- * });
33
- *
34
- * @param {Mocha.Suite} suite Root suite.
35
- * @ignore
36
- */
37
- export function suite(suite) {
38
- const suites = [suite];
39
- suite.timeout(0);
40
- let afterAllHooks;
41
- let afterEachHooks;
42
- let afterAllHooksAreLoaded;
43
- let afterEachHooksAreLoaded;
44
-
45
- suite.on('pre-require', (context, file, mocha) => {
46
- const common = mocha0(suites, context, mocha);
47
-
48
- const addScenario = function (title, opts = {}, fn) {
49
- const suite = suites[0];
50
-
51
- if (typeof opts === 'function' && !fn) {
52
- fn = opts;
53
- opts = {};
54
- }
55
- if (suite.pending) {
56
- fn = null;
57
- }
58
- const test = new Test(title, fn);
59
- test.fullTitle = () => `${suite.title}: ${test.title}`;
60
-
61
- test.tags = (suite.tags || []).concat(title.match(/(\@[a-zA-Z0-9-_]+)/g) || []); // match tags from title
62
- test.file = file;
63
- if (!test.inject) {
64
- test.inject = {};
65
- }
66
-
67
- suite.addTest(scenario.test(test));
68
- if (opts.retries) test.retries(opts.retries);
69
- if (opts.timeout) test.totalTimeout = opts.timeout;
70
- test.opts = opts;
71
-
72
- return new ScenarioConfig(test);
73
- };
74
-
75
- // create dispatcher
76
-
77
- context.BeforeAll = common.before;
78
- context.AfterAll = common.after;
79
-
80
- context.run = mocha.options.delay && common.runWithSuite(suite);
81
- /**
82
- * Describe a "suite" with the given `title`
83
- * and callback `fn` containing nested suites
84
- * and/or tests.
85
- * @global
86
- * @param {string} title
87
- * @param {Object<string, *>} [opts]
88
- * @returns {FeatureConfig}
89
- */
90
-
91
- context.Feature = function (title, opts) {
92
- if (suites.length > 1) {
93
- suites.shift();
94
- }
95
-
96
- afterAllHooks = [];
97
- afterEachHooks = [];
98
- afterAllHooksAreLoaded = false;
99
- afterEachHooksAreLoaded = false;
100
-
101
- const suite = Suite.create(suites[0], title);
102
- if (!opts) opts = {};
103
- suite.opts = opts;
104
- suite.timeout(0);
105
-
106
- if (opts.retries) suite.retries(opts.retries);
107
- if (opts.timeout) suite.totalTimeout = opts.timeout;
108
-
109
- suite.tags = title.match(/(\@[a-zA-Z0-9-_]+)/g) || []; // match tags from title
110
- suite.file = file;
111
- suite.fullTitle = () => `${suite.title}:`;
112
- suites.unshift(suite);
113
- suite.beforeEach('codeceptjs.before', () => scenario.setup(suite));
114
- afterEachHooks.push(['finalize codeceptjs', () => scenario.teardown(suite)]);
115
-
116
- suite.beforeAll('codeceptjs.beforeSuite', () => scenario.suiteSetup(suite));
117
- afterAllHooks.push(['codeceptjs.afterSuite', () => scenario.suiteTeardown(suite)]);
118
-
119
- if (opts.skipInfo && opts.skipInfo.skipped) {
120
- suite.pending = true;
121
- suite.opts = { ...suite.opts, skipInfo: opts.skipInfo };
122
- }
123
-
124
- return new FeatureConfig(suite);
125
- };
126
-
127
- /**
128
- * Pending test suite.
129
- * @global
130
- * @kind constant
131
- * @type {CodeceptJS.IFeature}
132
- */
133
- context.xFeature = context.Feature.skip = function (title, opts) {
134
- const skipInfo = {
135
- skipped: true,
136
- message: 'Skipped due to "skip" on Feature.',
137
- };
138
- return context.Feature(title, { ...opts, skipInfo });
139
- };
140
-
141
- context.BeforeSuite = function (fn) {
142
- suites[0].beforeAll('BeforeSuite', scenario.injected(fn, suites[0], 'beforeSuite'));
143
- };
144
-
145
- context.AfterSuite = function (fn) {
146
- afterAllHooks.unshift(['AfterSuite', scenario.injected(fn, suites[0], 'afterSuite')]);
147
- };
148
-
149
- context.Background = context.Before = function (fn) {
150
- suites[0].beforeEach('Before', scenario.injected(fn, suites[0], 'before'));
151
- };
152
-
153
- context.After = function (fn) {
154
- afterEachHooks.unshift(['After', scenario.injected(fn, suites[0], 'after')]);
155
- };
156
-
157
- /**
158
- * Describe a specification or test-case
159
- * with the given `title` and callback `fn`
160
- * acting as a thunk.
161
- * @ignore
162
- */
163
- context.Scenario = addScenario;
164
- /**
165
- * Exclusive test-case.
166
- * @ignore
167
- */
168
- context.Scenario.only = function (title, opts, fn) {
169
- const reString = `^${escapeRe(`${suites[0].title}: ${title}`.replace(/( \| {.+})?$/g, ''))}`;
170
- mocha.grep(new RegExp(reString));
171
- process.env.SCENARIO_ONLY = true;
172
- return addScenario(title, opts, fn);
173
- };
174
-
175
- /**
176
- * Pending test case.
177
- * @global
178
- * @kind constant
179
- * @type {CodeceptJS.IScenario}
180
- */
181
- context.xScenario = context.Scenario.skip = function (title, opts = {}, fn) {
182
- if (typeof opts === 'function' && !fn) {
183
- opts = {};
184
- }
185
-
186
- return context.Scenario(title, opts);
187
- };
188
-
189
- /**
190
- * Pending test case with message: 'Test not implemented!'.
191
- * @global
192
- * @kind constant
193
- * @type {CodeceptJS.IScenario}
194
- */
195
- context.Scenario.todo = function (title, opts = {}, fn) {
196
- if (typeof opts === 'function' && !fn) {
197
- fn = opts;
198
- opts = {};
199
- }
200
-
201
- const skipInfo = {
202
- message: 'Test not implemented!',
203
- description: fn ? fn.toString() : '',
204
- };
205
-
206
- return context.Scenario(title, { ...opts, skipInfo });
207
- };
208
-
209
- /**
210
- * For translation
211
- */
212
-
213
- setContextTranslation(context);
214
-
215
- addDataContext(context);
216
- });
217
-
218
- suite.on('post-require', () => {
219
- /**
220
- * load hooks from arrays to suite to prevent reordering
221
- */
222
- if (!afterEachHooksAreLoaded && Array.isArray(afterEachHooks)) {
223
- afterEachHooks.forEach((hook) => {
224
- suites[0].afterEach(hook[0], hook[1]);
225
- });
226
- afterEachHooksAreLoaded = true;
227
- }
228
-
229
- if (!afterAllHooksAreLoaded && Array.isArray(afterAllHooks)) {
230
- afterAllHooks.forEach((hook) => {
231
- suites[0].afterAll(hook[0], hook[1]);
232
- });
233
- afterAllHooksAreLoaded = true;
234
- }
235
- });
236
- }
237
-
238
- export default suite;