codeceptjs 3.0.6 → 3.1.2
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 +92 -8
- package/README.md +9 -1
- package/bin/codecept.js +28 -17
- package/docs/build/Appium.js +69 -0
- package/docs/build/GraphQL.js +9 -10
- package/docs/build/Playwright.js +271 -63
- package/docs/build/Protractor.js +2 -0
- package/docs/build/Puppeteer.js +56 -18
- package/docs/build/REST.js +16 -3
- package/docs/build/WebDriver.js +82 -16
- package/docs/changelog.md +93 -9
- package/docs/configuration.md +15 -2
- package/docs/email.md +8 -8
- package/docs/examples.md +3 -3
- package/docs/helpers/Appium.md +66 -68
- package/docs/helpers/MockRequest.md +3 -3
- package/docs/helpers/Playwright.md +269 -203
- package/docs/helpers/Puppeteer.md +17 -1
- package/docs/helpers/REST.md +23 -9
- package/docs/helpers/WebDriver.md +3 -2
- package/docs/locators.md +27 -0
- package/docs/mobile.md +2 -1
- package/docs/nightmare.md +0 -5
- package/docs/parallel.md +14 -7
- package/docs/playwright.md +178 -11
- package/docs/plugins.md +61 -69
- package/docs/react.md +1 -1
- package/docs/reports.md +5 -4
- package/lib/actor.js +1 -2
- package/lib/codecept.js +13 -2
- package/lib/command/definitions.js +8 -1
- package/lib/command/interactive.js +4 -2
- package/lib/command/run-multiple/collection.js +4 -0
- package/lib/container.js +3 -3
- package/lib/helper/Appium.js +41 -0
- package/lib/helper/GraphQL.js +9 -10
- package/lib/helper/Playwright.js +218 -70
- package/lib/helper/Protractor.js +2 -0
- package/lib/helper/Puppeteer.js +56 -18
- package/lib/helper/REST.js +12 -0
- package/lib/helper/WebDriver.js +82 -16
- package/lib/helper/errors/ConnectionRefused.js +1 -1
- package/lib/helper/extras/Popup.js +1 -1
- package/lib/helper/extras/React.js +44 -32
- package/lib/interfaces/gherkin.js +1 -0
- package/lib/listener/exit.js +2 -4
- package/lib/listener/helpers.js +3 -4
- package/lib/locator.js +7 -0
- package/lib/mochaFactory.js +11 -6
- package/lib/output.js +5 -2
- package/lib/plugin/allure.js +7 -18
- package/lib/plugin/commentStep.js +1 -1
- package/lib/plugin/{puppeteerCoverage.js → coverage.js} +10 -22
- package/lib/plugin/customLocator.js +2 -2
- package/lib/plugin/screenshotOnFail.js +5 -0
- package/lib/plugin/subtitles.js +88 -0
- package/lib/plugin/tryTo.js +1 -1
- package/lib/step.js +4 -2
- package/lib/ui.js +6 -2
- package/package.json +5 -4
- package/typings/index.d.ts +44 -21
- package/typings/types.d.ts +137 -16
package/lib/mochaFactory.js
CHANGED
|
@@ -17,12 +17,6 @@ class MochaFactory {
|
|
|
17
17
|
output.process(opts.child);
|
|
18
18
|
mocha.ui(scenarioUi);
|
|
19
19
|
|
|
20
|
-
// process.on('unhandledRejection', (reason) => {
|
|
21
|
-
// output.error('Unhandled rejection');
|
|
22
|
-
// console.log(Error.captureStackTrace(reason));
|
|
23
|
-
// output.error(reason);
|
|
24
|
-
// });
|
|
25
|
-
|
|
26
20
|
Mocha.Runner.prototype.uncaught = function (err) {
|
|
27
21
|
if (err) {
|
|
28
22
|
if (err.toString().indexOf('ECONNREFUSED') >= 0) {
|
|
@@ -51,19 +45,30 @@ class MochaFactory {
|
|
|
51
45
|
|
|
52
46
|
// add ids for each test and check uniqueness
|
|
53
47
|
const dupes = [];
|
|
48
|
+
let missingFeatureInFile = [];
|
|
54
49
|
const seenTests = [];
|
|
55
50
|
mocha.suite.eachTest(test => {
|
|
56
51
|
test.id = genTestId(test);
|
|
52
|
+
|
|
57
53
|
const name = test.fullTitle();
|
|
58
54
|
if (seenTests.includes(test.id)) {
|
|
59
55
|
dupes.push(name);
|
|
60
56
|
}
|
|
61
57
|
seenTests.push(test.id);
|
|
58
|
+
|
|
59
|
+
if (name.slice(0, name.indexOf(':')) === '') {
|
|
60
|
+
missingFeatureInFile.push(test.file);
|
|
61
|
+
}
|
|
62
62
|
});
|
|
63
63
|
if (dupes.length) {
|
|
64
64
|
// ideally this should be no-op and throw (breaking change)...
|
|
65
65
|
output.error(`Duplicate test names detected - Feature + Scenario name should be unique:\n${dupes.join('\n')}`);
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
if (missingFeatureInFile.length) {
|
|
69
|
+
missingFeatureInFile = [...new Set(missingFeatureInFile)];
|
|
70
|
+
output.error(`Missing Feature section in:\n${missingFeatureInFile.join('\n')}`);
|
|
71
|
+
}
|
|
67
72
|
}
|
|
68
73
|
};
|
|
69
74
|
|
package/lib/output.js
CHANGED
|
@@ -190,6 +190,9 @@ module.exports = {
|
|
|
190
190
|
* @param {string} [color]
|
|
191
191
|
*/
|
|
192
192
|
say(message, color = 'cyan') {
|
|
193
|
+
if (colors[color] === undefined) {
|
|
194
|
+
color = 'cyan';
|
|
195
|
+
}
|
|
193
196
|
if (outputLevel >= 1) print(` ${colors[color].bold(message)}`);
|
|
194
197
|
},
|
|
195
198
|
|
|
@@ -232,8 +235,8 @@ function print(...msg) {
|
|
|
232
235
|
}
|
|
233
236
|
|
|
234
237
|
function truncate(msg, gap = 0) {
|
|
235
|
-
if (msg.indexOf('\n') > 0) {
|
|
236
|
-
return msg; // don't cut multi line steps
|
|
238
|
+
if (msg.indexOf('\n') > 0 || outputLevel >= 3) {
|
|
239
|
+
return msg; // don't cut multi line steps or on verbose log level
|
|
237
240
|
}
|
|
238
241
|
const width = (process.stdout.columns || 200) - gap - 4;
|
|
239
242
|
if (msg.length > width) {
|
package/lib/plugin/allure.js
CHANGED
|
@@ -83,7 +83,6 @@ module.exports = (config) => {
|
|
|
83
83
|
|
|
84
84
|
let currentMetaStep = [];
|
|
85
85
|
let currentStep;
|
|
86
|
-
let isHookSteps = false;
|
|
87
86
|
|
|
88
87
|
reporter.pendingCase = function (testName, timestamp, opts = {}) {
|
|
89
88
|
reporter.startCase(testName, timestamp);
|
|
@@ -191,14 +190,6 @@ module.exports = (config) => {
|
|
|
191
190
|
}
|
|
192
191
|
});
|
|
193
192
|
|
|
194
|
-
event.dispatcher.on(event.hook.started, () => {
|
|
195
|
-
isHookSteps = true;
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
event.dispatcher.on(event.hook.passed, () => {
|
|
199
|
-
isHookSteps = false;
|
|
200
|
-
});
|
|
201
|
-
|
|
202
193
|
event.dispatcher.on(event.suite.after, () => {
|
|
203
194
|
reporter.endSuite();
|
|
204
195
|
});
|
|
@@ -258,15 +249,13 @@ module.exports = (config) => {
|
|
|
258
249
|
});
|
|
259
250
|
|
|
260
251
|
event.dispatcher.on(event.step.started, (step) => {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
currentStep = step;
|
|
269
|
-
}
|
|
252
|
+
startMetaStep(step.metaStep);
|
|
253
|
+
if (currentStep !== step) {
|
|
254
|
+
// In multi-session scenarios, actors' names will be highlighted with ANSI
|
|
255
|
+
// escape sequences which are invalid XML values
|
|
256
|
+
step.actor = step.actor.replace(ansiRegExp(), '');
|
|
257
|
+
reporter.startStep(step.toString());
|
|
258
|
+
currentStep = step;
|
|
270
259
|
}
|
|
271
260
|
});
|
|
272
261
|
|
|
@@ -41,7 +41,7 @@ const defaultGlobalName = '__';
|
|
|
41
41
|
* ### Config
|
|
42
42
|
*
|
|
43
43
|
* * `enabled` - (default: false) enable a plugin
|
|
44
|
-
* * `
|
|
44
|
+
* * `registerGlobal` - (default: false) register `__` template literal function globally. You can override function global name by providing a name as a value.
|
|
45
45
|
*
|
|
46
46
|
* ### Examples
|
|
47
47
|
*
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const
|
|
1
|
+
const debugModule = require('debug');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
|
|
@@ -13,7 +13,7 @@ const defaultConfig = {
|
|
|
13
13
|
uniqueFileName: true,
|
|
14
14
|
};
|
|
15
15
|
|
|
16
|
-
const supportedHelpers = ['Puppeteer'];
|
|
16
|
+
const supportedHelpers = ['Puppeteer', 'Playwright'];
|
|
17
17
|
|
|
18
18
|
function buildFileName(test, uniqueFileName) {
|
|
19
19
|
let fileName = clearString(test.title);
|
|
@@ -41,15 +41,14 @@ function buildFileName(test, uniqueFileName) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Dumps
|
|
44
|
+
* Dumps code coverage from Playwright/Puppeteer after every test.
|
|
45
45
|
*
|
|
46
46
|
* #### Configuration
|
|
47
47
|
*
|
|
48
|
-
* Configuration can either be taken from a corresponding helper (deprecated) or a from plugin config (recommended).
|
|
49
48
|
*
|
|
50
49
|
* ```js
|
|
51
50
|
* plugins: {
|
|
52
|
-
*
|
|
51
|
+
* playwrightCoverage: {
|
|
53
52
|
* enabled: true
|
|
54
53
|
* }
|
|
55
54
|
* }
|
|
@@ -59,33 +58,22 @@ function buildFileName(test, uniqueFileName) {
|
|
|
59
58
|
*
|
|
60
59
|
* * `coverageDir`: directory to dump coverage files
|
|
61
60
|
* * `uniqueFileName`: generate a unique filename by adding uuid
|
|
62
|
-
*
|
|
63
|
-
* First of all, your mileage may vary!
|
|
64
|
-
*
|
|
65
|
-
* To work, you need the client javascript code to be NOT uglified. They need to be built in "development" mode.
|
|
66
|
-
* And the end of your tests, you'll get a directory full of coverage per test run. Now what?
|
|
67
|
-
* You'll need to convert the coverage code to something istanbul can read. Good news is someone wrote the code
|
|
68
|
-
* for you (see puppeteer-to-istanbul link below). Then using istanbul you need to combine the converted
|
|
69
|
-
* coverage and create a report. Good luck!
|
|
70
|
-
*
|
|
71
|
-
* Links:
|
|
72
|
-
* * https://github.com/GoogleChrome/puppeteer/blob/v1.12.2/docs/api.md#class-coverage
|
|
73
|
-
* * https://github.com/istanbuljs/puppeteer-to-istanbul
|
|
74
|
-
* * https://github.com/gotwarlost/istanbul
|
|
75
61
|
*/
|
|
76
62
|
module.exports = function (config) {
|
|
77
63
|
const helpers = Container.helpers();
|
|
78
64
|
let coverageRunning = false;
|
|
79
65
|
let helper;
|
|
80
66
|
|
|
67
|
+
let debug;
|
|
81
68
|
for (const helperName of supportedHelpers) {
|
|
82
69
|
if (Object.keys(helpers).indexOf(helperName) > -1) {
|
|
83
70
|
helper = helpers[helperName];
|
|
71
|
+
debug = debugModule(`codeceptjs:plugin:${helperName.toLowerCase()}Coverage`);
|
|
84
72
|
}
|
|
85
73
|
}
|
|
86
74
|
|
|
87
75
|
if (!helper) {
|
|
88
|
-
console.error('Coverage is only supported in Puppeteer');
|
|
76
|
+
console.error('Coverage is only supported in Puppeteer, Playwright');
|
|
89
77
|
return; // no helpers for screenshot
|
|
90
78
|
}
|
|
91
79
|
|
|
@@ -102,7 +90,7 @@ module.exports = function (config) {
|
|
|
102
90
|
'starting coverage',
|
|
103
91
|
async () => {
|
|
104
92
|
try {
|
|
105
|
-
if (!coverageRunning) {
|
|
93
|
+
if (!coverageRunning && helper.page && helper.page.coverage) {
|
|
106
94
|
debug('--> starting coverage <--');
|
|
107
95
|
coverageRunning = true;
|
|
108
96
|
await helper.page.coverage.startJSCoverage();
|
|
@@ -115,13 +103,13 @@ module.exports = function (config) {
|
|
|
115
103
|
);
|
|
116
104
|
});
|
|
117
105
|
|
|
118
|
-
// Save
|
|
106
|
+
// Save coverage data after every test run
|
|
119
107
|
event.dispatcher.on(event.test.after, async (test) => {
|
|
120
108
|
recorder.add(
|
|
121
109
|
'saving coverage',
|
|
122
110
|
async () => {
|
|
123
111
|
try {
|
|
124
|
-
if (coverageRunning) {
|
|
112
|
+
if (coverageRunning && helper.page && helper.page.coverage) {
|
|
125
113
|
debug('--> stopping coverage <--');
|
|
126
114
|
coverageRunning = false;
|
|
127
115
|
const coverage = await helper.page.coverage.stopJSCoverage();
|
|
@@ -38,7 +38,7 @@ const defaultConfig = {
|
|
|
38
38
|
* // in codecept.conf.js
|
|
39
39
|
* plugins: {
|
|
40
40
|
* customLocator: {
|
|
41
|
-
* enabled: true
|
|
41
|
+
* enabled: true,
|
|
42
42
|
* attribute: 'data-test'
|
|
43
43
|
* }
|
|
44
44
|
* }
|
|
@@ -57,7 +57,7 @@ const defaultConfig = {
|
|
|
57
57
|
* // in codecept.conf.js
|
|
58
58
|
* plugins: {
|
|
59
59
|
* customLocator: {
|
|
60
|
-
* enabled: true
|
|
60
|
+
* enabled: true,
|
|
61
61
|
* prefix: '=',
|
|
62
62
|
* attribute: 'data-qa'
|
|
63
63
|
* }
|
|
@@ -107,6 +107,11 @@ module.exports = function (config) {
|
|
|
107
107
|
if (allureReporter) {
|
|
108
108
|
allureReporter.addAttachment('Last Seen Screenshot', fs.readFileSync(path.join(global.output_dir, fileName)), 'image/png');
|
|
109
109
|
}
|
|
110
|
+
|
|
111
|
+
const cucumberReporter = Container.plugins('cucumberJsonReporter');
|
|
112
|
+
if (cucumberReporter) {
|
|
113
|
+
cucumberReporter.addScreenshot(test.artifacts.screenshot);
|
|
114
|
+
}
|
|
110
115
|
} catch (err) {
|
|
111
116
|
output.plugin(err);
|
|
112
117
|
if (
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
const { v4: uuidv4 } = require('uuid');
|
|
2
|
+
const fsPromise = require('fs').promises;
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const event = require('../event');
|
|
5
|
+
|
|
6
|
+
// This will convert a given timestamp in milliseconds to
|
|
7
|
+
// an SRT recognized timestamp, ie HH:mm:ss,SSS
|
|
8
|
+
function formatTimestamp(timestampInMs) {
|
|
9
|
+
const date = new Date(0, 0, 0, 0, 0, 0, timestampInMs);
|
|
10
|
+
const hours = date.getHours();
|
|
11
|
+
const minutes = date.getMinutes();
|
|
12
|
+
const seconds = date.getSeconds();
|
|
13
|
+
const ms = timestampInMs - (hours * 3600000 + minutes * 60000 + seconds * 1000);
|
|
14
|
+
return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')},${ms.toString().padStart(3, '0')}`;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
let steps = {};
|
|
18
|
+
let testStartedAt;
|
|
19
|
+
/**
|
|
20
|
+
* Automatically captures steps as subtitle, and saves it as an artifact when a video is found for a failed test
|
|
21
|
+
*
|
|
22
|
+
* #### Configuration
|
|
23
|
+
* ```js
|
|
24
|
+
* plugins: {
|
|
25
|
+
* subtitles: {
|
|
26
|
+
* enabled: true
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
module.exports = function () {
|
|
32
|
+
event.dispatcher.on(event.test.before, (_) => {
|
|
33
|
+
testStartedAt = Date.now();
|
|
34
|
+
steps = {};
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
event.dispatcher.on(event.step.started, (step) => {
|
|
38
|
+
const stepStartedAt = Date.now();
|
|
39
|
+
step.id = uuidv4();
|
|
40
|
+
|
|
41
|
+
let title = `${step.actor}.${step.name}(${step.args ? step.args.join(',') : ''})`;
|
|
42
|
+
if (title.length > 100) {
|
|
43
|
+
title = `${title.substring(0, 100)}...`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
steps[step.id] = {
|
|
47
|
+
start: formatTimestamp(stepStartedAt - testStartedAt),
|
|
48
|
+
startedAt: stepStartedAt,
|
|
49
|
+
title,
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
event.dispatcher.on(event.step.finished, (step) => {
|
|
54
|
+
if (step && step.id && steps[step.id]) {
|
|
55
|
+
steps[step.id].end = formatTimestamp(Date.now() - testStartedAt);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
event.dispatcher.on(event.test.after, async (test) => {
|
|
60
|
+
if (test && test.artifacts && test.artifacts.video) {
|
|
61
|
+
const stepsSortedByStartTime = Object.values(steps);
|
|
62
|
+
stepsSortedByStartTime.sort((stepA, stepB) => {
|
|
63
|
+
return stepA.startedAt - stepB.startedAt;
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
let subtitle = '';
|
|
67
|
+
|
|
68
|
+
// For an SRT file, every subtitle has to be in the format as mentioned below:
|
|
69
|
+
//
|
|
70
|
+
// 1
|
|
71
|
+
// HH:mm:ss,SSS --> HH:mm:ss,SSS
|
|
72
|
+
// [title]
|
|
73
|
+
stepsSortedByStartTime.forEach((step, index) => {
|
|
74
|
+
if (step.end) {
|
|
75
|
+
subtitle = `${subtitle}${index + 1}
|
|
76
|
+
${step.start} --> ${step.end}
|
|
77
|
+
${step.title}
|
|
78
|
+
|
|
79
|
+
`;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
const { dir: artifactsDirectory, name: fileName } = path.parse(test.artifacts.video);
|
|
84
|
+
await fsPromise.writeFile(`${artifactsDirectory}/${fileName}.srt`, subtitle);
|
|
85
|
+
test.artifacts.subtitle = `${artifactsDirectory}/${fileName}.srt`;
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
};
|
package/lib/plugin/tryTo.js
CHANGED
|
@@ -89,7 +89,7 @@ function tryTo(callback) {
|
|
|
89
89
|
recorder.session.catch((err) => {
|
|
90
90
|
result = false;
|
|
91
91
|
const msg = err.inspect ? err.inspect() : err.toString();
|
|
92
|
-
debug(`
|
|
92
|
+
debug(`Unsuccessful try > ${msg}`);
|
|
93
93
|
recorder.session.restore('tryTo');
|
|
94
94
|
return result;
|
|
95
95
|
});
|
package/lib/step.js
CHANGED
|
@@ -212,16 +212,18 @@ class MetaStep extends Step {
|
|
|
212
212
|
step.metaStep = this;
|
|
213
213
|
};
|
|
214
214
|
event.dispatcher.prependListener(event.step.before, registerStep);
|
|
215
|
+
let rethrownError = null;
|
|
215
216
|
try {
|
|
216
217
|
this.startTime = Date.now();
|
|
217
218
|
result = fn.apply(this.context, this.args);
|
|
218
219
|
} catch (error) {
|
|
219
|
-
this.
|
|
220
|
+
this.setStatus('failed');
|
|
221
|
+
rethrownError = error;
|
|
220
222
|
} finally {
|
|
221
223
|
this.endTime = Date.now();
|
|
222
|
-
|
|
223
224
|
event.dispatcher.removeListener(event.step.before, registerStep);
|
|
224
225
|
}
|
|
226
|
+
if (rethrownError) { throw rethrownError; }
|
|
225
227
|
return result;
|
|
226
228
|
}
|
|
227
229
|
}
|
package/lib/ui.js
CHANGED
|
@@ -176,8 +176,12 @@ module.exports = function (suite) {
|
|
|
176
176
|
* @kind constant
|
|
177
177
|
* @type {CodeceptJS.IScenario}
|
|
178
178
|
*/
|
|
179
|
-
context.xScenario = context.Scenario.skip = function (title) {
|
|
180
|
-
|
|
179
|
+
context.xScenario = context.Scenario.skip = function (title, opts = {}, fn) {
|
|
180
|
+
if (typeof opts === 'function' && !fn) {
|
|
181
|
+
opts = {};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return context.Scenario(title, opts);
|
|
181
185
|
};
|
|
182
186
|
|
|
183
187
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.2",
|
|
4
4
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"acceptance",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"promise-retry": "^1.1.1",
|
|
85
85
|
"requireg": "^0.2.2",
|
|
86
86
|
"resq": "^1.10.0",
|
|
87
|
-
"
|
|
88
|
-
"
|
|
87
|
+
"sprintf-js": "^1.1.1",
|
|
88
|
+
"uuid": "^8.3.2"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
91
|
"@codeceptjs/detox-helper": "^1.0.2",
|
|
@@ -123,10 +123,11 @@
|
|
|
123
123
|
"nodemon": "^1.19.4",
|
|
124
124
|
"playwright": "^1.9.1",
|
|
125
125
|
"protractor": "^5.4.4",
|
|
126
|
-
"puppeteer": "^
|
|
126
|
+
"puppeteer": "^10.0.0",
|
|
127
127
|
"qrcode-terminal": "^0.12.0",
|
|
128
128
|
"rosie": "^1.6.0",
|
|
129
129
|
"runok": "^0.9.2",
|
|
130
|
+
"semver": "^6.3.0",
|
|
130
131
|
"sinon": "^9.2.2",
|
|
131
132
|
"sinon-chai": "^3.5.0",
|
|
132
133
|
"testcafe": "^1.9.4",
|
package/typings/index.d.ts
CHANGED
|
@@ -8,13 +8,13 @@ declare namespace CodeceptJS {
|
|
|
8
8
|
import("./utils").Translate<T, Translation.Actions>;
|
|
9
9
|
|
|
10
10
|
type Cookie = {
|
|
11
|
-
name: string
|
|
12
|
-
value: string
|
|
13
|
-
}
|
|
11
|
+
name: string;
|
|
12
|
+
value: string;
|
|
13
|
+
};
|
|
14
14
|
|
|
15
15
|
interface PageScrollPosition {
|
|
16
|
-
x: number
|
|
17
|
-
y: number
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
// Could get extended by user generated typings
|
|
@@ -23,7 +23,7 @@ declare namespace CodeceptJS {
|
|
|
23
23
|
interface IHook {}
|
|
24
24
|
interface IScenario {}
|
|
25
25
|
interface IFeature {
|
|
26
|
-
(title: string): FeatureConfig
|
|
26
|
+
(title: string): FeatureConfig;
|
|
27
27
|
}
|
|
28
28
|
interface CallbackOrder extends Array<any> {}
|
|
29
29
|
interface SupportObject {
|
|
@@ -51,25 +51,48 @@ declare namespace CodeceptJS {
|
|
|
51
51
|
| { frame: string }
|
|
52
52
|
| { android: string }
|
|
53
53
|
| { ios: string }
|
|
54
|
-
| { android: string
|
|
55
|
-
| { react: string }
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
| { android: string; ios: string }
|
|
55
|
+
| { react: string }
|
|
56
|
+
| { shadow: string }
|
|
57
|
+
| { custom: string };
|
|
58
|
+
|
|
59
|
+
interface CustomLocators {}
|
|
60
|
+
type LocatorOrString =
|
|
61
|
+
| string
|
|
62
|
+
| ILocator
|
|
63
|
+
| Locator
|
|
64
|
+
| CustomLocators[keyof CustomLocators];
|
|
59
65
|
|
|
60
66
|
type StringOrSecret = string | CodeceptJS.Secret;
|
|
61
67
|
|
|
62
|
-
interface HookCallback {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
interface
|
|
68
|
+
interface HookCallback {
|
|
69
|
+
(args: SupportObject): void;
|
|
70
|
+
}
|
|
71
|
+
interface Scenario extends IScenario {
|
|
72
|
+
only: IScenario;
|
|
73
|
+
skip: IScenario;
|
|
74
|
+
todo: IScenario;
|
|
75
|
+
}
|
|
76
|
+
interface Feature extends IFeature {
|
|
77
|
+
skip: IFeature;
|
|
78
|
+
}
|
|
79
|
+
interface IData {
|
|
80
|
+
Scenario: IScenario;
|
|
81
|
+
only: { Scenario: IScenario };
|
|
82
|
+
}
|
|
66
83
|
|
|
67
84
|
interface IScenario {
|
|
68
85
|
// Scenario.todo can be called only with a title.
|
|
69
86
|
(title: string, callback?: HookCallback): ScenarioConfig;
|
|
70
|
-
(
|
|
87
|
+
(
|
|
88
|
+
title: string,
|
|
89
|
+
opts: { [key: string]: any },
|
|
90
|
+
callback: HookCallback
|
|
91
|
+
): ScenarioConfig;
|
|
92
|
+
}
|
|
93
|
+
interface IHook {
|
|
94
|
+
(callback: HookCallback): void;
|
|
71
95
|
}
|
|
72
|
-
interface IHook { (callback: HookCallback): void; }
|
|
73
96
|
|
|
74
97
|
interface Globals {
|
|
75
98
|
codeceptjs: typeof codeceptjs;
|
|
@@ -164,12 +187,12 @@ declare namespace Mocha {
|
|
|
164
187
|
}
|
|
165
188
|
|
|
166
189
|
interface Suite extends SuiteRunnable {
|
|
167
|
-
tags: any[]
|
|
168
|
-
comment: string
|
|
169
|
-
feature: any
|
|
190
|
+
tags: any[];
|
|
191
|
+
comment: string;
|
|
192
|
+
feature: any;
|
|
170
193
|
}
|
|
171
194
|
|
|
172
|
-
interface Test
|
|
195
|
+
interface Test extends Runnable {
|
|
173
196
|
tags: any[];
|
|
174
197
|
}
|
|
175
198
|
}
|