codeceptjs 3.0.7 → 3.1.3
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 +96 -2
- package/README.md +9 -1
- package/bin/codecept.js +27 -17
- package/docs/bdd.md +55 -1
- package/docs/build/Appium.js +76 -4
- package/docs/build/Playwright.js +186 -69
- package/docs/build/Protractor.js +2 -0
- package/docs/build/Puppeteer.js +56 -18
- package/docs/build/REST.js +12 -0
- package/docs/build/WebDriver.js +1 -3
- package/docs/changelog.md +96 -2
- package/docs/commands.md +21 -7
- package/docs/configuration.md +15 -2
- package/docs/helpers/Appium.md +96 -94
- package/docs/helpers/Playwright.md +259 -202
- package/docs/helpers/Puppeteer.md +17 -1
- package/docs/helpers/REST.md +23 -9
- package/docs/helpers/WebDriver.md +2 -2
- package/docs/mobile.md +2 -1
- package/docs/playwright.md +156 -6
- package/docs/plugins.md +61 -69
- package/docs/react.md +1 -1
- package/docs/reports.md +21 -3
- package/lib/actor.js +2 -3
- package/lib/codecept.js +13 -2
- package/lib/command/definitions.js +8 -1
- package/lib/command/run-multiple/collection.js +4 -0
- package/lib/config.js +1 -1
- package/lib/container.js +3 -3
- package/lib/data/dataTableArgument.js +35 -0
- package/lib/helper/Appium.js +49 -4
- package/lib/helper/Playwright.js +186 -69
- 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 +1 -3
- 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/index.js +2 -0
- package/lib/interfaces/gherkin.js +8 -1
- package/lib/listener/exit.js +2 -4
- package/lib/listener/helpers.js +4 -4
- package/lib/locator.js +7 -0
- package/lib/mochaFactory.js +13 -9
- package/lib/output.js +2 -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/subtitles.js +88 -0
- package/lib/plugin/tryTo.js +1 -1
- package/lib/recorder.js +5 -3
- package/lib/step.js +4 -2
- package/package.json +4 -3
- package/typings/index.d.ts +2 -0
- package/typings/types.d.ts +158 -18
|
@@ -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
|
+
* coverage: {
|
|
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
|
* }
|
|
@@ -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/recorder.js
CHANGED
|
@@ -3,6 +3,8 @@ const promiseRetry = require('promise-retry');
|
|
|
3
3
|
|
|
4
4
|
const { log } = require('./output');
|
|
5
5
|
|
|
6
|
+
const MAX_TASKS = 100;
|
|
7
|
+
|
|
6
8
|
let promise;
|
|
7
9
|
let running = false;
|
|
8
10
|
let errFn;
|
|
@@ -172,7 +174,7 @@ module.exports = {
|
|
|
172
174
|
return;
|
|
173
175
|
}
|
|
174
176
|
tasks.push(taskName);
|
|
175
|
-
debug(`${currentQueue()}Queued | ${taskName}`);
|
|
177
|
+
if (process.env.DEBUG) debug(`${currentQueue()}Queued | ${taskName}`);
|
|
176
178
|
|
|
177
179
|
return promise = Promise.resolve(promise).then((res) => {
|
|
178
180
|
const retryOpts = this.retries.slice(-1).pop();
|
|
@@ -296,7 +298,7 @@ module.exports = {
|
|
|
296
298
|
* @inner
|
|
297
299
|
*/
|
|
298
300
|
stop() {
|
|
299
|
-
debug(this.toString());
|
|
301
|
+
if (process.env.DEBUG) debug(this.toString());
|
|
300
302
|
log(`${currentQueue()}Stopping recording promises`);
|
|
301
303
|
running = false;
|
|
302
304
|
},
|
|
@@ -318,7 +320,7 @@ module.exports = {
|
|
|
318
320
|
* @inner
|
|
319
321
|
*/
|
|
320
322
|
scheduled() {
|
|
321
|
-
return tasks.join('\n');
|
|
323
|
+
return tasks.slice(-MAX_TASKS).join('\n');
|
|
322
324
|
},
|
|
323
325
|
|
|
324
326
|
/**
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codeceptjs",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.3",
|
|
4
4
|
"description": "Supercharged End 2 End Testing Framework for NodeJS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"acceptance",
|
|
@@ -84,7 +84,8 @@
|
|
|
84
84
|
"promise-retry": "^1.1.1",
|
|
85
85
|
"requireg": "^0.2.2",
|
|
86
86
|
"resq": "^1.10.0",
|
|
87
|
-
"sprintf-js": "^1.1.1"
|
|
87
|
+
"sprintf-js": "^1.1.1",
|
|
88
|
+
"uuid": "^8.3.2"
|
|
88
89
|
},
|
|
89
90
|
"devDependencies": {
|
|
90
91
|
"@codeceptjs/detox-helper": "^1.0.2",
|
|
@@ -122,7 +123,7 @@
|
|
|
122
123
|
"nodemon": "^1.19.4",
|
|
123
124
|
"playwright": "^1.9.1",
|
|
124
125
|
"protractor": "^5.4.4",
|
|
125
|
-
"puppeteer": "^
|
|
126
|
+
"puppeteer": "^10.0.0",
|
|
126
127
|
"qrcode-terminal": "^0.12.0",
|
|
127
128
|
"rosie": "^1.6.0",
|
|
128
129
|
"runok": "^0.9.2",
|
package/typings/index.d.ts
CHANGED
|
@@ -111,6 +111,7 @@ declare const pause: typeof CodeceptJS.pause;
|
|
|
111
111
|
declare const within: typeof CodeceptJS.within;
|
|
112
112
|
declare const session: typeof CodeceptJS.session;
|
|
113
113
|
declare const DataTable: typeof CodeceptJS.DataTable;
|
|
114
|
+
declare const DataTableArgument: typeof CodeceptJS.DataTableArgument;
|
|
114
115
|
declare const codeceptjs: typeof CodeceptJS.index;
|
|
115
116
|
declare const locate: typeof CodeceptJS.Locator.build;
|
|
116
117
|
declare function inject(): CodeceptJS.SupportObject;
|
|
@@ -160,6 +161,7 @@ declare namespace NodeJS {
|
|
|
160
161
|
within: typeof within;
|
|
161
162
|
session: typeof session;
|
|
162
163
|
DataTable: typeof DataTable;
|
|
164
|
+
DataTableArgument: typeof DataTableArgument;
|
|
163
165
|
locate: typeof locate;
|
|
164
166
|
inject: typeof inject;
|
|
165
167
|
secret: typeof secret;
|
package/typings/types.d.ts
CHANGED
|
@@ -321,11 +321,11 @@ declare namespace CodeceptJS {
|
|
|
321
321
|
* ```js
|
|
322
322
|
* I.removeApp('appName', 'com.example.android.apis');
|
|
323
323
|
* ```
|
|
324
|
-
* @param bundleId - String ID of bundle
|
|
325
324
|
*
|
|
326
325
|
* Appium: support only Android
|
|
326
|
+
* @param [bundleId] - ID of bundle
|
|
327
327
|
*/
|
|
328
|
-
removeApp(appId: string, bundleId
|
|
328
|
+
removeApp(appId: string, bundleId?: string): void;
|
|
329
329
|
/**
|
|
330
330
|
* Check current activity on an Android device.
|
|
331
331
|
*
|
|
@@ -522,11 +522,12 @@ declare namespace CodeceptJS {
|
|
|
522
522
|
* // or by pressing key
|
|
523
523
|
* I.hideDeviceKeyboard('pressKey', 'Done');
|
|
524
524
|
* ```
|
|
525
|
-
* @param strategy - desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
|
|
526
525
|
*
|
|
527
526
|
* Appium: support Android and iOS
|
|
527
|
+
* @param [strategy] - Desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)
|
|
528
|
+
* @param [key] - Optional key
|
|
528
529
|
*/
|
|
529
|
-
hideDeviceKeyboard(strategy
|
|
530
|
+
hideDeviceKeyboard(strategy?: 'tapOutside' | 'pressKey', key?: string): void;
|
|
530
531
|
/**
|
|
531
532
|
* Send a key event to the device.
|
|
532
533
|
* List of keys: https://developer.android.com/reference/android/view/KeyEvent.html
|
|
@@ -682,8 +683,9 @@ declare namespace CodeceptJS {
|
|
|
682
683
|
* ```
|
|
683
684
|
*
|
|
684
685
|
* Appium: support Android and iOS
|
|
686
|
+
* @param actions - Array of touch actions
|
|
685
687
|
*/
|
|
686
|
-
touchPerform(): void;
|
|
688
|
+
touchPerform(actions: any[]): void;
|
|
687
689
|
/**
|
|
688
690
|
* Pulls a file from the device.
|
|
689
691
|
*
|
|
@@ -886,6 +888,45 @@ declare namespace CodeceptJS {
|
|
|
886
888
|
* @returns attribute value
|
|
887
889
|
*/
|
|
888
890
|
grabTextFrom(locator: CodeceptJS.LocatorOrString): Promise<string>;
|
|
891
|
+
/**
|
|
892
|
+
* Grab number of visible elements by locator.
|
|
893
|
+
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
894
|
+
*
|
|
895
|
+
* ```js
|
|
896
|
+
* let numOfElements = await I.grabNumberOfVisibleElements('p');
|
|
897
|
+
* ```
|
|
898
|
+
* @param locator - located by CSS|XPath|strict locator.
|
|
899
|
+
* @returns number of visible elements
|
|
900
|
+
*/
|
|
901
|
+
grabNumberOfVisibleElements(locator: CodeceptJS.LocatorOrString): Promise<number>;
|
|
902
|
+
/**
|
|
903
|
+
* Can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
|
|
904
|
+
*
|
|
905
|
+
* Retrieves an attribute from an element located by CSS or XPath and returns it to test.
|
|
906
|
+
* Resumes test execution, so **should be used inside async with `await`** operator.
|
|
907
|
+
* If more than one element is found - attribute of first element is returned.
|
|
908
|
+
*
|
|
909
|
+
* ```js
|
|
910
|
+
* let hint = await I.grabAttributeFrom('#tooltip', 'title');
|
|
911
|
+
* ```
|
|
912
|
+
* @param locator - element located by CSS|XPath|strict locator.
|
|
913
|
+
* @param attr - attribute name.
|
|
914
|
+
* @returns attribute value
|
|
915
|
+
*/
|
|
916
|
+
grabAttributeFrom(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string>;
|
|
917
|
+
/**
|
|
918
|
+
* Can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
|
|
919
|
+
* Retrieves an array of attributes from elements located by CSS or XPath and returns it to test.
|
|
920
|
+
* Resumes test execution, so **should be used inside async with `await`** operator.
|
|
921
|
+
*
|
|
922
|
+
* ```js
|
|
923
|
+
* let hints = await I.grabAttributeFromAll('.tooltip', 'title');
|
|
924
|
+
* ```
|
|
925
|
+
* @param locator - element located by CSS|XPath|strict locator.
|
|
926
|
+
* @param attr - attribute name.
|
|
927
|
+
* @returns attribute value
|
|
928
|
+
*/
|
|
929
|
+
grabAttributeFromAll(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string[]>;
|
|
889
930
|
/**
|
|
890
931
|
* Retrieves an array of value from a form located by CSS or XPath and returns it to test.
|
|
891
932
|
* Resumes test execution, so **should be used inside async function with `await`** operator.
|
|
@@ -909,6 +950,16 @@ declare namespace CodeceptJS {
|
|
|
909
950
|
* @returns attribute value
|
|
910
951
|
*/
|
|
911
952
|
grabValueFrom(locator: CodeceptJS.LocatorOrString): Promise<string>;
|
|
953
|
+
/**
|
|
954
|
+
* Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
|
|
955
|
+
* Filename is relative to output folder.
|
|
956
|
+
*
|
|
957
|
+
* ```js
|
|
958
|
+
* I.saveScreenshot('debug.png');
|
|
959
|
+
* ```
|
|
960
|
+
* @param fileName - file name to save.
|
|
961
|
+
*/
|
|
962
|
+
saveScreenshot(fileName: string): void;
|
|
912
963
|
/**
|
|
913
964
|
* Scroll element into viewport.
|
|
914
965
|
*
|
|
@@ -2368,6 +2419,8 @@ declare namespace CodeceptJS {
|
|
|
2368
2419
|
* * `restart`: (optional, default: true) - restart browser between tests.
|
|
2369
2420
|
* * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
|
|
2370
2421
|
* * `emulate`: (optional, default: {}) launch browser in device emulation mode.
|
|
2422
|
+
* * `video`: (optional, default: false) enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
2423
|
+
* * `trace`: (optional, default: false) record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
|
|
2371
2424
|
* * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
|
|
2372
2425
|
* * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
2373
2426
|
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
|
|
@@ -2384,6 +2437,22 @@ declare namespace CodeceptJS {
|
|
|
2384
2437
|
* * `chromium`: (optional) pass additional chromium options
|
|
2385
2438
|
* * `electron`: (optional) pass additional electron options
|
|
2386
2439
|
*
|
|
2440
|
+
* #### Video Recording Customization
|
|
2441
|
+
*
|
|
2442
|
+
* By default, video is saved to `output/video` dir. You can customize this path by passing `dir` option to `recordVideo` option.
|
|
2443
|
+
*
|
|
2444
|
+
* * `video`: enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
2445
|
+
* * `keepVideoForPassedTests`: - save videos for passed tests
|
|
2446
|
+
* * `recordVideo`: [additional options for videos customization](https://playwright.dev/docs/next/api/class-browser#browser-new-context)
|
|
2447
|
+
*
|
|
2448
|
+
* #### Trace Recording Customization
|
|
2449
|
+
*
|
|
2450
|
+
* Trace recording provides a complete information on test execution and includes DOM snapshots, screenshots, and network requests logged during run.
|
|
2451
|
+
* Traces will be saved to `output/trace`
|
|
2452
|
+
*
|
|
2453
|
+
* * `trace`: enables trace recording for failed tests; trace are saved into `output/trace` folder
|
|
2454
|
+
* * `keepTraceForPassedTests`: - save trace for passed tests
|
|
2455
|
+
*
|
|
2387
2456
|
* #### Example #1: Wait for 0 network connections.
|
|
2388
2457
|
*
|
|
2389
2458
|
* ```js
|
|
@@ -2435,7 +2504,7 @@ declare namespace CodeceptJS {
|
|
|
2435
2504
|
* Playwright: {
|
|
2436
2505
|
* url: "http://localhost",
|
|
2437
2506
|
* chromium: {
|
|
2438
|
-
* browserWSEndpoint:
|
|
2507
|
+
* browserWSEndpoint: 'ws://localhost:9222/devtools/browser/c5aa6160-b5bc-4d53-bb49-6ecb36cd2e0a'
|
|
2439
2508
|
* }
|
|
2440
2509
|
* }
|
|
2441
2510
|
* }
|
|
@@ -3902,6 +3971,29 @@ declare namespace CodeceptJS {
|
|
|
3902
3971
|
* @returns Element bounding rectangle
|
|
3903
3972
|
*/
|
|
3904
3973
|
grabElementBoundingRect(locator: LocatorOrString, elementSize?: string): Promise<DOMRect> | Promise<number>;
|
|
3974
|
+
/**
|
|
3975
|
+
* Mocks network request using [`browserContext.route`](https://playwright.dev/docs/api/class-browsercontext#browser-context-route) of Playwright
|
|
3976
|
+
*
|
|
3977
|
+
* ```js
|
|
3978
|
+
* I.mockRoute(/(\.png$)|(\.jpg$)/, route => route.abort());
|
|
3979
|
+
* ```
|
|
3980
|
+
* This method allows intercepting and mocking requests & responses. [Learn more about it](https://playwright.dev/docs/network#handle-requests)
|
|
3981
|
+
* @param [url] - URL, regex or pattern for to match URL
|
|
3982
|
+
* @param [handler] - a function to process request
|
|
3983
|
+
*/
|
|
3984
|
+
mockRoute(url?: string, handler?: (...params: any[]) => any): void;
|
|
3985
|
+
/**
|
|
3986
|
+
* Stops network mocking created by `mockRoute`.
|
|
3987
|
+
*
|
|
3988
|
+
* ```js
|
|
3989
|
+
* I.stopMockingRoute(/(\.png$)|(\.jpg$)/);
|
|
3990
|
+
* I.stopMockingRoute(/(\.png$)|(\.jpg$)/, previouslySetHandler);
|
|
3991
|
+
* ```
|
|
3992
|
+
* If no handler is passed, all mock requests for the rote are disabled.
|
|
3993
|
+
* @param [url] - URL, regex or pattern for to match URL
|
|
3994
|
+
* @param [handler] - a function to process request
|
|
3995
|
+
*/
|
|
3996
|
+
stopMockingRoute(url?: string, handler?: (...params: any[]) => any): void;
|
|
3905
3997
|
}
|
|
3906
3998
|
/**
|
|
3907
3999
|
* This helper works the same as MockRequest helper. It has been included for backwards compatibility
|
|
@@ -5294,6 +5386,7 @@ declare namespace CodeceptJS {
|
|
|
5294
5386
|
* }
|
|
5295
5387
|
* }
|
|
5296
5388
|
* ```
|
|
5389
|
+
* > Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
|
|
5297
5390
|
*
|
|
5298
5391
|
* #### Example #5: Target URL with provided basic authentication
|
|
5299
5392
|
*
|
|
@@ -5308,10 +5401,25 @@ declare namespace CodeceptJS {
|
|
|
5308
5401
|
* }
|
|
5309
5402
|
* }
|
|
5310
5403
|
* ```
|
|
5404
|
+
* #### Troubleshooting
|
|
5311
5405
|
*
|
|
5406
|
+
* Error Message: `No usable sandbox!`
|
|
5407
|
+
*
|
|
5408
|
+
* When running Puppeteer on CI try to disable sandbox if you see that message
|
|
5409
|
+
*
|
|
5410
|
+
* ```
|
|
5411
|
+
* helpers: {
|
|
5412
|
+
* Puppeteer: {
|
|
5413
|
+
* url: 'http://localhost',
|
|
5414
|
+
* show: false,
|
|
5415
|
+
* chrome: {
|
|
5416
|
+
* args: ['--no-sandbox', '--disable-setuid-sandbox']
|
|
5417
|
+
* }
|
|
5418
|
+
* },
|
|
5419
|
+
* }
|
|
5420
|
+
* ```
|
|
5312
5421
|
*
|
|
5313
5422
|
*
|
|
5314
|
-
* Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
|
|
5315
5423
|
*
|
|
5316
5424
|
* ## Access From Helpers
|
|
5317
5425
|
*
|
|
@@ -6850,8 +6958,9 @@ declare namespace CodeceptJS {
|
|
|
6850
6958
|
class REST {
|
|
6851
6959
|
/**
|
|
6852
6960
|
* Executes axios request
|
|
6961
|
+
* @returns response
|
|
6853
6962
|
*/
|
|
6854
|
-
_executeRequest(request: any):
|
|
6963
|
+
_executeRequest(request: any): Promise<any>;
|
|
6855
6964
|
/**
|
|
6856
6965
|
* Generates url based on format sent (takes endpoint + url if latter lacks 'http')
|
|
6857
6966
|
*/
|
|
@@ -6871,8 +6980,9 @@ declare namespace CodeceptJS {
|
|
|
6871
6980
|
* I.sendGetRequest('/api/users.json');
|
|
6872
6981
|
* ```
|
|
6873
6982
|
* @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
|
|
6983
|
+
* @returns response
|
|
6874
6984
|
*/
|
|
6875
|
-
sendGetRequest(url: any, headers?: any):
|
|
6985
|
+
sendGetRequest(url: any, headers?: any): Promise<any>;
|
|
6876
6986
|
/**
|
|
6877
6987
|
* Sends POST request to API.
|
|
6878
6988
|
*
|
|
@@ -6885,8 +6995,9 @@ declare namespace CodeceptJS {
|
|
|
6885
6995
|
* ```
|
|
6886
6996
|
* @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
|
|
6887
6997
|
* @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
|
|
6998
|
+
* @returns response
|
|
6888
6999
|
*/
|
|
6889
|
-
sendPostRequest(url: any, payload?: any, headers?: any):
|
|
7000
|
+
sendPostRequest(url: any, payload?: any, headers?: any): Promise<any>;
|
|
6890
7001
|
/**
|
|
6891
7002
|
* Sends PATCH request to API.
|
|
6892
7003
|
*
|
|
@@ -6899,8 +7010,9 @@ declare namespace CodeceptJS {
|
|
|
6899
7010
|
* ```
|
|
6900
7011
|
* @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
|
|
6901
7012
|
* @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
|
|
7013
|
+
* @returns response
|
|
6902
7014
|
*/
|
|
6903
|
-
sendPatchRequest(url: string, payload?: any, headers?: any):
|
|
7015
|
+
sendPatchRequest(url: string, payload?: any, headers?: any): Promise<any>;
|
|
6904
7016
|
/**
|
|
6905
7017
|
* Sends PUT request to API.
|
|
6906
7018
|
*
|
|
@@ -6913,8 +7025,9 @@ declare namespace CodeceptJS {
|
|
|
6913
7025
|
* ```
|
|
6914
7026
|
* @param [payload = {}] - the payload to be sent. By default it is sent as an empty object
|
|
6915
7027
|
* @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
|
|
7028
|
+
* @returns response
|
|
6916
7029
|
*/
|
|
6917
|
-
sendPutRequest(url: string, payload?: any, headers?: any):
|
|
7030
|
+
sendPutRequest(url: string, payload?: any, headers?: any): Promise<any>;
|
|
6918
7031
|
/**
|
|
6919
7032
|
* Sends DELETE request to API.
|
|
6920
7033
|
*
|
|
@@ -6922,8 +7035,9 @@ declare namespace CodeceptJS {
|
|
|
6922
7035
|
* I.sendDeleteRequest('/api/users/1');
|
|
6923
7036
|
* ```
|
|
6924
7037
|
* @param [headers = {}] - the headers object to be sent. By default it is sent as an empty object
|
|
7038
|
+
* @returns response
|
|
6925
7039
|
*/
|
|
6926
|
-
sendDeleteRequest(url: any, headers?: any):
|
|
7040
|
+
sendDeleteRequest(url: any, headers?: any): Promise<any>;
|
|
6927
7041
|
}
|
|
6928
7042
|
/**
|
|
6929
7043
|
* SeleniumWebdriver helper is based on the official [Selenium Webdriver JS](https://www.npmjs.com/package/selenium-webdriver)
|
|
@@ -8656,8 +8770,6 @@ declare namespace CodeceptJS {
|
|
|
8656
8770
|
* @param locator - element located by CSS|XPath|strict locator.
|
|
8657
8771
|
* @param attr - attribute name.
|
|
8658
8772
|
* @returns attribute value
|
|
8659
|
-
*
|
|
8660
|
-
* Appium: can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
|
|
8661
8773
|
*/
|
|
8662
8774
|
grabAttributeFromAll(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string[]>;
|
|
8663
8775
|
/**
|
|
@@ -8671,8 +8783,6 @@ declare namespace CodeceptJS {
|
|
|
8671
8783
|
* @param locator - element located by CSS|XPath|strict locator.
|
|
8672
8784
|
* @param attr - attribute name.
|
|
8673
8785
|
* @returns attribute value
|
|
8674
|
-
*
|
|
8675
|
-
* Appium: can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")
|
|
8676
8786
|
*/
|
|
8677
8787
|
grabAttributeFrom(locator: CodeceptJS.LocatorOrString, attr: string): Promise<string>;
|
|
8678
8788
|
/**
|
|
@@ -9695,7 +9805,7 @@ declare namespace CodeceptJS {
|
|
|
9695
9805
|
* add print comment method`
|
|
9696
9806
|
*/
|
|
9697
9807
|
say(msg: string, color?: string): Promise<any> | undefined;
|
|
9698
|
-
retry(opts
|
|
9808
|
+
retry(opts?: any): this;
|
|
9699
9809
|
}
|
|
9700
9810
|
/**
|
|
9701
9811
|
* Create CodeceptJS runner.
|
|
@@ -9839,6 +9949,34 @@ declare namespace CodeceptJS {
|
|
|
9839
9949
|
xadd(array: any[]): void;
|
|
9840
9950
|
filter(func: (...params: any[]) => any): void;
|
|
9841
9951
|
}
|
|
9952
|
+
/**
|
|
9953
|
+
* DataTableArgument class to store the Cucumber data table from
|
|
9954
|
+
* a step as an object with methods that can be used to access the data.
|
|
9955
|
+
*/
|
|
9956
|
+
class DataTableArgument {
|
|
9957
|
+
constructor(gherkinDataTable: any);
|
|
9958
|
+
/**
|
|
9959
|
+
* Returns the table as a 2-D array
|
|
9960
|
+
*/
|
|
9961
|
+
raw(): string[][];
|
|
9962
|
+
/**
|
|
9963
|
+
* Returns the table as a 2-D array, without the first row
|
|
9964
|
+
*/
|
|
9965
|
+
rows(): string[][];
|
|
9966
|
+
/**
|
|
9967
|
+
* Returns an array of objects where each row is converted to an object (column header is the key)
|
|
9968
|
+
*/
|
|
9969
|
+
hashes(): any[];
|
|
9970
|
+
/**
|
|
9971
|
+
* Returns an object where each row corresponds to an entry
|
|
9972
|
+
* (first column is the key, second column is the value)
|
|
9973
|
+
*/
|
|
9974
|
+
rowsHash(): Record<string, string>;
|
|
9975
|
+
/**
|
|
9976
|
+
* Transposed the data
|
|
9977
|
+
*/
|
|
9978
|
+
transpose(): void;
|
|
9979
|
+
}
|
|
9842
9980
|
namespace event {
|
|
9843
9981
|
const dispatcher: NodeJS.EventEmitter;
|
|
9844
9982
|
const test: {
|
|
@@ -9935,6 +10073,7 @@ declare namespace CodeceptJS {
|
|
|
9935
10073
|
var pause: typeof CodeceptJS.pause;
|
|
9936
10074
|
var within: typeof CodeceptJS.within;
|
|
9937
10075
|
var dataTable: typeof CodeceptJS.DataTable;
|
|
10076
|
+
var dataTableArgument: typeof CodeceptJS.DataTableArgument;
|
|
9938
10077
|
var store: typeof CodeceptJS.store;
|
|
9939
10078
|
var locator: typeof CodeceptJS.Locator;
|
|
9940
10079
|
}
|
|
@@ -10020,6 +10159,7 @@ declare namespace CodeceptJS {
|
|
|
10020
10159
|
isCustom(): boolean;
|
|
10021
10160
|
isStrict(): boolean;
|
|
10022
10161
|
isAccessibilityId(): boolean;
|
|
10162
|
+
isBasic(): boolean;
|
|
10023
10163
|
toXPath(): string;
|
|
10024
10164
|
or(locator: CodeceptJS.LocatorOrString): Locator;
|
|
10025
10165
|
find(locator: CodeceptJS.LocatorOrString): Locator;
|