codeceptjs 4.0.0-beta.4 → 4.0.0-beta.6.esm-aria

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 (188) hide show
  1. package/README.md +89 -119
  2. package/bin/codecept.js +53 -54
  3. package/docs/webapi/clearCookie.mustache +1 -1
  4. package/lib/actor.js +70 -102
  5. package/lib/ai.js +131 -121
  6. package/lib/assert/empty.js +11 -12
  7. package/lib/assert/equal.js +16 -21
  8. package/lib/assert/error.js +2 -2
  9. package/lib/assert/include.js +11 -15
  10. package/lib/assert/throws.js +3 -5
  11. package/lib/assert/truth.js +10 -7
  12. package/lib/assert.js +18 -18
  13. package/lib/codecept.js +112 -101
  14. package/lib/colorUtils.js +48 -50
  15. package/lib/command/check.js +206 -0
  16. package/lib/command/configMigrate.js +13 -14
  17. package/lib/command/definitions.js +24 -36
  18. package/lib/command/dryRun.js +16 -16
  19. package/lib/command/generate.js +38 -39
  20. package/lib/command/gherkin/init.js +36 -38
  21. package/lib/command/gherkin/snippets.js +76 -74
  22. package/lib/command/gherkin/steps.js +21 -18
  23. package/lib/command/info.js +49 -15
  24. package/lib/command/init.js +41 -37
  25. package/lib/command/interactive.js +22 -13
  26. package/lib/command/list.js +11 -10
  27. package/lib/command/run-multiple/chunk.js +50 -47
  28. package/lib/command/run-multiple/collection.js +5 -5
  29. package/lib/command/run-multiple/run.js +3 -3
  30. package/lib/command/run-multiple.js +27 -47
  31. package/lib/command/run-rerun.js +6 -7
  32. package/lib/command/run-workers.js +15 -66
  33. package/lib/command/run.js +8 -8
  34. package/lib/command/utils.js +22 -21
  35. package/lib/command/workers/runTests.js +131 -241
  36. package/lib/config.js +111 -49
  37. package/lib/container.js +589 -244
  38. package/lib/data/context.js +16 -18
  39. package/lib/data/dataScenarioConfig.js +9 -9
  40. package/lib/data/dataTableArgument.js +7 -7
  41. package/lib/data/table.js +6 -12
  42. package/lib/effects.js +307 -0
  43. package/lib/els.js +160 -0
  44. package/lib/event.js +24 -19
  45. package/lib/globals.js +141 -0
  46. package/lib/heal.js +89 -81
  47. package/lib/helper/AI.js +3 -2
  48. package/lib/helper/ApiDataFactory.js +19 -19
  49. package/lib/helper/Appium.js +47 -51
  50. package/lib/helper/FileSystem.js +35 -15
  51. package/lib/helper/GraphQL.js +1 -1
  52. package/lib/helper/GraphQLDataFactory.js +4 -4
  53. package/lib/helper/JSONResponse.js +72 -45
  54. package/lib/helper/Mochawesome.js +14 -11
  55. package/lib/helper/Playwright.js +832 -434
  56. package/lib/helper/Puppeteer.js +393 -292
  57. package/lib/helper/REST.js +32 -27
  58. package/lib/helper/WebDriver.js +320 -219
  59. package/lib/helper/errors/ConnectionRefused.js +6 -6
  60. package/lib/helper/errors/ElementAssertion.js +11 -16
  61. package/lib/helper/errors/ElementNotFound.js +5 -9
  62. package/lib/helper/errors/RemoteBrowserConnectionRefused.js +5 -5
  63. package/lib/helper/extras/Console.js +11 -11
  64. package/lib/helper/extras/PlaywrightLocator.js +110 -0
  65. package/lib/helper/extras/PlaywrightPropEngine.js +18 -18
  66. package/lib/helper/extras/PlaywrightRestartOpts.js +23 -23
  67. package/lib/helper/extras/Popup.js +22 -22
  68. package/lib/helper/extras/React.js +29 -30
  69. package/lib/helper/network/actions.js +33 -48
  70. package/lib/helper/network/utils.js +76 -83
  71. package/lib/helper/scripts/blurElement.js +6 -6
  72. package/lib/helper/scripts/focusElement.js +6 -6
  73. package/lib/helper/scripts/highlightElement.js +9 -9
  74. package/lib/helper/scripts/isElementClickable.js +34 -34
  75. package/lib/helper.js +2 -1
  76. package/lib/history.js +23 -20
  77. package/lib/hooks.js +10 -10
  78. package/lib/html.js +90 -100
  79. package/lib/index.js +48 -21
  80. package/lib/listener/config.js +8 -9
  81. package/lib/listener/emptyRun.js +54 -0
  82. package/lib/listener/exit.js +10 -12
  83. package/lib/listener/{retry.js → globalRetry.js} +10 -10
  84. package/lib/listener/globalTimeout.js +166 -0
  85. package/lib/listener/helpers.js +43 -24
  86. package/lib/listener/mocha.js +4 -5
  87. package/lib/listener/result.js +11 -0
  88. package/lib/listener/steps.js +26 -23
  89. package/lib/listener/store.js +20 -0
  90. package/lib/locator.js +213 -192
  91. package/lib/mocha/asyncWrapper.js +264 -0
  92. package/lib/mocha/bdd.js +167 -0
  93. package/lib/mocha/cli.js +341 -0
  94. package/lib/mocha/factory.js +160 -0
  95. package/lib/{interfaces → mocha}/featureConfig.js +33 -13
  96. package/lib/{interfaces → mocha}/gherkin.js +75 -45
  97. package/lib/mocha/hooks.js +121 -0
  98. package/lib/mocha/index.js +21 -0
  99. package/lib/mocha/inject.js +46 -0
  100. package/lib/{interfaces → mocha}/scenarioConfig.js +32 -8
  101. package/lib/mocha/suite.js +89 -0
  102. package/lib/mocha/test.js +178 -0
  103. package/lib/mocha/types.d.ts +42 -0
  104. package/lib/mocha/ui.js +229 -0
  105. package/lib/output.js +86 -64
  106. package/lib/parser.js +44 -44
  107. package/lib/pause.js +160 -139
  108. package/lib/plugin/analyze.js +403 -0
  109. package/lib/plugin/{autoLogin.js → auth.js} +137 -43
  110. package/lib/plugin/autoDelay.js +19 -15
  111. package/lib/plugin/coverage.js +22 -27
  112. package/lib/plugin/customLocator.js +5 -5
  113. package/lib/plugin/customReporter.js +53 -0
  114. package/lib/plugin/heal.js +49 -17
  115. package/lib/plugin/pageInfo.js +140 -0
  116. package/lib/plugin/pauseOnFail.js +4 -3
  117. package/lib/plugin/retryFailedStep.js +60 -19
  118. package/lib/plugin/screenshotOnFail.js +80 -83
  119. package/lib/plugin/stepByStepReport.js +70 -31
  120. package/lib/plugin/stepTimeout.js +7 -13
  121. package/lib/plugin/subtitles.js +10 -9
  122. package/lib/recorder.js +167 -126
  123. package/lib/rerun.js +94 -50
  124. package/lib/result.js +161 -0
  125. package/lib/secret.js +18 -17
  126. package/lib/session.js +95 -89
  127. package/lib/step/base.js +239 -0
  128. package/lib/step/comment.js +10 -0
  129. package/lib/step/config.js +50 -0
  130. package/lib/step/func.js +46 -0
  131. package/lib/step/helper.js +50 -0
  132. package/lib/step/meta.js +99 -0
  133. package/lib/step/record.js +74 -0
  134. package/lib/step/retry.js +11 -0
  135. package/lib/step/section.js +55 -0
  136. package/lib/step.js +18 -332
  137. package/lib/steps.js +54 -0
  138. package/lib/store.js +37 -5
  139. package/lib/template/heal.js +2 -11
  140. package/lib/timeout.js +60 -0
  141. package/lib/transform.js +8 -8
  142. package/lib/translation.js +32 -18
  143. package/lib/utils.js +354 -250
  144. package/lib/workerStorage.js +16 -16
  145. package/lib/workers.js +366 -282
  146. package/package.json +107 -95
  147. package/translations/de-DE.js +5 -4
  148. package/translations/fr-FR.js +5 -4
  149. package/translations/index.js +23 -9
  150. package/translations/it-IT.js +5 -4
  151. package/translations/ja-JP.js +5 -4
  152. package/translations/nl-NL.js +76 -0
  153. package/translations/pl-PL.js +5 -4
  154. package/translations/pt-BR.js +5 -4
  155. package/translations/ru-RU.js +5 -4
  156. package/translations/utils.js +18 -0
  157. package/translations/zh-CN.js +5 -4
  158. package/translations/zh-TW.js +5 -4
  159. package/typings/index.d.ts +177 -186
  160. package/typings/promiseBasedTypes.d.ts +3573 -5941
  161. package/typings/types.d.ts +4042 -6370
  162. package/lib/cli.js +0 -256
  163. package/lib/helper/ExpectHelper.js +0 -391
  164. package/lib/helper/Nightmare.js +0 -1504
  165. package/lib/helper/Protractor.js +0 -1863
  166. package/lib/helper/SoftExpectHelper.js +0 -381
  167. package/lib/helper/TestCafe.js +0 -1414
  168. package/lib/helper/clientscripts/nightmare.js +0 -213
  169. package/lib/helper/extras/PlaywrightReactVueLocator.js +0 -43
  170. package/lib/helper/testcafe/testControllerHolder.js +0 -42
  171. package/lib/helper/testcafe/testcafe-utils.js +0 -62
  172. package/lib/interfaces/bdd.js +0 -81
  173. package/lib/listener/artifacts.js +0 -19
  174. package/lib/listener/timeout.js +0 -109
  175. package/lib/mochaFactory.js +0 -113
  176. package/lib/plugin/allure.js +0 -15
  177. package/lib/plugin/commentStep.js +0 -136
  178. package/lib/plugin/debugErrors.js +0 -67
  179. package/lib/plugin/eachElement.js +0 -127
  180. package/lib/plugin/fakerTransform.js +0 -49
  181. package/lib/plugin/retryTo.js +0 -127
  182. package/lib/plugin/selenoid.js +0 -384
  183. package/lib/plugin/standardActingHelpers.js +0 -3
  184. package/lib/plugin/tryTo.js +0 -115
  185. package/lib/plugin/wdio.js +0 -249
  186. package/lib/scenario.js +0 -224
  187. package/lib/ui.js +0 -236
  188. package/lib/within.js +0 -70
