codeceptjs 3.3.8-beta.1 → 3.4.0
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 +47 -0
- package/README.md +31 -32
- package/docs/advanced.md +48 -24
- package/docs/basics.md +115 -40
- package/docs/best.md +2 -2
- package/docs/build/ApiDataFactory.js +14 -9
- package/docs/build/Appium.js +2 -19
- package/docs/build/FileSystem.js +3 -3
- package/docs/build/GraphQL.js +1 -1
- package/docs/build/GraphQLDataFactory.js +3 -3
- package/docs/build/JSONResponse.js +1 -1
- package/docs/build/Mochawesome.js +1 -1
- package/docs/build/Nightmare.js +1 -1
- package/docs/build/Playwright.js +4 -3
- package/docs/build/Protractor.js +1 -1
- package/docs/build/Puppeteer.js +1 -1
- package/docs/build/REST.js +1 -1
- package/docs/build/TestCafe.js +5 -5
- package/docs/build/WebDriver.js +30 -165
- package/docs/changelog.md +49 -2
- package/docs/helpers/ApiDataFactory.md +6 -6
- package/docs/helpers/FileSystem.md +2 -2
- package/docs/helpers/GraphQLDataFactory.md +2 -2
- package/docs/helpers/Playwright.md +2 -1
- package/docs/index.md +1 -1
- package/docs/plugins.md +42 -125
- package/docs/reports.md +0 -56
- package/docs/tutorial.md +271 -0
- package/docs/typescript.md +2 -8
- package/lib/actor.js +2 -1
- package/lib/cli.js +3 -3
- package/lib/codecept.js +2 -1
- package/lib/command/generate.js +3 -1
- package/lib/command/gherkin/snippets.js +8 -4
- package/lib/command/init.js +0 -8
- package/lib/command/run-workers.js +3 -6
- package/lib/command/utils.js +0 -10
- package/lib/command/workers/runTests.js +2 -2
- package/lib/config.js +5 -1
- package/lib/helper/ApiDataFactory.js +14 -9
- package/lib/helper/Appium.js +2 -19
- package/lib/helper/FileSystem.js +3 -3
- package/lib/helper/GraphQL.js +1 -1
- package/lib/helper/GraphQLDataFactory.js +3 -3
- package/lib/helper/JSONResponse.js +1 -1
- package/lib/helper/Mochawesome.js +1 -1
- package/lib/helper/Nightmare.js +1 -1
- package/lib/helper/Playwright.js +4 -3
- package/lib/helper/Protractor.js +1 -1
- package/lib/helper/Puppeteer.js +1 -1
- package/lib/helper/REST.js +1 -1
- package/lib/helper/TestCafe.js +5 -5
- package/lib/helper/WebDriver.js +30 -165
- package/lib/helper.js +0 -2
- package/lib/interfaces/bdd.js +1 -1
- package/lib/interfaces/featureConfig.js +1 -0
- package/lib/interfaces/gherkin.js +38 -25
- package/lib/listener/exit.js +2 -2
- package/lib/listener/retry.js +67 -0
- package/lib/listener/steps.js +1 -1
- package/lib/listener/timeout.js +47 -10
- package/lib/mochaFactory.js +3 -3
- package/lib/plugin/allure.js +14 -323
- package/lib/plugin/fakerTransform.js +2 -2
- package/lib/recorder.js +1 -1
- package/lib/scenario.js +25 -18
- package/lib/utils.js +6 -0
- package/lib/workers.js +4 -7
- package/package.json +14 -18
- package/typings/index.d.ts +76 -1
- package/typings/promiseBasedTypes.d.ts +12 -12
- package/typings/types.d.ts +95 -262
package/lib/cli.js
CHANGED
|
@@ -40,7 +40,7 @@ class Cli extends Base {
|
|
|
40
40
|
|
|
41
41
|
runner.on('fail', (test) => {
|
|
42
42
|
if (test.ctx.currentTest) {
|
|
43
|
-
this.loadedTests.push(test.ctx.currentTest.
|
|
43
|
+
this.loadedTests.push(test.ctx.currentTest.uid);
|
|
44
44
|
}
|
|
45
45
|
if (showSteps && test.steps) {
|
|
46
46
|
return output.scenario.failed(test);
|
|
@@ -57,7 +57,7 @@ class Cli extends Base {
|
|
|
57
57
|
} else {
|
|
58
58
|
skipTestConfig(test, null);
|
|
59
59
|
}
|
|
60
|
-
this.loadedTests.push(test.
|
|
60
|
+
this.loadedTests.push(test.uid);
|
|
61
61
|
cursor.CR();
|
|
62
62
|
output.test.skipped(test);
|
|
63
63
|
});
|
|
@@ -111,7 +111,7 @@ class Cli extends Base {
|
|
|
111
111
|
let skippedCount = 0;
|
|
112
112
|
const grep = runner._grep;
|
|
113
113
|
for (const test of suite.tests) {
|
|
114
|
-
if (!test.state && !this.loadedTests.includes(test.
|
|
114
|
+
if (!test.state && !this.loadedTests.includes(test.uid)) {
|
|
115
115
|
if (matchTest(grep, test.title)) {
|
|
116
116
|
if (!test.opts) {
|
|
117
117
|
test.opts = {};
|
package/lib/codecept.js
CHANGED
|
@@ -67,8 +67,8 @@ class Codecept {
|
|
|
67
67
|
global.output_dir = fsPath.resolve(dir, this.config.output);
|
|
68
68
|
|
|
69
69
|
if (!this.config.noGlobals) {
|
|
70
|
+
global.Helper = global.codecept_helper = require('@codeceptjs/helper');
|
|
70
71
|
global.actor = global.codecept_actor = require('./actor');
|
|
71
|
-
global.Helper = global.codecept_helper = require('./helper');
|
|
72
72
|
global.pause = require('./pause');
|
|
73
73
|
global.within = require('./within');
|
|
74
74
|
global.session = require('./session');
|
|
@@ -98,6 +98,7 @@ class Codecept {
|
|
|
98
98
|
runHook(require('./listener/artifacts'));
|
|
99
99
|
runHook(require('./listener/config'));
|
|
100
100
|
runHook(require('./listener/helpers'));
|
|
101
|
+
runHook(require('./listener/retry'));
|
|
101
102
|
runHook(require('./listener/timeout'));
|
|
102
103
|
runHook(require('./listener/exit'));
|
|
103
104
|
|
package/lib/command/generate.js
CHANGED
|
@@ -128,7 +128,9 @@ module.exports.pageObject = function (genPath, opts) {
|
|
|
128
128
|
const name = lcfirst(result.name) + ucfirst(kind);
|
|
129
129
|
let data = readConfig(configFile);
|
|
130
130
|
config.include[name] = result.filename;
|
|
131
|
-
|
|
131
|
+
const currentInclude = `${data.match(/include:[\s\S][^\}]*/i)[0]}\n ${name}:${JSON.stringify(config.include[name])}`;
|
|
132
|
+
|
|
133
|
+
data = data.replace(/include:[\s\S][^\}]*/i, `${currentInclude}`);
|
|
132
134
|
|
|
133
135
|
fs.writeFileSync(configFile, beautify(data), 'utf-8');
|
|
134
136
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const escapeStringRegexp = require('escape-string-regexp');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
const
|
|
3
|
+
const Gherkin = require('@cucumber/gherkin');
|
|
4
|
+
const Messages = require('@cucumber/messages');
|
|
4
5
|
const glob = require('glob');
|
|
5
6
|
const fsPath = require('path');
|
|
6
7
|
|
|
@@ -9,7 +10,10 @@ const Codecept = require('../../codecept');
|
|
|
9
10
|
const output = require('../../output');
|
|
10
11
|
const { matchStep } = require('../../interfaces/bdd');
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
+
const uuidFn = Messages.IdGenerator.uuid();
|
|
14
|
+
const builder = new Gherkin.AstBuilder(uuidFn);
|
|
15
|
+
const matcher = new Gherkin.GherkinClassicTokenMatcher();
|
|
16
|
+
const parser = new Gherkin.Parser(builder, matcher);
|
|
13
17
|
parser.stopAtFirstError = false;
|
|
14
18
|
|
|
15
19
|
module.exports = function (genPath, options) {
|
|
@@ -85,8 +89,8 @@ module.exports = function (genPath, options) {
|
|
|
85
89
|
const parseFile = (file) => {
|
|
86
90
|
const ast = parser.parse(fs.readFileSync(file).toString());
|
|
87
91
|
for (const child of ast.feature.children) {
|
|
88
|
-
if (child.
|
|
89
|
-
parseSteps(child.steps).map((step) => {
|
|
92
|
+
if (child.scenario.keyword === 'Scenario Outline') continue; // skip scenario outline
|
|
93
|
+
parseSteps(child.scenario.steps).map((step) => {
|
|
90
94
|
return Object.assign(step, { file: file.replace(global.codecept_dir, '').slice(1) });
|
|
91
95
|
}).map((step) => newSteps.set(`${step.type}(${step})`, step));
|
|
92
96
|
}
|
package/lib/command/init.js
CHANGED
|
@@ -126,13 +126,6 @@ module.exports = function (initPath) {
|
|
|
126
126
|
default: './output',
|
|
127
127
|
message: 'Where should logs, screenshots, and reports to be stored?',
|
|
128
128
|
},
|
|
129
|
-
{
|
|
130
|
-
name: 'promise',
|
|
131
|
-
type: 'confirm',
|
|
132
|
-
default: false,
|
|
133
|
-
message: 'Would you prefer to use promise-based typings for all I.* commands? http://bit.ly/3XIMq6n',
|
|
134
|
-
when: (answers) => answers.typescript,
|
|
135
|
-
},
|
|
136
129
|
{
|
|
137
130
|
name: 'translation',
|
|
138
131
|
type: 'list',
|
|
@@ -155,7 +148,6 @@ module.exports = function (initPath) {
|
|
|
155
148
|
config.tests = result.tests;
|
|
156
149
|
if (isTypeScript) {
|
|
157
150
|
config.tests = `${config.tests.replace(/\.js$/, `.${extension}`)}`;
|
|
158
|
-
config.fullPromiseBased = result.promise;
|
|
159
151
|
}
|
|
160
152
|
|
|
161
153
|
// create a directory tests if it is included in tests path
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
// For Node version >=10.5.0, have to use experimental flag
|
|
2
|
-
const { satisfyNodeVersion } = require('./utils');
|
|
3
2
|
const { tryOrDefault } = require('../utils');
|
|
4
3
|
const output = require('../output');
|
|
5
4
|
const event = require('../event');
|
|
6
5
|
const Workers = require('../workers');
|
|
7
6
|
|
|
8
7
|
module.exports = async function (workerCount, options) {
|
|
9
|
-
satisfyNodeVersion(
|
|
10
|
-
'>=11.7.0',
|
|
11
|
-
'Required minimum Node version of 11.7.0 to work with "run-workers"',
|
|
12
|
-
);
|
|
13
|
-
|
|
14
8
|
process.env.profile = options.profile;
|
|
15
9
|
|
|
16
10
|
const { config: testConfig, override = '' } = options;
|
|
@@ -46,6 +40,9 @@ module.exports = async function (workerCount, options) {
|
|
|
46
40
|
try {
|
|
47
41
|
await workers.bootstrapAll();
|
|
48
42
|
await workers.run();
|
|
43
|
+
} catch (err) {
|
|
44
|
+
output.error(err);
|
|
45
|
+
process.exit(1);
|
|
49
46
|
} finally {
|
|
50
47
|
await workers.teardownAll();
|
|
51
48
|
}
|
package/lib/command/utils.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
|
-
const semver = require('semver');
|
|
4
3
|
const util = require('util');
|
|
5
4
|
const mkdirp = require('mkdirp');
|
|
6
5
|
|
|
@@ -71,15 +70,6 @@ function safeFileWrite(file, contents) {
|
|
|
71
70
|
|
|
72
71
|
module.exports.safeFileWrite = safeFileWrite;
|
|
73
72
|
|
|
74
|
-
module.exports.satisfyNodeVersion = (
|
|
75
|
-
version,
|
|
76
|
-
failureMessage = `Required Node version: ${version}`,
|
|
77
|
-
) => {
|
|
78
|
-
if (!semver.satisfies(process.version, version)) {
|
|
79
|
-
fail(failureMessage);
|
|
80
|
-
}
|
|
81
|
-
};
|
|
82
|
-
|
|
83
73
|
module.exports.captureStream = (stream) => {
|
|
84
74
|
let oldStream;
|
|
85
75
|
let buffer = '';
|
|
@@ -68,7 +68,7 @@ function filterTests() {
|
|
|
68
68
|
mocha.loadFiles();
|
|
69
69
|
|
|
70
70
|
for (const suite of mocha.suite.suites) {
|
|
71
|
-
suite.tests = suite.tests.filter(test => tests.indexOf(test.
|
|
71
|
+
suite.tests = suite.tests.filter(test => tests.indexOf(test.uid) >= 0);
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
@@ -124,7 +124,7 @@ function initializeListeners() {
|
|
|
124
124
|
return {
|
|
125
125
|
opts: test.opts || {},
|
|
126
126
|
tags: test.tags || [],
|
|
127
|
-
|
|
127
|
+
uid: test.uid,
|
|
128
128
|
workerIndex,
|
|
129
129
|
retries: test._retries,
|
|
130
130
|
title: test.title,
|
package/lib/config.js
CHANGED
|
@@ -79,7 +79,11 @@ class Config {
|
|
|
79
79
|
configFile = path.resolve(configFile || '.');
|
|
80
80
|
|
|
81
81
|
if (!fileExists(configFile)) {
|
|
82
|
-
|
|
82
|
+
configFile = configFile.replace('.js', '.ts');
|
|
83
|
+
|
|
84
|
+
if (!fileExists(configFile)) {
|
|
85
|
+
throw new Error(`Config file ${configFile} does not exist. Execute 'codeceptjs init' to create config`);
|
|
86
|
+
}
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
// is config file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
|
|
3
|
-
const Helper = require('
|
|
3
|
+
const Helper = require('@codeceptjs/helper');
|
|
4
4
|
const REST = require('./REST');
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -46,8 +46,8 @@ const REST = require('./REST');
|
|
|
46
46
|
* ```js
|
|
47
47
|
* // tests/factories/posts.js
|
|
48
48
|
*
|
|
49
|
-
* const Factory = require('rosie')
|
|
50
|
-
* const faker = require('@faker-js/faker');
|
|
49
|
+
* const { Factory } = require('rosie');
|
|
50
|
+
* const { faker } = require('@faker-js/faker');
|
|
51
51
|
*
|
|
52
52
|
* module.exports = new Factory()
|
|
53
53
|
* // no need to set id, it will be set by REST API
|
|
@@ -230,7 +230,7 @@ class ApiDataFactory extends Helper {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
_after() {
|
|
233
|
-
if (!this.config.cleanup) {
|
|
233
|
+
if (!this.config.cleanup || this.config.cleanup === false) {
|
|
234
234
|
return Promise.resolve();
|
|
235
235
|
}
|
|
236
236
|
const promises = [];
|
|
@@ -244,7 +244,6 @@ class ApiDataFactory extends Helper {
|
|
|
244
244
|
promises.push(this._requestDelete(factoryName, createdItems[id]));
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
|
|
248
247
|
return Promise.all(promises);
|
|
249
248
|
}
|
|
250
249
|
|
|
@@ -262,8 +261,8 @@ class ApiDataFactory extends Helper {
|
|
|
262
261
|
* ```
|
|
263
262
|
*
|
|
264
263
|
* @param {*} factory factory to use
|
|
265
|
-
* @param {*} params predefined parameters
|
|
266
|
-
* @param {*} options options for programmatically generate the attributes
|
|
264
|
+
* @param {*} [params] predefined parameters
|
|
265
|
+
* @param {*} [options] options for programmatically generate the attributes
|
|
267
266
|
* @returns {Promise<*>}
|
|
268
267
|
*/
|
|
269
268
|
have(factory, params, options) {
|
|
@@ -288,8 +287,8 @@ class ApiDataFactory extends Helper {
|
|
|
288
287
|
*
|
|
289
288
|
* @param {*} factory
|
|
290
289
|
* @param {*} times
|
|
291
|
-
* @param {*} params
|
|
292
|
-
* @param {*} options
|
|
290
|
+
* @param {*} [params]
|
|
291
|
+
* @param {*} [options]
|
|
293
292
|
*/
|
|
294
293
|
haveMultiple(factory, times, params, options) {
|
|
295
294
|
const promises = [];
|
|
@@ -379,7 +378,9 @@ Current file error: ${err.message}`);
|
|
|
379
378
|
|
|
380
379
|
if (!request) {
|
|
381
380
|
const method = Object.keys(this.factories[factory].delete)[0];
|
|
381
|
+
|
|
382
382
|
const url = this.factories[factory].delete[method].replace('{id}', id);
|
|
383
|
+
|
|
383
384
|
request = {
|
|
384
385
|
method,
|
|
385
386
|
url,
|
|
@@ -388,6 +389,10 @@ Current file error: ${err.message}`);
|
|
|
388
389
|
|
|
389
390
|
request.baseURL = this.config.endpoint;
|
|
390
391
|
|
|
392
|
+
if (request.url.match(/^undefined/)) {
|
|
393
|
+
return this.debugSection('Please configure the delete request in your ApiDataFactory helper', 'delete: () => ({ method: \'DELETE\', url: \'/api/users\' })');
|
|
394
|
+
}
|
|
395
|
+
|
|
391
396
|
return this.restHelper._executeRequest(request).then(() => {
|
|
392
397
|
const idx = this.created[factory].indexOf(id);
|
|
393
398
|
this.debugSection('Deleted Id', `Id: ${id}`);
|
package/lib/helper/Appium.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
let webdriverio;
|
|
2
|
-
let wdioV4;
|
|
3
2
|
|
|
4
3
|
const fs = require('fs');
|
|
5
4
|
const axios = require('axios').default;
|
|
@@ -131,6 +130,7 @@ class Appium extends Webdriver {
|
|
|
131
130
|
* @augments WebDriver
|
|
132
131
|
*/
|
|
133
132
|
|
|
133
|
+
// @ts-ignore
|
|
134
134
|
constructor(config) {
|
|
135
135
|
super(config);
|
|
136
136
|
|
|
@@ -138,7 +138,6 @@ class Appium extends Webdriver {
|
|
|
138
138
|
this.axios = axios.create();
|
|
139
139
|
|
|
140
140
|
webdriverio = require('webdriverio');
|
|
141
|
-
(!webdriverio.VERSION || webdriverio.VERSION.indexOf('4') !== 0) ? wdioV4 = false : wdioV4 = true;
|
|
142
141
|
}
|
|
143
142
|
|
|
144
143
|
_validateConfig(config) {
|
|
@@ -516,10 +515,6 @@ class Appium extends Webdriver {
|
|
|
516
515
|
async removeApp(appId, bundleId) {
|
|
517
516
|
onlyForApps.call(this, supportedPlatform.android);
|
|
518
517
|
|
|
519
|
-
if (wdioV4) {
|
|
520
|
-
return this.browser.removeApp(bundleId);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
518
|
return this.axios({
|
|
524
519
|
method: 'post',
|
|
525
520
|
url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/appium/device/remove_app`,
|
|
@@ -610,19 +605,13 @@ class Appium extends Webdriver {
|
|
|
610
605
|
*/
|
|
611
606
|
async seeOrientationIs(orientation) {
|
|
612
607
|
onlyForApps.call(this);
|
|
613
|
-
let currentOrientation;
|
|
614
|
-
|
|
615
|
-
if (wdioV4) {
|
|
616
|
-
const res = await this.browser.orientation();
|
|
617
|
-
currentOrientation = res;
|
|
618
|
-
}
|
|
619
608
|
|
|
620
609
|
const res = await this.axios({
|
|
621
610
|
method: 'get',
|
|
622
611
|
url: `${this._buildAppiumEndpoint()}/session/${this.browser.sessionId}/orientation`,
|
|
623
612
|
});
|
|
624
613
|
|
|
625
|
-
currentOrientation = res.data.value;
|
|
614
|
+
const currentOrientation = res.data.value;
|
|
626
615
|
return truth('orientation', `to be ${orientation}`).assert(currentOrientation === orientation);
|
|
627
616
|
}
|
|
628
617
|
|
|
@@ -640,9 +629,6 @@ class Appium extends Webdriver {
|
|
|
640
629
|
*/
|
|
641
630
|
async setOrientation(orientation) {
|
|
642
631
|
onlyForApps.call(this);
|
|
643
|
-
if (wdioV4) {
|
|
644
|
-
return this.browser.setOrientation(orientation);
|
|
645
|
-
}
|
|
646
632
|
|
|
647
633
|
return this.axios({
|
|
648
634
|
method: 'post',
|
|
@@ -916,9 +902,6 @@ class Appium extends Webdriver {
|
|
|
916
902
|
*/
|
|
917
903
|
async sendDeviceKeyEvent(keyValue) {
|
|
918
904
|
onlyForApps.call(this, supportedPlatform.android);
|
|
919
|
-
if (wdioV4) {
|
|
920
|
-
return this.browser.sendKeyEvent(keyValue);
|
|
921
|
-
}
|
|
922
905
|
return this.browser.pressKeyCode(keyValue);
|
|
923
906
|
}
|
|
924
907
|
|
package/lib/helper/FileSystem.js
CHANGED
|
@@ -2,7 +2,7 @@ const assert = require('assert');
|
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
|
-
const Helper = require('
|
|
5
|
+
const Helper = require('@codeceptjs/helper');
|
|
6
6
|
const { fileExists } = require('../utils');
|
|
7
7
|
const { fileIncludes } = require('../assert/include');
|
|
8
8
|
const { fileEquals } = require('../assert/equal');
|
|
@@ -71,10 +71,10 @@ class FileSystem extends Helper {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
/**
|
|
74
|
-
* Waits for file to be present in current directory.
|
|
74
|
+
* Waits for the file to be present in the current directory.
|
|
75
75
|
*
|
|
76
76
|
* ```js
|
|
77
|
-
* I.handleDownloads();
|
|
77
|
+
* I.handleDownloads('downloads/largeFilesName.txt');
|
|
78
78
|
* I.click('Download large File');
|
|
79
79
|
* I.amInPath('output/downloads');
|
|
80
80
|
* I.waitForFile('largeFilesName.txt', 10); // wait 10 seconds for file
|
package/lib/helper/GraphQL.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
|
|
3
|
-
const Helper = require('
|
|
3
|
+
const Helper = require('@codeceptjs/helper');
|
|
4
4
|
const GraphQL = require('./GraphQL');
|
|
5
5
|
|
|
6
6
|
/**
|
|
@@ -46,8 +46,8 @@ const GraphQL = require('./GraphQL');
|
|
|
46
46
|
* ```js
|
|
47
47
|
* // tests/factories/users.js
|
|
48
48
|
*
|
|
49
|
-
* const Factory = require('rosie').Factory;
|
|
50
|
-
* const faker = require('@faker-js/faker');
|
|
49
|
+
* const { Factory } = require('rosie').Factory;
|
|
50
|
+
* const { faker } = require('@faker-js/faker');
|
|
51
51
|
*
|
|
52
52
|
* // Used with a constructor function passed to Factory, so that the final build
|
|
53
53
|
* // object matches the necessary pattern to be sent as the variables object.
|
package/lib/helper/Nightmare.js
CHANGED
|
@@ -2,7 +2,7 @@ const path = require('path');
|
|
|
2
2
|
|
|
3
3
|
const urlResolve = require('url').resolve;
|
|
4
4
|
|
|
5
|
-
const Helper = require('
|
|
5
|
+
const Helper = require('@codeceptjs/helper');
|
|
6
6
|
const { includes: stringIncludes } = require('../assert/include');
|
|
7
7
|
const { urlEquals } = require('../assert/equal');
|
|
8
8
|
const { equals } = require('../assert/equal');
|
package/lib/helper/Playwright.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
|
|
4
|
-
const Helper = require('
|
|
4
|
+
const Helper = require('@codeceptjs/helper');
|
|
5
5
|
const Locator = require('../locator');
|
|
6
6
|
const recorder = require('../recorder');
|
|
7
7
|
const stringIncludes = require('../assert/include').includes;
|
|
@@ -66,6 +66,7 @@ const pathSeparator = path.sep;
|
|
|
66
66
|
* @prop {boolean} [video=false] - enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
67
67
|
* @prop {boolean} [keepVideoForPassedTests=false] - save videos for passed tests; videos are saved into `output/videos` folder
|
|
68
68
|
* @prop {boolean} [trace=false] - record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
|
|
69
|
+
* @prop {boolean} [keepTraceForPassedTests=false] - save trace for passed tests.
|
|
69
70
|
* @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
|
|
70
71
|
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
71
72
|
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to 'session'.
|
|
@@ -1259,7 +1260,7 @@ class Playwright extends Helper {
|
|
|
1259
1260
|
*
|
|
1260
1261
|
* ```
|
|
1261
1262
|
*
|
|
1262
|
-
* @param {string}
|
|
1263
|
+
* @param {string} fileName set filename for downloaded file
|
|
1263
1264
|
* @return {Promise<void>}
|
|
1264
1265
|
*/
|
|
1265
1266
|
async handleDownloads(fileName) {
|
|
@@ -2981,7 +2982,7 @@ async function refreshContextSession() {
|
|
|
2981
2982
|
|
|
2982
2983
|
async function saveVideoForPage(page, name) {
|
|
2983
2984
|
if (!page.video()) return null;
|
|
2984
|
-
const fileName = `${global.output_dir}${pathSeparator}videos${pathSeparator}${Date.now()}_${clearString(name)
|
|
2985
|
+
const fileName = `${`${global.output_dir}${pathSeparator}videos${pathSeparator}${Date.now()}_${clearString(name)}`.slice(0, 245)}.webm`;
|
|
2985
2986
|
page.video().saveAs(fileName).then(() => {
|
|
2986
2987
|
if (!page) return;
|
|
2987
2988
|
page.video().delete().catch(e => {});
|
package/lib/helper/Protractor.js
CHANGED
|
@@ -6,7 +6,7 @@ let ProtractorExpectedConditions;
|
|
|
6
6
|
|
|
7
7
|
const path = require('path');
|
|
8
8
|
|
|
9
|
-
const Helper = require('
|
|
9
|
+
const Helper = require('@codeceptjs/helper');
|
|
10
10
|
const stringIncludes = require('../assert/include').includes;
|
|
11
11
|
const { urlEquals, equals } = require('../assert/equal');
|
|
12
12
|
const { empty } = require('../assert/empty');
|
package/lib/helper/Puppeteer.js
CHANGED
|
@@ -3,7 +3,7 @@ const fs = require('fs');
|
|
|
3
3
|
const fsExtra = require('fs-extra');
|
|
4
4
|
const path = require('path');
|
|
5
5
|
|
|
6
|
-
const Helper = require('
|
|
6
|
+
const Helper = require('@codeceptjs/helper');
|
|
7
7
|
const Locator = require('../locator');
|
|
8
8
|
const recorder = require('../recorder');
|
|
9
9
|
const stringIncludes = require('../assert/include').includes;
|
package/lib/helper/REST.js
CHANGED
package/lib/helper/TestCafe.js
CHANGED
|
@@ -6,6 +6,7 @@ const qrcode = require('qrcode-terminal');
|
|
|
6
6
|
const createTestCafe = require('testcafe');
|
|
7
7
|
const { Selector, ClientFunction } = require('testcafe');
|
|
8
8
|
|
|
9
|
+
const Helper = require('@codeceptjs/helper');
|
|
9
10
|
const ElementNotFound = require('./errors/ElementNotFound');
|
|
10
11
|
const testControllerHolder = require('./testcafe/testControllerHolder');
|
|
11
12
|
const {
|
|
@@ -22,7 +23,6 @@ const {
|
|
|
22
23
|
xpathLocator,
|
|
23
24
|
} = require('../utils');
|
|
24
25
|
const Locator = require('../locator');
|
|
25
|
-
const Helper = require('../helper');
|
|
26
26
|
|
|
27
27
|
/**
|
|
28
28
|
* Client Functions
|
|
@@ -545,8 +545,8 @@ class TestCafe extends Helper {
|
|
|
545
545
|
|
|
546
546
|
// TODO As far as I understand the testcafe docs this should do a multi-select
|
|
547
547
|
// but it does not work
|
|
548
|
-
const clickOpts = { ctrl: option.length > 1 };
|
|
549
|
-
await this.t.click(el
|
|
548
|
+
// const clickOpts = { ctrl: option.length > 1 };
|
|
549
|
+
await this.t.click(el).catch(mapError);
|
|
550
550
|
|
|
551
551
|
for (const key of option) {
|
|
552
552
|
const opt = key;
|
|
@@ -555,7 +555,7 @@ class TestCafe extends Helper {
|
|
|
555
555
|
try {
|
|
556
556
|
optEl = el.child('option').withText(opt);
|
|
557
557
|
if (await optEl.count) {
|
|
558
|
-
await this.t.click(optEl
|
|
558
|
+
await this.t.click(optEl).catch(mapError);
|
|
559
559
|
continue;
|
|
560
560
|
}
|
|
561
561
|
// eslint-disable-next-line no-empty
|
|
@@ -566,7 +566,7 @@ class TestCafe extends Helper {
|
|
|
566
566
|
const sel = `[value="${opt}"]`;
|
|
567
567
|
optEl = el.find(sel);
|
|
568
568
|
if (await optEl.count) {
|
|
569
|
-
await this.t.click(optEl
|
|
569
|
+
await this.t.click(optEl).catch(mapError);
|
|
570
570
|
}
|
|
571
571
|
// eslint-disable-next-line no-empty
|
|
572
572
|
} catch (err) {
|