codeceptjs 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/docs/build/Appium.js +1 -1
- package/docs/build/Nightmare.js +4 -5
- package/docs/build/Playwright.js +41 -15
- package/docs/build/Protractor.js +1 -1
- package/docs/build/Puppeteer.js +1 -1
- package/docs/build/REST.js +20 -1
- package/docs/build/TestCafe.js +1 -1
- package/docs/build/WebDriver.js +3 -3
- package/docs/changelog.md +34 -0
- package/docs/data.md +5 -5
- package/docs/detox.md +2 -2
- package/docs/docker.md +11 -11
- package/docs/helpers/Appium.md +1 -1
- package/docs/helpers/Nightmare.md +4 -5
- package/docs/helpers/Playwright.md +81 -61
- package/docs/helpers/Protractor.md +1 -1
- package/docs/helpers/Puppeteer.md +1 -1
- package/docs/helpers/REST.md +9 -0
- package/docs/helpers/TestCafe.md +1 -1
- package/docs/helpers/WebDriver.md +1 -1
- package/docs/locators.md +2 -2
- package/docs/mobile-react-native-locators.md +2 -2
- package/docs/mobile.md +3 -3
- package/docs/pageobjects.md +3 -1
- package/docs/reports.md +3 -3
- package/docs/typescript.md +47 -5
- package/docs/webapi/fillField.mustache +1 -1
- package/lib/cli.js +16 -10
- package/lib/command/interactive.js +6 -7
- package/lib/config.js +6 -1
- package/lib/helper/Nightmare.js +1 -1
- package/lib/helper/Playwright.js +8 -16
- package/lib/helper/REST.js +20 -1
- package/lib/helper/WebDriver.js +2 -2
- package/lib/interfaces/gherkin.js +9 -3
- package/lib/output.js +2 -2
- package/lib/plugin/allure.js +3 -7
- package/lib/plugin/screenshotOnFail.js +1 -2
- package/lib/step.js +2 -1
- package/lib/within.js +1 -1
- package/lib/workers.js +13 -1
- package/package.json +5 -5
- package/typings/index.d.ts +7 -2
- package/typings/types.d.ts +55 -21
package/docs/typescript.md
CHANGED
|
@@ -19,10 +19,10 @@ Example:
|
|
|
19
19
|
|
|
20
20
|

