codeceptjs 2.4.3 → 2.6.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 +117 -0
- package/README.md +32 -7
- package/bin/codecept.js +3 -0
- package/docs/basics.md +11 -5
- package/docs/bdd.md +4 -4
- package/docs/build/MockRequest.js +3 -0
- package/docs/build/Nightmare.js +10 -2
- package/docs/build/Playwright.js +3187 -0
- package/docs/build/Protractor.js +16 -2
- package/docs/build/Puppeteer.js +126 -19
- package/docs/build/REST.js +3 -1
- package/docs/build/TestCafe.js +11 -3
- package/docs/build/WebDriver.js +361 -28
- package/docs/changelog.md +116 -0
- package/docs/configuration.md +2 -2
- package/docs/custom-helpers.md +55 -10
- package/docs/helpers/Appium.md +81 -1
- package/docs/helpers/MockRequest.md +281 -38
- package/docs/helpers/Nightmare.md +10 -2
- package/docs/helpers/Playwright.md +1770 -0
- package/docs/helpers/Protractor.md +15 -3
- package/docs/helpers/Puppeteer-firefox.md +32 -1
- package/docs/helpers/Puppeteer.md +126 -76
- package/docs/helpers/TestCafe.md +10 -2
- package/docs/helpers/WebDriver.md +208 -118
- package/docs/locators.md +2 -0
- package/docs/playwright.md +306 -0
- package/docs/plugins.md +103 -0
- package/docs/reports.md +12 -0
- package/docs/shadow.md +68 -0
- package/docs/visual.md +0 -73
- package/docs/webapi/forceClick.mustache +27 -0
- package/docs/webapi/seeInPopup.mustache +7 -0
- package/docs/webapi/setCookie.mustache +10 -2
- package/docs/webapi/type.mustache +12 -0
- package/docs/webdriver.md +7 -3
- package/lib/codecept.js +1 -1
- package/lib/command/definitions.js +2 -2
- package/lib/command/generate.js +4 -4
- package/lib/command/gherkin/snippets.js +4 -4
- package/lib/command/init.js +1 -1
- package/lib/command/interactive.js +3 -0
- package/lib/command/run-multiple.js +2 -2
- package/lib/command/run-rerun.js +2 -0
- package/lib/command/run-workers.js +22 -8
- package/lib/command/run.js +2 -0
- package/lib/command/workers/runTests.js +1 -0
- package/lib/container.js +1 -1
- package/lib/event.js +2 -0
- package/lib/helper/MockRequest.js +3 -0
- package/lib/helper/Playwright.js +2422 -0
- package/lib/helper/Protractor.js +1 -2
- package/lib/helper/Puppeteer.js +84 -19
- package/lib/helper/REST.js +3 -1
- package/lib/helper/TestCafe.js +1 -1
- package/lib/helper/WebDriver.js +313 -26
- package/lib/helper/extras/PlaywrightPropEngine.js +53 -0
- package/lib/helper/scripts/isElementClickable.js +54 -14
- package/lib/interfaces/gherkin.js +1 -1
- package/lib/listener/helpers.js +3 -0
- package/lib/locator.js +5 -0
- package/lib/mochaFactory.js +12 -10
- package/lib/plugin/allure.js +8 -1
- package/lib/plugin/autoDelay.js +1 -8
- package/lib/plugin/commentStep.js +133 -0
- package/lib/plugin/screenshotOnFail.js +3 -10
- package/lib/plugin/selenoid.js +2 -2
- package/lib/plugin/standardActingHelpers.js +13 -0
- package/lib/plugin/stepByStepReport.js +1 -8
- package/lib/plugin/wdio.js +10 -1
- package/lib/reporter/cli.js +30 -1
- package/lib/session.js +7 -4
- package/package.json +13 -10
- package/typings/Mocha.d.ts +567 -16
- package/typings/index.d.ts +9 -5
- package/typings/types.d.ts +1634 -74
package/docs/webdriver.md
CHANGED
|
@@ -53,6 +53,8 @@ exports.config = {
|
|
|
53
53
|
}
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
> ⚠ It is not recommended to use wdio plugin & selenium-standalone when running tests in parallel. Consider **switching to Selenoid** if you need parallel run or using cloud services.
|
|
57
|
+
|
|
56
58
|
|
|
57
59
|
## Configuring WebDriver
|
|
58
60
|
|
|
@@ -104,7 +106,7 @@ path: '/',
|
|
|
104
106
|
|
|
105
107
|
> If you face issues connecting to WebDriver, please check that corresponding server is running on a specified port. If host is other than `localhost` or port is other than `4444`, update the configuration.
|
|
106
108
|
|
|
107
|
-
### Selenium in Docker
|
|
109
|
+
### Selenium in Docker (Selenoid)
|
|
108
110
|
|
|
109
111
|
Browsers can be executed in Docker containers. This is useful when testing on Continous Integration server.
|
|
110
112
|
We recommend using [Selenoid](https://aerokube.com/selenoid/) to run browsers in container.
|
|
@@ -204,7 +206,7 @@ Scenario('login test', (I) => {
|
|
|
204
206
|
> ▶ Actions like `amOnPage`, `click`, `fillField` are not limited to WebDriver only. They work similarly for all available helpers. [Go to Basics guide to learn them](/basics#writing-tests).
|
|
205
207
|
|
|
206
208
|
|
|
207
|
-
An empty test case can be created with `codeceptjs gt` command.
|
|
209
|
+
An empty test case can be created with `npx codeceptjs gt` command.
|
|
208
210
|
|
|
209
211
|
```
|
|
210
212
|
npx codeceptjs gt
|
|
@@ -223,7 +225,7 @@ Scenario('open my website', (I) => {
|
|
|
223
225
|
|
|
224
226
|
This is just enough to run a test, open a browser, and think what to do next to write a test case.
|
|
225
227
|
|
|
226
|
-
When you execute such test with `codeceptjs run` command you may see the browser is started
|
|
228
|
+
When you execute such test with `npx codeceptjs run` command you may see the browser is started
|
|
227
229
|
|
|
228
230
|
```
|
|
229
231
|
npx codeceptjs run --steps
|
|
@@ -264,6 +266,8 @@ Scenario('create todo item', (I) => {
|
|
|
264
266
|
|
|
265
267
|
> [▶ Working example of CodeceptJS WebDriver tests](https://github.com/DavertMik/codeceptjs-webdriver-example) for TodoMVC application.
|
|
266
268
|
|
|
269
|
+
WebDriver helper supports standard [CSS/XPath and text locators](/locators) as well as non-trivial [React locators](/react) and [Shadow DOM](/shadow).
|
|
270
|
+
|
|
267
271
|
## Waiting
|
|
268
272
|
|
|
269
273
|
Web applications do not always respond instantly. That's why WebDriver protocol has methods to wait for changes on a page. CodeceptJS provides such commands prefixed with `wait*` so you could explicitly define what effects we wait for.
|
package/lib/codecept.js
CHANGED
|
@@ -6,7 +6,7 @@ const resolve = require('path').resolve;
|
|
|
6
6
|
|
|
7
7
|
const container = require('./container');
|
|
8
8
|
const Config = require('./config');
|
|
9
|
-
const event = require('
|
|
9
|
+
const event = require('./event');
|
|
10
10
|
const runHook = require('./hooks');
|
|
11
11
|
const output = require('./output');
|
|
12
12
|
|
|
@@ -93,8 +93,8 @@ function getPath(originalPath, targetFolderPath, testsPath) {
|
|
|
93
93
|
if (parsedPath.base.endsWith('.d.ts')) parsedPath.base = parsedPath.base.substring(0, parsedPath.base.length - 5);
|
|
94
94
|
else if (parsedPath.ext === '.ts') parsedPath.base = parsedPath.name;
|
|
95
95
|
|
|
96
|
-
if (!parsedPath.dir.startsWith('.')) return path.join(parsedPath.dir, parsedPath.base);
|
|
97
|
-
const relativePath = path.relative(targetFolderPath, path.join(testsPath, parsedPath.dir, parsedPath.base));
|
|
96
|
+
if (!parsedPath.dir.startsWith('.')) return path.posix.join(parsedPath.dir, parsedPath.base);
|
|
97
|
+
const relativePath = path.posix.relative(targetFolderPath, path.posix.join(testsPath, parsedPath.dir, parsedPath.base));
|
|
98
98
|
|
|
99
99
|
return relativePath.startsWith('.') ? relativePath : `./${relativePath}`;
|
|
100
100
|
}
|
package/lib/command/generate.js
CHANGED
|
@@ -26,20 +26,20 @@ module.exports.test = function (genPath) {
|
|
|
26
26
|
output.print('Creating a new test...');
|
|
27
27
|
output.print('----------------------');
|
|
28
28
|
|
|
29
|
-
const defaultExt = config.tests.match(/([^\*/]*?)$/[1]
|
|
29
|
+
const defaultExt = config.tests.match(/([^\*/]*?)$/)[1] || '_test.js';
|
|
30
30
|
|
|
31
31
|
return inquirer.prompt([
|
|
32
32
|
{
|
|
33
33
|
type: 'input',
|
|
34
34
|
name: 'feature',
|
|
35
|
-
message: 'Feature which is being tested',
|
|
35
|
+
message: 'Feature which is being tested (ex: account, login, etc)',
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
38
|
type: 'input',
|
|
39
39
|
message: 'Filename of a test',
|
|
40
40
|
name: 'filename',
|
|
41
41
|
default(answers) {
|
|
42
|
-
return (answers.feature).replace(' ', '_')
|
|
42
|
+
return (answers.feature).replace(' ', '_') + defaultExt;
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
]).then((result) => {
|
|
@@ -60,7 +60,7 @@ module.exports.test = function (genPath) {
|
|
|
60
60
|
testContent = testContent.replace('{{actor}}', 'I');
|
|
61
61
|
|
|
62
62
|
if (!safeFileWrite(testFile, testContent)) return;
|
|
63
|
-
output.success(
|
|
63
|
+
output.success(`\nTest for ${result.filename} was created in ${testFile}`);
|
|
64
64
|
});
|
|
65
65
|
};
|
|
66
66
|
|
|
@@ -49,7 +49,7 @@ module.exports = function (genPath, options) {
|
|
|
49
49
|
});
|
|
50
50
|
output.print(`Loaded ${files.length} files`);
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
const newSteps = new Map();
|
|
53
53
|
|
|
54
54
|
const parseSteps = (steps) => {
|
|
55
55
|
const newSteps = [];
|
|
@@ -88,9 +88,9 @@ module.exports = function (genPath, options) {
|
|
|
88
88
|
const ast = parser.parse(fs.readFileSync(file).toString());
|
|
89
89
|
for (const child of ast.feature.children) {
|
|
90
90
|
if (child.type === 'ScenarioOutline') continue; // skip scenario outline
|
|
91
|
-
|
|
91
|
+
parseSteps(child.steps).map((step) => {
|
|
92
92
|
return Object.assign(step, { file: file.replace(global.codecept_dir, '').slice(1) });
|
|
93
|
-
}));
|
|
93
|
+
}).map((step) => newSteps.set(`${step.type}(${step})`, step));
|
|
94
94
|
}
|
|
95
95
|
};
|
|
96
96
|
|
|
@@ -106,7 +106,7 @@ module.exports = function (genPath, options) {
|
|
|
106
106
|
stepFile = fsPath.join(global.codecept_dir, stepFile);
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
const snippets = newSteps
|
|
109
|
+
const snippets = [...newSteps.values()]
|
|
110
110
|
.filter((value, index, self) => self.indexOf(value) === index)
|
|
111
111
|
.map((step) => {
|
|
112
112
|
return `
|
package/lib/command/init.js
CHANGED
|
@@ -21,7 +21,7 @@ const defaultConfig = {
|
|
|
21
21
|
mocha: {},
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
const helpers = ['WebDriver', 'Puppeteer', 'TestCafe', 'Protractor', 'Nightmare', 'Appium'];
|
|
24
|
+
const helpers = ['WebDriver', 'Puppeteer', 'TestCafe', 'Protractor', 'Nightmare', 'Appium', 'Playwright'];
|
|
25
25
|
const translations = Object.keys(require('../../translations'));
|
|
26
26
|
|
|
27
27
|
const noTranslation = 'English (no localization)';
|
|
@@ -6,7 +6,9 @@ const event = require('../event');
|
|
|
6
6
|
const output = require('../output');
|
|
7
7
|
|
|
8
8
|
module.exports = function (path, options) {
|
|
9
|
+
// Backward compatibility for --profile
|
|
9
10
|
process.profile = options.profile;
|
|
11
|
+
process.env.profile = options.profile;
|
|
10
12
|
|
|
11
13
|
const testsPath = getTestRoot(path);
|
|
12
14
|
const config = getConfig(testsPath);
|
|
@@ -33,6 +35,7 @@ module.exports = function (path, options) {
|
|
|
33
35
|
require('../pause')();
|
|
34
36
|
recorder.add(() => event.emit(event.test.after));
|
|
35
37
|
recorder.add(() => event.emit(event.suite.after, {}));
|
|
38
|
+
recorder.add(() => event.emit(event.all.result, {}));
|
|
36
39
|
recorder.add(() => codecept.teardown());
|
|
37
40
|
});
|
|
38
41
|
};
|
|
@@ -14,7 +14,7 @@ const {
|
|
|
14
14
|
const runner = path.join(__dirname, '/../../bin/codecept');
|
|
15
15
|
let config;
|
|
16
16
|
const childOpts = {};
|
|
17
|
-
const copyOptions = ['override', 'steps', 'reporter', 'verbose', 'config', 'reporter-options', 'grep', 'fgrep', 'invert', 'debug', 'plugins'];
|
|
17
|
+
const copyOptions = ['override', 'steps', 'reporter', 'verbose', 'config', 'reporter-options', 'grep', 'fgrep', 'invert', 'debug', 'plugins', 'colors'];
|
|
18
18
|
let overrides = {};
|
|
19
19
|
|
|
20
20
|
// codeceptjs run-multiple smoke:chrome regression:firefox - will launch smoke run in chrome and regression in firefox
|
|
@@ -29,7 +29,7 @@ let processesDone;
|
|
|
29
29
|
|
|
30
30
|
module.exports = function (selectedRuns, options) {
|
|
31
31
|
// registering options globally to use in config
|
|
32
|
-
process.profile = options.profile;
|
|
32
|
+
process.env.profile = options.profile;
|
|
33
33
|
const configFile = options.config;
|
|
34
34
|
let codecept;
|
|
35
35
|
|
package/lib/command/run-rerun.js
CHANGED
|
@@ -7,7 +7,9 @@ const Codecept = require('../rerun');
|
|
|
7
7
|
|
|
8
8
|
module.exports = function (test, options) {
|
|
9
9
|
// registering options globally to use in config
|
|
10
|
+
// Backward compatibility for --profile
|
|
10
11
|
process.profile = options.profile;
|
|
12
|
+
process.env.profile = options.profile;
|
|
11
13
|
const configFile = options.config;
|
|
12
14
|
let codecept;
|
|
13
15
|
|
|
@@ -32,7 +32,7 @@ module.exports = function (workers, options) {
|
|
|
32
32
|
'Required minimum Node version of 11.7.0 to work with "run-workers"',
|
|
33
33
|
);
|
|
34
34
|
|
|
35
|
-
process.profile = options.profile;
|
|
35
|
+
process.env.profile = options.profile;
|
|
36
36
|
|
|
37
37
|
const { Worker } = require('worker_threads');
|
|
38
38
|
|
|
@@ -46,6 +46,12 @@ module.exports = function (workers, options) {
|
|
|
46
46
|
...overrideConfigs,
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
+
const configRerun = config.rerun || {};
|
|
50
|
+
let maxReruns = configRerun.maxReruns || 1;
|
|
51
|
+
if (maxReruns > 1) {
|
|
52
|
+
maxReruns *= numberOfWorkers;
|
|
53
|
+
}
|
|
54
|
+
|
|
49
55
|
const testRoot = getTestRoot(configPath);
|
|
50
56
|
|
|
51
57
|
const codecept = new Codecept(config, options);
|
|
@@ -95,11 +101,12 @@ module.exports = function (workers, options) {
|
|
|
95
101
|
|
|
96
102
|
switch (message.event) {
|
|
97
103
|
case event.test.failed:
|
|
98
|
-
updateFinishedTests(repackTest(message.data));
|
|
99
104
|
output.test.failed(repackTest(message.data));
|
|
105
|
+
updateFinishedTests(repackTest(message.data), maxReruns);
|
|
100
106
|
break;
|
|
101
|
-
case event.test.passed:
|
|
102
|
-
|
|
107
|
+
case event.test.passed:
|
|
108
|
+
output.test.passed(repackTest(message.data));
|
|
109
|
+
updateFinishedTests(repackTest(message.data), maxReruns);
|
|
103
110
|
break;
|
|
104
111
|
case event.suite.before: output.suite.started(message.data); break;
|
|
105
112
|
case event.all.after: appendStats(message.data); break;
|
|
@@ -223,11 +230,18 @@ function simplifyObject(object) {
|
|
|
223
230
|
}, {});
|
|
224
231
|
}
|
|
225
232
|
|
|
226
|
-
const updateFinishedTests = (test) => {
|
|
233
|
+
const updateFinishedTests = (test, maxReruns) => {
|
|
227
234
|
const { id } = test;
|
|
228
235
|
if (finishedTests[id]) {
|
|
229
|
-
|
|
230
|
-
|
|
236
|
+
if (finishedTests[id].runs <= maxReruns) {
|
|
237
|
+
finishedTests[id].runs++;
|
|
238
|
+
}
|
|
239
|
+
if (test.retries !== -1) {
|
|
240
|
+
const stats = { passes: 0, failures: -1, tests: 0 };
|
|
241
|
+
appendStats(stats);
|
|
242
|
+
}
|
|
243
|
+
} else {
|
|
244
|
+
finishedTests[id] = test;
|
|
245
|
+
finishedTests[id].runs = 1;
|
|
231
246
|
}
|
|
232
|
-
finishedTests[id] = test;
|
|
233
247
|
};
|
package/lib/command/run.js
CHANGED
|
@@ -10,7 +10,9 @@ const Codecept = require('../codecept');
|
|
|
10
10
|
|
|
11
11
|
module.exports = function (test, options) {
|
|
12
12
|
// registering options globally to use in config
|
|
13
|
+
// Backward compatibility for --profile
|
|
13
14
|
process.profile = options.profile;
|
|
15
|
+
process.env.profile = options.profile;
|
|
14
16
|
const configFile = options.config;
|
|
15
17
|
let codecept;
|
|
16
18
|
|
package/lib/container.js
CHANGED
package/lib/event.js
CHANGED
|
@@ -24,6 +24,7 @@ module.exports = {
|
|
|
24
24
|
* @property {'test.passed'} passed
|
|
25
25
|
* @property {'test.failed'} failed
|
|
26
26
|
* @property {'test.finish'} finished
|
|
27
|
+
* @property {'test.skipped'} skipped
|
|
27
28
|
*/
|
|
28
29
|
test: {
|
|
29
30
|
started: 'test.start', // sync
|
|
@@ -32,6 +33,7 @@ module.exports = {
|
|
|
32
33
|
passed: 'test.passed', // sync
|
|
33
34
|
failed: 'test.failed', // sync
|
|
34
35
|
finished: 'test.finish', // sync
|
|
36
|
+
skipped: 'test.skipped', // sync
|
|
35
37
|
},
|
|
36
38
|
/**
|
|
37
39
|
* @type {object}
|
|
@@ -57,6 +57,9 @@ let PollyJS;
|
|
|
57
57
|
*/
|
|
58
58
|
class MockRequest extends Helper {
|
|
59
59
|
constructor(config) {
|
|
60
|
+
console.log('DEPRECATION NOTICE:');
|
|
61
|
+
console.log('MockRequest helper was moved to a standalone package: https://github.com/codecept-js/mock-request');
|
|
62
|
+
console.log('Disable MockRequest in config & install @codeceptjs/mock-request package\n');
|
|
60
63
|
super(config);
|
|
61
64
|
this._setConfig(config);
|
|
62
65
|
PollyJS = requireg('@pollyjs/core').Polly;
|