@@ -1,213 +0,0 @@
1
- if (!window.codeceptjs) {
2
- /**
3
- * @alias CodeceptJS.browserCodecept
4
- * @namespace
5
- */
6
- const codeceptjs = {};
7
-
8
- /**
9
- * all found elements are stored here for reuse
10
- * @inner
11
- * @type {Node[]}
12
- */
13
- codeceptjs.elements = [];
14
-
15
- /**
16
- * global context changer
17
- * @inner
18
- * @type {?Node}
19
- */
20
- codeceptjs.within = null;
21
-
22
- // save
23
- const storeElement = function (el) {
24
- if (!el) return;
25
- return codeceptjs.elements.push(el) - 1; // return index
26
- };
27
-
28
- const storeElements = function (els) {
29
- return els.map(el => storeElement(el));
30
- };
31
-
32
- /**
33
- * finders
34
- * @param {number} id
35
- * @return {Node}
36
- */
37
- codeceptjs.fetchElement = function (id) {
38
- if (!this.elements[id]) throw new Error(`Element (${id}) is not accessible`);
39
- return this.elements[id];
40
- };
41
-
42
- /**
43
- * @param {string} by
44
- * @param {CodeceptJS.ILocator} locator
45
- * @param {*} [contextEl]
46
- * @return {number[]}
47
- */
48
- codeceptjs.findAndStoreElements = function (by, locator, contextEl) {
49
- return storeElements(this.findElements(by, locator, contextEl));
50
- };
51
-
52
- /**
53
- * @param {string} by
54
- * @param {CodeceptJS.ILocator} locator
55
- * @param {*} [contextEl]
56
- * @return {number | undefined}
57
- */
58
- codeceptjs.findAndStoreElement = function (by, locator, contextEl) {
59
- return storeElement(this.findElement(by, locator, contextEl));
60
- };
61
-
62
- /**
63
- * @param {string} by
64
- * @param {CodeceptJS.ILocator} locator
65
- */
66
- codeceptjs.setWithin = function (by, locator) {
67
- this.within = this.findElement(by, locator);
68
- };
69
-
70
- /**
71
- * @param {string} by
72
- * @param {CodeceptJS.ILocator} locator
73
- * @param {*} [contextEl]
74
- * @return {Node[]}
75
- */
76
- codeceptjs.findElements = function (by, locator, contextEl) {
77
- let context;
78
- if (typeof contextEl !== 'number') {
79
- context = this.within || document;
80
- } else {
81
- context = this.fetchElement(contextEl);
82
- }
83
-
84
- if (by === 'name') {
85
- by = 'css';
86
- locator = `*[name="${locator}"]`;
87
- }
88
- if (by === 'id') {
89
- by = 'css';
90
- locator = `#${locator}`;
91
- }
92
-
93
- if (by === 'css') {
94
- const found = context.querySelectorAll(locator);
95
- const res = [];
96
- for (let i = 0; i < found.length; i++) {
97
- res.push(found[i]);
98
- }
99
- return res;
100
- }
101
-
102
- if (by === 'xpath') {
103
- const found = document.evaluate(locator, context, null, 5, null);
104
- const res = [];
105
- let current = null;
106
- while (current = found.iterateNext()) {
107
- res.push(current);
108
- }
109
- return res;
110
- }
111
-
112
- if (by === 'frame') {
113
- if (!Array.isArray(locator)) locator = [locator];
114
- return [locator.reduce((parent, child) => parent.querySelector(child).contentDocument, window.document).querySelector('body')];
115
- }
116
- return [];
117
- };
118
-
119
- /**
120
- * @param {string} by
121
- * @param {CodeceptJS.ILocator} locator
122
- * @param {*} [context]
123
- * @return {?Node}
124
- */
125
- codeceptjs.findElement = function (by, locator, context) {
126
- return this.findElements(by, locator, context)[0] || null;
127
- };
128
-
129
- // actions
130
- /**
131
- * @param {number} el
132
- * @return {boolean}
133
- */
134
- codeceptjs.clickEl = function (el) {
135
- if (document.activeElement instanceof HTMLElement) {
136
- document.activeElement.blur();
137
- }
138
- const event = document.createEvent('MouseEvent');
139
- event.initEvent('click', true, true);
140
- return this.fetchElement(el).dispatchEvent(event);
141
- };
142
-
143
- /** @param {number} el */
144
- codeceptjs.doubleClickEl = function (el) {
145
- if (document.activeElement instanceof HTMLElement) {
146
- document.activeElement.blur();
147
- }
148
- const event = document.createEvent('MouseEvent');
149
- event.initEvent('dblclick', true, true);
150
- this.fetchElement(el).dispatchEvent(event);
151
- };
152
-
153
- /**
154
- * @param {number} el
155
- * @param {number | undefined} x
156
- * @param {number | undefined} y
157
- */
158
- codeceptjs.hoverEl = function (el, x, y) {
159
- if (document.activeElement instanceof HTMLElement) {
160
- document.activeElement.blur();
161
- }
162
-
163
- const event = new MouseEvent('mouseover', {
164
- bubbles: true,
165
- cancelable: true,
166
- screenX: x,
167
- screenY: y,
168
- clientX: x,
169
- clientY: y,
170
- });
171
-
172
- this.fetchElement(el).dispatchEvent(event);
173
- };
174
-
175
- /** @param {number} el */
176
- codeceptjs.rightClickEl = function (el) {
177
- const event = new MouseEvent('contextmenu', {
178
- bubbles: true,
179
- cancelable: true,
180
- view: window,
181
- buttons: 2,
182
- });
183
-
184
- this.fetchElement(el).dispatchEvent(event);
185
- };
186
-
187
- /**
188
- * @param {number} el
189
- * @return {boolean | undefined}
190
- */
191
- codeceptjs.checkEl = function (el) {
192
- const element = this.fetchElement(el);
193
- const event = document.createEvent('HTMLEvents');
194
- if (element.checked) return;
195
- element.checked = true;
196
- event.initEvent('change', true, true);
197
- return element.dispatchEvent(event);
198
- };
199
-
200
- /**
201
- * @param {number} el
202
- * @return {boolean}
203
- */
204
- codeceptjs.unCheckEl = function (el) {
205
- const element = this.fetchElement(el);
206
- const event = document.createEvent('HTMLEvents');
207
- element.checked = false;
208
- event.initEvent('change', true, true);
209
- return element.dispatchEvent(event);
210
- };
211
-
212
- window.codeceptjs = codeceptjs;
213
- }
@@ -1,43 +0,0 @@
1
- async function findReact(matcher, locator) {
2
- let _locator = `_react=${locator.react}`;
3
- let props = '';
4
-
5
- if (locator.props) {
6
- props += propBuilder(locator.props);
7
- _locator += props;
8
- }
9
- return matcher.locator(_locator).all();
10
- }
11
-
12
- async function findVue(matcher, locator) {
13
- let _locator = `_vue=${locator.vue}`;
14
- let props = '';
15
-
16
- if (locator.props) {
17
- props += propBuilder(locator.props);
18
- _locator += props;
19
- }
20
- return matcher.locator(_locator).all();
21
- }
22
-
23
- async function findByPlaywrightLocator(matcher, locator) {
24
- if (locator && locator.toString().includes(process.env.testIdAttribute)) return matcher.getByTestId(locator.pw.value.split('=')[1]);
25
- return matcher.locator(locator.pw).all();
26
- }
27
-
28
- function propBuilder(props) {
29
- let _props = '';
30
-
31
- for (const [key, value] of Object.entries(props)) {
32
- if (typeof value === 'object') {
33
- for (const [k, v] of Object.entries(value)) {
34
- _props += `[${key}.${k} = "${v}"]`;
35
- }
36
- } else {
37
- _props += `[${key} = "${value}"]`;
38
- }
39
- }
40
- return _props;
41
- }
42
-
43
- module.exports = { findReact, findVue, findByPlaywrightLocator };
@@ -1,42 +0,0 @@
1
- const testControllerHolder = {
2
-
3
- testController: undefined,
4
- captureResolver: undefined,
5
- getResolver: undefined,
6
-
7
- capture(t) {
8
- testControllerHolder.testController = t;
9
-
10
- if (testControllerHolder.getResolver) {
11
- // @ts-ignore
12
- testControllerHolder.getResolver(t);
13
- }
14
-
15
- return new Promise((resolve) => {
16
- // @ts-ignore
17
- testControllerHolder.captureResolver = resolve;
18
- });
19
- },
20
-
21
- free() {
22
- testControllerHolder.testController = undefined;
23
-
24
- if (testControllerHolder.captureResolver) {
25
- // @ts-ignore
26
- testControllerHolder.captureResolver();
27
- }
28
- },
29
-
30
- get() {
31
- return new Promise((resolve) => {
32
- if (testControllerHolder.testController) {
33
- resolve(testControllerHolder.testController);
34
- } else {
35
- // @ts-ignore
36
- testControllerHolder.getResolver = resolve;
37
- }
38
- });
39
- },
40
- };
41
-
42
- module.exports = testControllerHolder;
@@ -1,62 +0,0 @@
1
- const { ClientFunction } = require('testcafe');
2
-
3
- const assert = require('assert');
4
- const fs = require('fs');
5
- const path = require('path');
6
- const { getParamNames } = require('../../utils');
7
-
8
- const createTestFile = () => {
9
- assert(global.output_dir, 'global.output_dir must be set');
10
-
11
- const testFile = path.join(global.output_dir, `${Date.now()}_test.js`);
12
- const testControllerHolderDir = __dirname.replace(/\\/g, '/');
13
-
14
- fs.writeFileSync(
15
- testFile,
16
- `import testControllerHolder from "${testControllerHolderDir}/testControllerHolder.js";\n\n
17
- fixture("fixture")\n
18
- test\n
19
- ("test", testControllerHolder.capture)`,
20
- );
21
-
22
- return testFile;
23
- };
24
-
25
- // TODO Better error mapping (actual, expected)
26
- const mapError = (testcafeError) => {
27
- // console.log('TODO map error better', JSON.stringify(testcafeError, null, 2));
28
- if (testcafeError.errMsg) {
29
- throw new Error(testcafeError.errMsg);
30
- }
31
- const errorInfo = `${testcafeError.callsite ? JSON.stringify(testcafeError.callsite) : ''} ${testcafeError.apiFnChain || JSON.stringify(testcafeError)}`;
32
- throw new Error(`TestCafe Error: ${errorInfo}`);
33
- };
34
-
35
- function createClientFunction(func, args) {
36
- if (!args || !args.length) {
37
- return ClientFunction(func);
38
- }
39
- const paramNames = getParamNames(func);
40
- const dependencies = {};
41
- paramNames.forEach((param, i) => dependencies[param] = args[i]);
42
-
43
- return ClientFunction(getFuncBody(func), { dependencies });
44
- }
45
-
46
- function getFuncBody(func) {
47
- let fnStr = func.toString();
48
- const arrowIndex = fnStr.indexOf('=>');
49
- if (arrowIndex >= 0) {
50
- fnStr = fnStr.slice(arrowIndex + 2);
51
-
52
- // eslint-disable-next-line no-eval
53
- return eval(`() => ${fnStr}`);
54
- }
55
- // TODO: support general functions
56
- }
57
-
58
- module.exports = {
59
- createTestFile,
60
- mapError,
61
- createClientFunction,
62
- };
@@ -1,81 +0,0 @@
1
- const { CucumberExpression, ParameterTypeRegistry, ParameterType } = require('@cucumber/cucumber-expressions')
2
- const Config = require('../config')
3
-
4
- let steps = {}
5
-
6
- const STACK_POSITION = 2
7
-
8
- /**
9
- * @param {*} step
10
- * @param {*} fn
11
- */
12
- const addStep = (step, fn) => {
13
- const avoidDuplicateSteps = Config.get('gherkin', {}).avoidDuplicateSteps || false
14
- const stack = new Error().stack
15
- if (avoidDuplicateSteps && steps[step]) {
16
- throw new Error(`Step '${step}' is already defined`)
17
- }
18
- steps[step] = fn
19
- fn.line = stack && stack.split('\n')[STACK_POSITION]
20
- if (fn.line) {
21
- fn.line = fn.line
22
- .trim()
23
- .replace(/^at (.*?)\(/, '(')
24
- .replace(codecept_dir, '.')
25
- }
26
- }
27
-
28
- const parameterTypeRegistry = new ParameterTypeRegistry()
29
-
30
- const matchStep = (step) => {
31
- for (const stepName in steps) {
32
- if (stepName.indexOf('/') === 0) {
33
- const regExpArr = stepName.match(/^\/(.*?)\/([gimy]*)$/) || []
34
- const res = step.match(new RegExp(regExpArr[1], regExpArr[2]))
35
- if (res) {
36
- const fn = steps[stepName]
37
- fn.params = res.slice(1)
38
- return fn
39
- }
40
- continue
41
- }
42
- const expression = new CucumberExpression(stepName, parameterTypeRegistry)
43
- const res = expression.match(step)
44
- if (res) {
45
- const fn = steps[stepName]
46
- fn.params = res.map((arg) => arg.getValue())
47
- return fn
48
- }
49
- }
50
- throw new Error(`No steps matching "${step.toString()}"`)
51
- }
52
-
53
- const clearSteps = () => {
54
- steps = {}
55
- }
56
-
57
- const getSteps = () => {
58
- return steps
59
- }
60
-
61
- const defineParameterType = (options) => {
62
- const parameterType = buildParameterType(options)
63
- parameterTypeRegistry.defineParameterType(parameterType)
64
- }
65
-
66
- const buildParameterType = ({ name, regexp, transformer, useForSnippets, preferForRegexpMatch }) => {
67
- if (typeof useForSnippets !== 'boolean') useForSnippets = true
68
- if (typeof preferForRegexpMatch !== 'boolean') preferForRegexpMatch = false
69
- return new ParameterType(name, regexp, null, transformer, useForSnippets, preferForRegexpMatch)
70
- }
71
-
72
- module.exports = {
73
- Given: addStep,
74
- When: addStep,
75
- Then: addStep,
76
- And: addStep,
77
- matchStep,
78
- getSteps,
79
- clearSteps,
80
- defineParameterType,
81
- }
@@ -1,19 +0,0 @@
1
- const event = require('../event')
2
- const recorder = require('../recorder')
3
-
4
- /**
5
- * Create and clean up empty artifacts
6
- */
7
- module.exports = function () {
8
- event.dispatcher.on(event.test.before, (test) => {
9
- test.artifacts = {}
10
- })
11
-
12
- event.dispatcher.on(event.test.after, (test) => {
13
- recorder.add('clean up empty artifacts', () => {
14
- for (const key in test.artifacts || {}) {
15
- if (!test.artifacts[key]) delete test.artifacts[key]
16
- }
17
- })
18
- })
19
- }
@@ -1,109 +0,0 @@
1
- const event = require('../event')
2
- const output = require('../output')
3
- const recorder = require('../recorder')
4
- const Config = require('../config')
5
- const { timeouts } = require('../store')
6
- const TIMEOUT_ORDER = require('../step').TIMEOUT_ORDER
7
-
8
- module.exports = function () {
9
- let timeout
10
- let suiteTimeout = []
11
- let currentTest
12
- let currentTimeout
13
-
14
- if (!timeouts) {
15
- console.log('Timeouts were disabled')
16
- return
17
- }
18
-
19
- event.dispatcher.on(event.suite.before, (suite) => {
20
- suiteTimeout = []
21
- let timeoutConfig = Config.get('timeout')
22
-
23
- if (timeoutConfig) {
24
- if (!Number.isNaN(+timeoutConfig)) {
25
- checkForSeconds(timeoutConfig)
26
- suiteTimeout.push(timeoutConfig)
27
- }
28
-
29
- if (!Array.isArray(timeoutConfig)) {
30
- timeoutConfig = [timeoutConfig]
31
- }
32
-
33
- for (const config of timeoutConfig.filter((c) => !!c.Feature)) {
34
- if (config.grep) {
35
- if (!suite.title.includes(config.grep)) continue
36
- }
37
- suiteTimeout.push(config.Feature)
38
- }
39
- }
40
-
41
- if (suite.totalTimeout) suiteTimeout.push(suite.totalTimeout)
42
- output.log(`Timeouts: ${suiteTimeout}`)
43
- })
44
-
45
- event.dispatcher.on(event.test.before, (test) => {
46
- currentTest = test
47
- let testTimeout = null
48
-
49
- let timeoutConfig = Config.get('timeout')
50
-
51
- if (typeof timeoutConfig === 'object' || Array.isArray(timeoutConfig)) {
52
- if (!Array.isArray(timeoutConfig)) {
53
- timeoutConfig = [timeoutConfig]
54
- }
55
-
56
- for (const config of timeoutConfig.filter((c) => !!c.Scenario)) {
57
- console.log('Test Timeout', config, test.title.includes(config.grep))
58
- if (config.grep) {
59
- if (!test.title.includes(config.grep)) continue
60
- }
61
- testTimeout = config.Scenario
62
- }
63
- }
64
-
65
- timeout = test.totalTimeout || testTimeout || suiteTimeout[suiteTimeout.length - 1]
66
- if (!timeout) return
67
- currentTimeout = timeout
68
- output.debug(`Test Timeout: ${timeout}s`)
69
- timeout *= 1000
70
- })
71
-
72
- event.dispatcher.on(event.test.passed, (test) => {
73
- currentTest = null
74
- })
75
-
76
- event.dispatcher.on(event.test.failed, (test) => {
77
- currentTest = null
78
- })
79
-
80
- event.dispatcher.on(event.step.before, (step) => {
81
- if (typeof timeout !== 'number') return
82
-
83
- if (timeout < 0) {
84
- step.setTimeout(0.01, TIMEOUT_ORDER.testOrSuite)
85
- } else {
86
- step.setTimeout(timeout, TIMEOUT_ORDER.testOrSuite)
87
- }
88
- })
89
-
90
- event.dispatcher.on(event.step.finished, (step) => {
91
- if (typeof timeout === 'number' && !Number.isNaN(timeout)) timeout -= step.duration
92
-
93
- if (typeof timeout === 'number' && timeout <= 0 && recorder.isRunning()) {
94
- if (currentTest && currentTest.callback) {
95
- recorder.reset()
96
- // replace mocha timeout with custom timeout
97
- currentTest.timeout(0)
98
- currentTest.callback(new Error(`Timeout ${currentTimeout}s exceeded (with Before hook)`))
99
- currentTest.timedOut = true
100
- }
101
- }
102
- })
103
- }
104
-
105
- function checkForSeconds(timeout) {
106
- if (timeout >= 1000) {
107
- console.log(`Warning: Timeout was set to ${timeout}secs.\nGlobal timeout should be specified in seconds.`)
108
- }
109
- }
@@ -1,113 +0,0 @@
1
- const Mocha = require('mocha');
2
- const fsPath = require('path');
3
- const fs = require('fs');
4
- const reporter = require('./cli');
5
- const gherkinParser = require('./interfaces/gherkin');
6
- const output = require('./output');
7
- const { genTestId } = require('./utils');
8
- const ConnectionRefused = require('./helper/errors/ConnectionRefused');
9
-
10
- const scenarioUi = fsPath.join(__dirname, './ui.js');
11
-
12
- let mocha;
13
-
14
- class MochaFactory {
15
- static create(config, opts) {
16
- mocha = new Mocha(Object.assign(config, opts));
17
- output.process(opts.child);
18
- mocha.ui(scenarioUi);
19
-
20
- Mocha.Runner.prototype.uncaught = function (err) {
21
- if (err) {
22
- if (err.toString().indexOf('ECONNREFUSED') >= 0) {
23
- err = new ConnectionRefused(err);
24
- }
25
- output.error(err);
26
- output.print(err.stack);
27
- process.exit(1);
28
- }
29
- output.error('Uncaught undefined exception');
30
- process.exit(1);
31
- };
32
-
33
- mocha.loadFiles = (fn) => {
34
- // load features
35
- if (mocha.suite.suites.length === 0) {
36
- mocha.files
37
- .filter(file => file.match(/\.feature$/))
38
- .forEach(file => mocha.suite.addSuite(gherkinParser(fs.readFileSync(file, 'utf8'), file)));
39
-
40
- // remove feature files
41
- mocha.files = mocha.files.filter(file => !file.match(/\.feature$/));
42
-
43
- Mocha.prototype.loadFiles.call(mocha, fn);
44
-
45
- // add ids for each test and check uniqueness
46
- const dupes = [];
47
- let missingFeatureInFile = [];
48
- const seenTests = [];
49
- mocha.suite.eachTest(test => {
50
- test.uid = genTestId(test);
51
-
52
- const name = test.fullTitle();
53
- if (seenTests.includes(test.uid)) {
54
- dupes.push(name);
55
- }
56
- seenTests.push(test.uid);
57
-
58
- if (name.slice(0, name.indexOf(':')) === '') {
59
- missingFeatureInFile.push(test.file);
60
- }
61
- });
62
- if (dupes.length) {
63
- // ideally this should be no-op and throw (breaking change)...
64
- output.error(`Duplicate test names detected - Feature + Scenario name should be unique:\n${dupes.join('\n')}`);
65
- }
66
-
67
- if (missingFeatureInFile.length) {
68
- missingFeatureInFile = [...new Set(missingFeatureInFile)];
69
- output.error(`Missing Feature section in:\n${missingFeatureInFile.join('\n')}`);
70
- }
71
- }
72
- };
73
-
74
- const presetReporter = opts.reporter || config.reporter;
75
- // use standard reporter
76
- if (!presetReporter) {
77
- mocha.reporter(reporter, opts);
78
- return mocha;
79
- }
80
-
81
- // load custom reporter with options
82
- const reporterOptions = Object.assign(config.reporterOptions || {});
83
-
84
- if (opts.reporterOptions !== undefined) {
85
- opts.reporterOptions.split(',').forEach((opt) => {
86
- const L = opt.split('=');
87
- if (L.length > 2 || L.length === 0) {
88
- throw new Error(`invalid reporter option '${opt}'`);
89
- } else if (L.length === 2) {
90
- reporterOptions[L[0]] = L[1];
91
- } else {
92
- reporterOptions[L[0]] = true;
93
- }
94
- });
95
- }
96
-
97
- const attributes = Object.getOwnPropertyDescriptor(reporterOptions, 'codeceptjs-cli-reporter');
98
- if (reporterOptions['codeceptjs-cli-reporter'] && attributes) {
99
- Object.defineProperty(
100
- reporterOptions,
101
- 'codeceptjs/lib/cli',
102
- attributes,
103
- );
104
- delete reporterOptions['codeceptjs-cli-reporter'];
105
- }
106
-
107
- // custom reporters
108
- mocha.reporter(presetReporter, reporterOptions);
109
- return mocha;
110
- }
111
- }
112
-
113
- module.exports = MochaFactory;
@@ -1,15 +0,0 @@
1
- module.exports = () => {
2
- console.log('Allure plugin was moved to @codeceptjs/allure-legacy. Please install it and update your config')
3
- console.log()
4
- console.log('npm install @codeceptjs/allure-legacy --save-dev')
5
- console.log()
6
- console.log('Then update your config to use it:')
7
- console.log()
8
- console.log('plugins: {')
9
- console.log(' allure: {')
10
- console.log(' enabled: true,')
11
- console.log(" require: '@codeceptjs/allure-legacy',")
12
- console.log(' }')
13
- console.log('}')
14
- console.log()
15
- }