|
|
21
21
|
|
|
22
|
-
- Checks types - thanks to TypeScript support in CodeceptJS now allow to tests your tests. TypeScript can prevent some errors:
|
|
22
|
+
- Checks types - thanks to TypeScript support in CodeceptJS now allow to tests your tests. TypeScript can prevent some errors:
|
|
23
23
|
- invalid type of variables passed to function;
|
|
24
24
|
- calls no-exist method from PageObject or `I` object;
|
|
25
|
-
- incorrectly used CodeceptJS features;
|
|
25
|
+
- incorrectly used CodeceptJS features;
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
## Getting Started
|
|
@@ -106,7 +106,7 @@ declare namespace CodeceptJS {
|
|
|
106
106
|
|
|
107
107
|
## Types for custom helper or page object
|
|
108
108
|
|
|
109
|
-
If you want to get types for your [custom helper](https://codecept.io/helpers/#configuration), you can add their automatically with CodeceptJS command `npx codeceptjs def`.
|
|
109
|
+
If you want to get types for your [custom helper](https://codecept.io/helpers/#configuration), you can add their automatically with CodeceptJS command `npx codeceptjs def`.
|
|
110
110
|
|
|
111
111
|
For example, if you add the new step `printMessage` for your custom helper like this:
|
|
112
112
|
```js
|
|
@@ -121,9 +121,9 @@ export = CustomHelper
|
|
|
121
121
|
```
|
|
122
122
|
|
|
123
123
|
Then you need to add this helper to your `codecept.conf.js` like in this [docs](https://codecept.io/helpers/#configuration).
|
|
124
|
-
And then run the command `npx codeceptjs def`.
|
|
124
|
+
And then run the command `npx codeceptjs def`.
|
|
125
125
|
|
|
126
|
-
As result our `steps.d.ts` file will be updated like this:
|
|
126
|
+
As result our `steps.d.ts` file will be updated like this:
|
|
127
127
|
```ts
|
|
128
128
|
/// <reference types='codeceptjs' />
|
|
129
129
|
type CustomHelper = import('./CustomHelper');
|
|
@@ -156,3 +156,45 @@ declare namespace CodeceptJS {
|
|
|
156
156
|
}
|
|
157
157
|
}
|
|
158
158
|
```
|
|
159
|
+
|
|
160
|
+
## Types for custom strict locators
|
|
161
|
+
|
|
162
|
+
You can define [custom strict locators](https://codecept.io/locators/#custom-strict-locators) that can be used in all methods taking a locator (parameter type `LocatorOrString`).
|
|
163
|
+
|
|
164
|
+
Example: A custom strict locator with a `data` property, which can be used like this:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
I.click({ data: 'user-login' });
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
In order to use the custom locator in TypeScript code, its type shape needs to be registered in the interface `CustomLocators` in your `steps.d.ts` file:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
/// <reference types='codeceptjs' />
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
declare namespace CodeceptJS {
|
|
177
|
+
...
|
|
178
|
+
|
|
179
|
+
interface CustomLocators {
|
|
180
|
+
data: { data: string };
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The property keys used in the `CustomLocators` interface do not matter (only the *types* of the interface properties are used). For simplicity it is recommended to use the name that is also used in your custom locator itself.
|
|
186
|
+
|
|
187
|
+
You can also define more complicated custom locators with multiple (also optional) properties:
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
/// <reference types='codeceptjs' />
|
|
191
|
+
...
|
|
192
|
+
|
|
193
|
+
declare namespace CodeceptJS {
|
|
194
|
+
...
|
|
195
|
+
|
|
196
|
+
interface CustomLocators {
|
|
197
|
+
data: { data: string, value?: number, flag?: boolean };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
@@ -12,4 +12,4 @@ I.fillField('form#login input[name=username]', 'John');
|
|
|
12
12
|
I.fillField({css: 'form#login input[name=username]'}, 'John');
|
|
13
13
|
```
|
|
14
14
|
@param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
|
|
15
|
-
@param {
|
|
15
|
+
@param {CodeceptJS.StringOrSecret} value text value to fill.
|
package/lib/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ const ms = require('ms');
|
|
|
3
3
|
const event = require('./event');
|
|
4
4
|
const AssertionFailedError = require('./assert/error');
|
|
5
5
|
const output = require('./output');
|
|
6
|
+
const { MetaStep } = require('./step');
|
|
6
7
|
|
|
7
8
|
const cursor = Base.cursor;
|
|
8
9
|
let currentMetaStep = [];
|
|
@@ -77,17 +78,22 @@ class Cli extends Base {
|
|
|
77
78
|
});
|
|
78
79
|
|
|
79
80
|
event.dispatcher.on(event.step.started, (step) => {
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
81
|
+
let processingStep = step;
|
|
82
|
+
const metaSteps = [];
|
|
83
|
+
while (processingStep.metaStep) {
|
|
84
|
+
metaSteps.unshift(processingStep.metaStep);
|
|
85
|
+
processingStep = processingStep.metaStep;
|
|
86
|
+
}
|
|
87
|
+
const shift = metaSteps.length;
|
|
88
|
+
|
|
89
|
+
for (let i = 0; i < Math.max(currentMetaStep.length, metaSteps.length); i++) {
|
|
90
|
+
if (currentMetaStep[i] !== metaSteps[i]) {
|
|
91
|
+
output.stepShift = 3 + 2 * i;
|
|
92
|
+
if (metaSteps[i]) output.step(metaSteps[i]);
|
|
86
93
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
printMetaStep(step.metaStep);
|
|
94
|
+
}
|
|
95
|
+
currentMetaStep = metaSteps;
|
|
96
|
+
output.stepShift = 3 + 2 * shift;
|
|
91
97
|
output.step(step);
|
|
92
98
|
});
|
|
93
99
|
|
|
@@ -4,7 +4,7 @@ const Codecept = require('../codecept');
|
|
|
4
4
|
const event = require('../event');
|
|
5
5
|
const output = require('../output');
|
|
6
6
|
|
|
7
|
-
module.exports = function (path, options) {
|
|
7
|
+
module.exports = async function (path, options) {
|
|
8
8
|
// Backward compatibility for --profile
|
|
9
9
|
process.profile = options.profile;
|
|
10
10
|
process.env.profile = options.profile;
|
|
@@ -14,11 +14,8 @@ module.exports = function (path, options) {
|
|
|
14
14
|
const codecept = new Codecept(config, options);
|
|
15
15
|
codecept.init(testsPath);
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
output.error(`Error while running bootstrap file :${err}`);
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
17
|
+
try {
|
|
18
|
+
await codecept.bootstrap();
|
|
22
19
|
|
|
23
20
|
if (options.verbose) output.level(3);
|
|
24
21
|
|
|
@@ -36,5 +33,7 @@ module.exports = function (path, options) {
|
|
|
36
33
|
recorder.add(() => event.emit(event.suite.after, {}));
|
|
37
34
|
recorder.add(() => event.emit(event.all.result, {}));
|
|
38
35
|
recorder.add(() => codecept.teardown());
|
|
39
|
-
})
|
|
36
|
+
} catch (err) {
|
|
37
|
+
output.error(`Error while running bootstrap file :${err}`);
|
|
38
|
+
}
|
|
40
39
|
};
|
package/lib/config.js
CHANGED
|
@@ -77,7 +77,12 @@ class Config {
|
|
|
77
77
|
return loadConfigFile(jsonConfig);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
const tsConfig = path.join(configFile, 'codecept.conf.ts');
|
|
81
|
+
if (isFile(tsConfig)) {
|
|
82
|
+
return loadConfigFile(tsConfig);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
throw new Error(`Can not load config from ${jsConfig} or ${jsonConfig} or ${tsConfig}\nCodeceptJS is not initialized in this dir. Execute 'codeceptjs init' to start`);
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
/**
|
package/lib/helper/Nightmare.js
CHANGED
package/lib/helper/Playwright.js
CHANGED
|
@@ -800,11 +800,7 @@ class Playwright extends Helper {
|
|
|
800
800
|
}
|
|
801
801
|
|
|
802
802
|
/**
|
|
803
|
-
*
|
|
804
|
-
*
|
|
805
|
-
* ```js
|
|
806
|
-
* I.seeTitleEquals('Test title.');
|
|
807
|
-
* ```
|
|
803
|
+
* {{> seeTitleEquals }}
|
|
808
804
|
*/
|
|
809
805
|
async seeTitleEquals(text) {
|
|
810
806
|
const title = await this.page.title();
|
|
@@ -1069,14 +1065,7 @@ class Playwright extends Helper {
|
|
|
1069
1065
|
}
|
|
1070
1066
|
|
|
1071
1067
|
/**
|
|
1072
|
-
*
|
|
1073
|
-
* Force clicks an element without waiting for it to become visible and not animating.
|
|
1074
|
-
*
|
|
1075
|
-
* ```js
|
|
1076
|
-
* I.forceClick('#hiddenButton');
|
|
1077
|
-
* I.forceClick('Click me', '#hidden');
|
|
1078
|
-
* ```
|
|
1079
|
-
*
|
|
1068
|
+
* {{> forceClick }}
|
|
1080
1069
|
*/
|
|
1081
1070
|
async forceClick(locator, context = null) {
|
|
1082
1071
|
return proceedClick.call(this, locator, context, { force: true });
|
|
@@ -1500,6 +1489,10 @@ class Playwright extends Helper {
|
|
|
1500
1489
|
* I.executeScript(([x, y]) => x + y, [x, y]);
|
|
1501
1490
|
* ```
|
|
1502
1491
|
* If a function returns a Promise it will wait for its resolution.
|
|
1492
|
+
*
|
|
1493
|
+
* @param {string|function} fn function to be executed in browser context.
|
|
1494
|
+
* @param {any} [arg] optional argument to pass to the function
|
|
1495
|
+
* @return {Promise<any>}
|
|
1503
1496
|
*/
|
|
1504
1497
|
async executeScript(fn, arg) {
|
|
1505
1498
|
let context = this.page;
|
|
@@ -1590,8 +1583,7 @@ class Playwright extends Helper {
|
|
|
1590
1583
|
async grabCssPropertyFromAll(locator, cssProperty) {
|
|
1591
1584
|
const els = await this._locate(locator);
|
|
1592
1585
|
this.debug(`Matched ${els.length} elements`);
|
|
1593
|
-
const
|
|
1594
|
-
const cssValues = res.map(props => props[toCamelCase(cssProperty)]);
|
|
1586
|
+
const cssValues = await Promise.all(els.map(el => el.$eval('xpath=.', (el, cssProperty) => getComputedStyle(el).getPropertyValue(cssProperty), cssProperty)));
|
|
1595
1587
|
|
|
1596
1588
|
return cssValues;
|
|
1597
1589
|
}
|
|
@@ -2083,7 +2075,7 @@ class Playwright extends Helper {
|
|
|
2083
2075
|
/**
|
|
2084
2076
|
* Waits for navigation to finish. By default takes configured `waitForNavigation` option.
|
|
2085
2077
|
*
|
|
2086
|
-
* See [
|
|
2078
|
+
* See [Playwright's reference](https://playwright.dev/docs/api/class-page?_highlight=waitfornavi#pagewaitfornavigationoptions)
|
|
2087
2079
|
*
|
|
2088
2080
|
* @param {*} opts
|
|
2089
2081
|
*/
|
package/lib/helper/REST.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const axios = require('axios').default;
|
|
2
|
+
const Secret = require('../secret');
|
|
2
3
|
|
|
3
4
|
const Helper = require('../helper');
|
|
4
5
|
|
|
@@ -75,12 +76,18 @@ class REST extends Helper {
|
|
|
75
76
|
* @param {*} request
|
|
76
77
|
*/
|
|
77
78
|
async _executeRequest(request) {
|
|
79
|
+
const _debugRequest = { ...request };
|
|
78
80
|
axios.defaults.timeout = request.timeout || this.options.timeout;
|
|
79
81
|
|
|
80
82
|
if (this.headers && this.headers.auth) {
|
|
81
83
|
request.auth = this.headers.auth;
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
if (request.data instanceof Secret) {
|
|
87
|
+
_debugRequest.data = '*****';
|
|
88
|
+
request.data = typeof request.data === 'object' ? { ...request.data.toString() } : request.data.toString();
|
|
89
|
+
}
|
|
90
|
+
|
|
84
91
|
if ((typeof request.data) === 'string') {
|
|
85
92
|
if (!request.headers || !request.headers['Content-Type']) {
|
|
86
93
|
request.headers = { ...request.headers, ...{ 'Content-Type': 'application/x-www-form-urlencoded' } };
|
|
@@ -91,7 +98,7 @@ class REST extends Helper {
|
|
|
91
98
|
await this.config.onRequest(request);
|
|
92
99
|
}
|
|
93
100
|
|
|
94
|
-
this.debugSection('Request', JSON.stringify(
|
|
101
|
+
this.debugSection('Request', JSON.stringify(_debugRequest));
|
|
95
102
|
|
|
96
103
|
let response;
|
|
97
104
|
try {
|
|
@@ -149,6 +156,10 @@ class REST extends Helper {
|
|
|
149
156
|
*
|
|
150
157
|
* ```js
|
|
151
158
|
* I.sendPostRequest('/api/users.json', { "email": "user@user.com" });
|
|
159
|
+
*
|
|
160
|
+
* // To mask the payload in logs
|
|
161
|
+
* I.sendPostRequest('/api/users.json', secret({ "email": "user@user.com" }));
|
|
162
|
+
*
|
|
152
163
|
* ```
|
|
153
164
|
*
|
|
154
165
|
* @param {*} url
|
|
@@ -176,6 +187,10 @@ class REST extends Helper {
|
|
|
176
187
|
*
|
|
177
188
|
* ```js
|
|
178
189
|
* I.sendPatchRequest('/api/users.json', { "email": "user@user.com" });
|
|
190
|
+
*
|
|
191
|
+
* // To mask the payload in logs
|
|
192
|
+
* I.sendPatchRequest('/api/users.json', secret({ "email": "user@user.com" }));
|
|
193
|
+
*
|
|
179
194
|
* ```
|
|
180
195
|
*
|
|
181
196
|
* @param {string} url
|
|
@@ -203,6 +218,10 @@ class REST extends Helper {
|
|
|
203
218
|
*
|
|
204
219
|
* ```js
|
|
205
220
|
* I.sendPutRequest('/api/users.json', { "email": "user@user.com" });
|
|
221
|
+
*
|
|
222
|
+
* // To mask the payload in logs
|
|
223
|
+
* I.sendPutRequest('/api/users.json', secret({ "email": "user@user.com" }));
|
|
224
|
+
*
|
|
206
225
|
* ```
|
|
207
226
|
*
|
|
208
227
|
* @param {string} url
|
package/lib/helper/WebDriver.js
CHANGED
|
@@ -718,7 +718,7 @@ class WebDriver extends Helper {
|
|
|
718
718
|
* @param {object} locator
|
|
719
719
|
*/
|
|
720
720
|
async _smartWait(locator) {
|
|
721
|
-
this.debugSection(`SmartWait (${this.options.smartWait}ms)`, `Locating ${locator} in ${this.options.smartWait}`);
|
|
721
|
+
this.debugSection(`SmartWait (${this.options.smartWait}ms)`, `Locating ${JSON.stringify(locator)} in ${this.options.smartWait}`);
|
|
722
722
|
await this.defineTimeout({ implicit: this.options.smartWait });
|
|
723
723
|
}
|
|
724
724
|
|
|
@@ -1370,7 +1370,7 @@ class WebDriver extends Helper {
|
|
|
1370
1370
|
*/
|
|
1371
1371
|
async grabBrowserLogs() {
|
|
1372
1372
|
if (this.browser.isW3C) {
|
|
1373
|
-
this.debug('Logs not
|
|
1373
|
+
this.debug('Logs not available in W3C specification');
|
|
1374
1374
|
return;
|
|
1375
1375
|
}
|
|
1376
1376
|
return this.browser.getLogs('browser');
|
|
@@ -31,7 +31,13 @@ module.exports = (text) => {
|
|
|
31
31
|
const metaStep = new Step.MetaStep(null, step.text);
|
|
32
32
|
metaStep.actor = step.keyword.trim();
|
|
33
33
|
const setMetaStep = (step) => {
|
|
34
|
-
if (step.metaStep)
|
|
34
|
+
if (step.metaStep) {
|
|
35
|
+
if (step.metaStep === metaStep) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
setMetaStep(step.metaStep);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
35
41
|
step.metaStep = metaStep;
|
|
36
42
|
};
|
|
37
43
|
const fn = matchStep(step.text);
|
|
@@ -46,14 +52,14 @@ module.exports = (text) => {
|
|
|
46
52
|
step.startTime = Date.now();
|
|
47
53
|
step.match = fn.line;
|
|
48
54
|
event.emit(event.bddStep.before, step);
|
|
49
|
-
event.dispatcher.
|
|
55
|
+
event.dispatcher.prependListener(event.step.before, setMetaStep);
|
|
50
56
|
try {
|
|
51
57
|
await fn(...fn.params);
|
|
52
58
|
step.status = 'passed';
|
|
53
59
|
} catch (err) {
|
|
54
60
|
step.status = 'failed';
|
|
55
61
|
step.err = err;
|
|
56
|
-
|
|
62
|
+
throw err;
|
|
57
63
|
} finally {
|
|
58
64
|
step.endTime = Date.now();
|
|
59
65
|
event.dispatcher.removeListener(event.step.before, setMetaStep);
|
package/lib/output.js
CHANGED
|
@@ -102,14 +102,14 @@ module.exports = {
|
|
|
102
102
|
if (!step) return;
|
|
103
103
|
// Avoid to print non-gherkin steps, when gherkin is running for --steps mode
|
|
104
104
|
if (outputLevel === 1) {
|
|
105
|
-
if (
|
|
105
|
+
if (step.hasBDDAncestor()) {
|
|
106
106
|
return;
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
let stepLine = step.toString();
|
|
111
111
|
if (step.metaStep && outputLevel >= 1) {
|
|
112
|
-
this.stepShift += 2;
|
|
112
|
+
// this.stepShift += 2;
|
|
113
113
|
stepLine = colors.green(truncate(stepLine, this.spaceShift));
|
|
114
114
|
}
|
|
115
115
|
if (step.comment) {
|
package/lib/plugin/allure.js
CHANGED
|
@@ -261,13 +261,9 @@ module.exports = (config) => {
|
|
|
261
261
|
if (isHookSteps === false) {
|
|
262
262
|
startMetaStep(step.metaStep);
|
|
263
263
|
if (currentStep !== step) {
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
|
|
267
|
-
// generate the report
|
|
268
|
-
if (step.actor.includes('\u001b[36m')) {
|
|
269
|
-
step.actor = step.actor.replace('\u001b[36m', '').replace('\u001b[39m', '');
|
|
270
|
-
}
|
|
264
|
+
// In multi-session scenarios, actors' names will be highlighted with ANSI
|
|
265
|
+
// escape sequences which are invalid XML values
|
|
266
|
+
step.actor = step.actor.replace(ansiRegExp(), '');
|
|
271
267
|
reporter.startStep(step.toString());
|
|
272
268
|
currentStep = step;
|
|
273
269
|
}
|
|
@@ -99,8 +99,7 @@ module.exports = function (config) {
|
|
|
99
99
|
await helper.saveScreenshot(fileName, options.fullPageScreenshots);
|
|
100
100
|
|
|
101
101
|
test.artifacts.screenshot = path.join(global.output_dir, fileName);
|
|
102
|
-
|
|
103
|
-
if (Container.mocha().options.reporterOptions['mocha-junit-reporter'] && Container.mocha().options.reporterOptions['mocha-junit-reporter'].attachments) {
|
|
102
|
+
if (Container.mocha().options.reporterOptions['mocha-junit-reporter'] && Container.mocha().options.reporterOptions['mocha-junit-reporter'].options.attachments) {
|
|
104
103
|
test.attachments = [path.join(global.output_dir, fileName)];
|
|
105
104
|
}
|
|
106
105
|
|
package/lib/step.js
CHANGED
|
@@ -208,9 +208,10 @@ class MetaStep extends Step {
|
|
|
208
208
|
let result;
|
|
209
209
|
|
|
210
210
|
const registerStep = (step) => {
|
|
211
|
+
this.metaStep = null;
|
|
211
212
|
step.metaStep = this;
|
|
212
213
|
};
|
|
213
|
-
event.dispatcher.
|
|
214
|
+
event.dispatcher.prependListener(event.step.before, registerStep);
|
|
214
215
|
try {
|
|
215
216
|
this.startTime = Date.now();
|
|
216
217
|
result = fn.apply(this.context, this.args);
|
package/lib/within.js
CHANGED
|
@@ -20,7 +20,7 @@ function within(context, fn) {
|
|
|
20
20
|
const defineMetaStep = step => step.metaStep = metaStep;
|
|
21
21
|
recorder.session.start('within');
|
|
22
22
|
|
|
23
|
-
event.dispatcher.
|
|
23
|
+
event.dispatcher.prependListener(event.step.before, defineMetaStep);
|
|
24
24
|
|
|
25
25
|
Object.keys(helpers).forEach((helper) => {
|
|
26
26
|
if (helpers[helper]._withinBegin) recorder.add(`[${helper}] start within`, () => helpers[helper]._withinBegin(context));
|
package/lib/workers.js
CHANGED
|
@@ -318,11 +318,21 @@ class Workers extends EventEmitter {
|
|
|
318
318
|
_listenWorkerEvents(worker) {
|
|
319
319
|
worker.on('message', (message) => {
|
|
320
320
|
output.process(message.workerIndex);
|
|
321
|
+
|
|
321
322
|
switch (message.event) {
|
|
323
|
+
case event.suite.before:
|
|
324
|
+
this.emit(event.suite.before, repackTest(message.data));
|
|
325
|
+
break;
|
|
322
326
|
case event.hook.failed:
|
|
323
327
|
this.emit(event.hook.failed, repackTest(message.data));
|
|
324
328
|
this.errors.push(message.data.err);
|
|
325
329
|
break;
|
|
330
|
+
case event.test.before:
|
|
331
|
+
this.emit(event.test.before, repackTest(message.data));
|
|
332
|
+
break;
|
|
333
|
+
case event.test.started:
|
|
334
|
+
this.emit(event.test.started, repackTest(message.data));
|
|
335
|
+
break;
|
|
326
336
|
case event.test.failed:
|
|
327
337
|
this._updateFinishedTests(repackTest(message.data));
|
|
328
338
|
this.emit(event.test.failed, repackTest(message.data));
|
|
@@ -335,7 +345,9 @@ class Workers extends EventEmitter {
|
|
|
335
345
|
this._updateFinishedTests(repackTest(message.data));
|
|
336
346
|
this.emit(event.test.skipped, repackTest(message.data));
|
|
337
347
|
break;
|
|
338
|
-
case event.test.finished:
|
|
348
|
+
case event.test.finished:
|
|
349
|
+
this.emit(event.test.finished, repackTest(message.data));
|
|
350
|
+
break;
|
|
339
351
|
case event.test.after:
|
|
340
352
|
this.emit(event.test.after, repackTest(message.data));
|
|
341
353
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"acceptance",
|
|
@@ -55,11 +55,11 @@
|
|
|
55
55
|
},
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@codeceptjs/configure": "^0.6.2",
|
|
58
|
-
"@codeceptjs/helper": "^1.0.
|
|
58
|
+
"@codeceptjs/helper": "^1.0.2",
|
|
59
59
|
"acorn": "^7.4.1",
|
|
60
60
|
"allure-js-commons": "^1.3.2",
|
|
61
61
|
"arrify": "^2.0.1",
|
|
62
|
-
"axios": "^0.
|
|
62
|
+
"axios": "^0.21.1",
|
|
63
63
|
"chalk": "^4.1.0",
|
|
64
64
|
"commander": "^2.20.3",
|
|
65
65
|
"cross-spawn": "^7.0.3",
|
|
@@ -90,8 +90,8 @@
|
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@codeceptjs/detox-helper": "^1.0.2",
|
|
92
92
|
"@codeceptjs/mock-request": "^0.3.0",
|
|
93
|
-
"@pollyjs/adapter-puppeteer": "^
|
|
94
|
-
"@pollyjs/core": "^
|
|
93
|
+
"@pollyjs/adapter-puppeteer": "^5.1.0",
|
|
94
|
+
"@pollyjs/core": "^5.1.0",
|
|
95
95
|
"@types/inquirer": "^0.0.35",
|
|
96
96
|
"@types/node": "^8.10.66",
|
|
97
97
|
"@wdio/sauce-service": "^5.22.5",
|
package/typings/index.d.ts
CHANGED
|
@@ -22,7 +22,9 @@ declare namespace CodeceptJS {
|
|
|
22
22
|
interface I {}
|
|
23
23
|
interface IHook {}
|
|
24
24
|
interface IScenario {}
|
|
25
|
-
interface IFeature {
|
|
25
|
+
interface IFeature {
|
|
26
|
+
(title: string): FeatureConfig
|
|
27
|
+
}
|
|
26
28
|
interface CallbackOrder extends Array<any> {}
|
|
27
29
|
interface SupportObject {
|
|
28
30
|
I: CodeceptJS.I;
|
|
@@ -52,7 +54,10 @@ declare namespace CodeceptJS {
|
|
|
52
54
|
| { android: string, ios: string }
|
|
53
55
|
| { react: string };
|
|
54
56
|
|
|
55
|
-
|
|
57
|
+
interface CustomLocators { }
|
|
58
|
+
type LocatorOrString = string | ILocator | Locator | CustomLocators[keyof CustomLocators];
|
|
59
|
+
|
|
60
|
+
type StringOrSecret = string | CodeceptJS.Secret;
|
|
56
61
|
|
|
57
62
|
interface HookCallback { (args: SupportObject): void; }
|
|
58
63
|
interface Scenario extends IScenario { only: IScenario, skip: IScenario, todo: IScenario}
|