codeceptjs 2.6.7 → 2.6.11
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 +33 -6
- package/README.md +11 -11
- package/docs/advanced.md +21 -0
- package/docs/basics.md +6 -5
- package/docs/bdd.md +1 -2
- package/docs/books.md +1 -1
- package/docs/build/Appium.js +1 -2
- package/docs/build/FileSystem.js +3 -3
- package/docs/build/Mochawesome.js +1 -1
- package/docs/build/Nightmare.js +81 -5
- package/docs/build/Playwright.js +100 -17
- package/docs/build/Protractor.js +34 -2
- package/docs/build/Puppeteer.js +59 -2
- package/docs/build/TestCafe.js +23 -0
- package/docs/build/WebDriver.js +62 -16
- package/docs/changelog.md +152 -125
- package/docs/community-helpers.md +7 -3
- package/docs/configuration.md +1 -1
- package/docs/custom-helpers.md +2 -2
- package/docs/data.md +1 -1
- package/docs/detox.md +2 -2
- package/docs/email.md +1 -1
- package/docs/examples.md +12 -2
- package/docs/helpers/Appium.md +24 -5
- package/docs/helpers/Nightmare.md +42 -0
- package/docs/helpers/Playwright.md +41 -4
- package/docs/helpers/Protractor.md +14 -0
- package/docs/helpers/Puppeteer.md +38 -1
- package/docs/helpers/TestCafe.md +14 -0
- package/docs/helpers/WebDriver.md +24 -5
- package/docs/hooks.md +14 -14
- package/docs/locators.md +1 -1
- package/docs/playwright.md +13 -0
- package/docs/translation.md +21 -1
- package/docs/ui.md +2 -2
- package/docs/videos.md +4 -4
- package/docs/webapi/saveElementScreenshot.mustache +9 -0
- package/docs/webapi/type.mustache +11 -6
- package/docs/wiki/{Community-Helpers.md → Community-Helpers-&-Plugins.md} +6 -2
- package/docs/wiki/Examples.md +11 -1
- package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +68 -0
- package/docs/wiki/Home.md +9 -4
- package/docs/wiki/Release-Process.md +24 -0
- package/docs/wiki/Tests.md +1391 -0
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +153 -0
- package/docs/wiki/Videos.md +3 -3
- package/lib/actor.js +1 -1
- package/lib/assert/empty.js +1 -1
- package/lib/assert/equal.js +1 -1
- package/lib/assert/include.js +1 -1
- package/lib/assert/truth.js +1 -1
- package/lib/codecept.js +2 -3
- package/lib/command/configMigrate.js +3 -5
- package/lib/command/definitions.js +1 -2
- package/lib/command/dryRun.js +1 -2
- package/lib/command/gherkin/init.js +1 -1
- package/lib/command/gherkin/snippets.js +3 -3
- package/lib/command/gherkin/steps.js +2 -3
- package/lib/command/info.js +1 -2
- package/lib/command/init.js +2 -2
- package/lib/command/interactive.js +1 -2
- package/lib/command/list.js +3 -4
- package/lib/command/run-multiple.js +2 -3
- package/lib/command/run-rerun.js +2 -4
- package/lib/command/run.js +1 -2
- package/lib/container.js +2 -2
- package/lib/data/context.js +1 -1
- package/lib/event.js +1 -1
- package/lib/helper/Appium.js +1 -2
- package/lib/helper/FileSystem.js +3 -3
- package/lib/helper/Mochawesome.js +1 -1
- package/lib/helper/Nightmare.js +54 -5
- package/lib/helper/Playwright.js +75 -17
- package/lib/helper/Protractor.js +26 -2
- package/lib/helper/Puppeteer.js +34 -2
- package/lib/helper/TestCafe.js +15 -0
- package/lib/helper/WebDriver.js +43 -11
- package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
- package/lib/hooks.js +1 -2
- package/lib/interfaces/gherkin.js +0 -1
- package/lib/listener/helpers.js +1 -2
- package/lib/listener/mocha.js +0 -1
- package/lib/locator.js +2 -2
- package/lib/pause.js +1 -1
- package/lib/plugin/allure.js +1 -1
- package/lib/plugin/autoDelay.js +3 -3
- package/lib/plugin/autoLogin.js +1 -1
- package/lib/plugin/screenshotOnFail.js +2 -1
- package/lib/plugin/standardActingHelpers.js +0 -3
- package/lib/recorder.js +1 -1
- package/lib/step.js +3 -0
- package/lib/ui.js +1 -0
- package/package.json +3 -2
- package/translations/fr-FR.js +63 -0
- package/translations/index.js +5 -4
- package/typings/types.d.ts +140 -8
- package/docs/wiki/Release-process.md +0 -25
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
🚀 CodeceptJS 3 is in beta now. Install it:
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
npm i codeceptjs@3.0.0-beta.3
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
* [COMPLETE CHANGELOG](https://github.com/Codeception/CodeceptJS/blob/codeceptjs-v3.0/CHANGELOG.md#300-beta)
|
|
8
|
+
* [Documentation](https://github.com/Codeception/CodeceptJS/tree/codeceptjs-v3.0/docs)
|
|
9
|
+
|
|
10
|
+
After installing a new version, run `codecept3-upgrade` which is described below:
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
CodeceptJS 3.0 is a new version of CodeceptJS with some breaking changes included.
|
|
15
|
+
You should update your project following this guide to ensure that everything works correctly.
|
|
16
|
+
|
|
17
|
+
### 1️⃣ Syntax Change
|
|
18
|
+
|
|
19
|
+
CodeceptJS 3.0 introduced a new syntax for declaring tests, instead of:
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
Scenario('title', (I, loginPage) => {})
|
|
23
|
+
```
|
|
24
|
+
we use a new way of passing arguments into a test, via destruction:
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
Scenario('title', ({ I, loginPage }) => {})
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This works similarly to `inject()` command. This change was done to unify accessing [dependency injection container](https://codecept.io/pageobjects/#dependency-injection), and to provide better TypeScript support.
|
|
31
|
+
|
|
32
|
+
> If you use BDD-style project with Gherkin, no changes needed for this step.
|
|
33
|
+
|
|
34
|
+
To upgrade your project, you don't need to change manually all your tests.
|
|
35
|
+
|
|
36
|
+
💪 **Use [codecept3-upgrade tool](https://www.npmjs.com/package/codecept3-upgrade) to perform the migration**. Use it carefully, as it updates your current code.
|
|
37
|
+
|
|
38
|
+
To upgrade your codebase, commit all your changes, and switch to a new branch.
|
|
39
|
+
Run upgrade script (even without installing) for a directory where you have your tests:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
npx codecept3-upgrade tests
|
|
43
|
+
```
|
|
44
|
+
Review the changes in Git Diff and try to execute tests using CodeceptJS 3.0
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
### 2️⃣ Grabbers signature change
|
|
48
|
+
|
|
49
|
+
There were confusion and inconsistency across grab* methods. What they will return if multiple elements are found? A single element or an array? This was the problem as the format was dependent on a page content.
|
|
50
|
+
|
|
51
|
+
In 3.0 we decided to make all current grab* methods to return a single value only. While we add new methods grab**FromAll that return an array.
|
|
52
|
+
|
|
53
|
+
For instance, `grabTextFrom` will always return a single text value, while `grabTextFromAll` will return an array of values:
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
await I.grabTextFrom('.username'); => 'john'
|
|
57
|
+
await I.grabTextFromAll('.username'); => ['john', 'claudia', 'bill']
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Please update parts in your project where you rely on grab* methods to return an array.
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
| Single Value | Multiple Values |
|
|
64
|
+
| -- | -- |
|
|
65
|
+
| ✋`grabTextFrom` | 🙌 `grabTextFromAll` |
|
|
66
|
+
| ✋`grabValueFrom` | 🙌 `grabValueFromAll` |
|
|
67
|
+
| ✋ `grabAttributeFrom` | 🙌`grabAttributeFromAll` |
|
|
68
|
+
| ✋ `grabHTMLFrom` | 🙌 `grabHTMLFromAll` |
|
|
69
|
+
| ✋ `grabCssPropertyFrom` | 🙌 `grabCssPropertyFromAll` |
|
|
70
|
+
|
|
71
|
+
> Single-value `grab*From` will throw error when no data was matched, while `grab*FromAll` will return array.
|
|
72
|
+
|
|
73
|
+
### 3️⃣ Bootstrap / Teardown Changed
|
|
74
|
+
|
|
75
|
+
`async/await` paradigm changed the way we write asynchronous code in NodeJS.
|
|
76
|
+
However, bootstrap functions were created to use old-style methods of passing `done` callback inside.
|
|
77
|
+
|
|
78
|
+
In 3.0 we decided to completely change the way async bootstrap is performed and replace all it with async/await functions:
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
// before
|
|
82
|
+
bootstrap: (done) => {
|
|
83
|
+
server.start().then(done);
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// after
|
|
87
|
+
bootstrap: async () => {
|
|
88
|
+
await server.start();
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
Passing a string as bootstrap function (to require a function from external file) is also not supported:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
// before
|
|
95
|
+
bootstrap: './server_start.js',
|
|
96
|
+
|
|
97
|
+
// after
|
|
98
|
+
bootstrap: require('./server_start.js'),
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The same rules are applied to teardown, bootstrapAll, teardownAll.
|
|
102
|
+
|
|
103
|
+
### 4️⃣ Locator Detection Heuristic Change
|
|
104
|
+
|
|
105
|
+
In 3.0 we added a new rule to auto-detect CSS locator. If a locator starts with `[` parser will use it as a CSS locator, without trying to match value by text.
|
|
106
|
+
|
|
107
|
+
* Previous behavior: I.click('[user]') - will try to search for a link with `[user]` text, if no found - take `[user]` as CSS locator
|
|
108
|
+
* Current behavior: I.click('[user]') - will check only for CSS locator `[user]`
|
|
109
|
+
|
|
110
|
+
### 5️⃣ Improved Parallel Execution with Workers
|
|
111
|
+
|
|
112
|
+
CodeceptJS has two parallel execution modes:
|
|
113
|
+
|
|
114
|
+
* classical `run-multiple` which spawns independent CodeceptJS processes on system level.
|
|
115
|
+
* threaded `run-workers` which uses NodeJS workers instead of subprocesses.
|
|
116
|
+
|
|
117
|
+
Workers are faster, they can communicate with parent thread. Unfortunately, `run-workers` was not as efficient as `run-multiple` because there was no way of declaring sophisticated configs for parallel execution. For instance, running tests in 4 threads in 2 browsers could not be set.
|
|
118
|
+
|
|
119
|
+
We updated workers API to make them as flexible as possible. You don't even need to put complex logic into config! You can create your own parallel runner and customize it to match your expectations:
|
|
120
|
+
|
|
121
|
+
```js
|
|
122
|
+
// don't initialize workers in constructor
|
|
123
|
+
const workers = new Workers(null, workerConfig);
|
|
124
|
+
// split tests by suites in 2 groups
|
|
125
|
+
const testGroups = workers.createGroupsOfSuites(2);
|
|
126
|
+
|
|
127
|
+
const browsers = ['firefox', 'chrome'];
|
|
128
|
+
|
|
129
|
+
const configs = browsers.map(browser => {
|
|
130
|
+
return helpers: {
|
|
131
|
+
WebDriver: { browser }
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
for (const config of configs) {
|
|
136
|
+
for (group of groupOfTests) {
|
|
137
|
+
const worker = workers.spawn();
|
|
138
|
+
worker.addTests(group);
|
|
139
|
+
worker.addConfig(config);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
workers.run();
|
|
144
|
+
```
|
|
145
|
+
[Learn more about how you can create a parallel runner](https://github.com/Codeception/CodeceptJS/blob/codeceptjs-v3.0/docs/parallel.md#custom-parallel-execution).
|
|
146
|
+
|
|
147
|
+
`run-multiple` will still work but it is considered deprecated and won't be supported.
|
|
148
|
+
|
|
149
|
+
### WebDriverIO helper removed
|
|
150
|
+
|
|
151
|
+
WebDriverIO helper supported webdriverio v4 library, which is not maintained anymore. It should be easy to switch to WebDriver helper which supports webdriverio v6.
|
|
152
|
+
|
|
153
|
+
|
package/docs/wiki/Videos.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
[](https://www.youtube.com/watch?v=BRMWstiOTks)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
## [An Introduction, Getting started and working with CodeceptJS & Puppeteer (EAWeekend)](https://www.youtube.com/watch?v=BRMWstiOTks)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## [CodeceptJS Official YouTube Channel](https://www.youtube.com/channel/UCEs4030bmtonyDhTHEXa_2g)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## [Introductory Videos](https://www.youtube.com/watch?v=FPFG1rBNJ64&list=PLcFXthgti9Lt4SjSvL1ALDg6dOeTC0TvT)
|
|
8
8
|
|
|
9
9
|
Free educational videos provided by our community member **[@ontytoom](http://github.com/ontytoom)**.
|
|
10
10
|
|
package/lib/actor.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const Step = require('./step');
|
|
2
2
|
const container = require('./container');
|
|
3
|
-
const methodsOfObject = require('./utils')
|
|
3
|
+
const { methodsOfObject } = require('./utils');
|
|
4
4
|
const recorder = require('./recorder');
|
|
5
5
|
const event = require('./event');
|
|
6
6
|
const output = require('./output');
|
package/lib/assert/empty.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const Assertion = require('../assert');
|
|
2
2
|
const AssertionFailedError = require('./error');
|
|
3
|
-
const template = require('../utils')
|
|
3
|
+
const { template } = require('../utils');
|
|
4
4
|
const output = require('../output');
|
|
5
5
|
|
|
6
6
|
class EmptinessAssertion extends Assertion {
|
package/lib/assert/equal.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const Assertion = require('../assert');
|
|
2
2
|
const AssertionFailedError = require('./error');
|
|
3
|
-
const template = require('../utils')
|
|
3
|
+
const { template } = require('../utils');
|
|
4
4
|
const output = require('../output');
|
|
5
5
|
|
|
6
6
|
class EqualityAssertion extends Assertion {
|
package/lib/assert/include.js
CHANGED
package/lib/assert/truth.js
CHANGED
package/lib/codecept.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
const existsSync = require('fs')
|
|
2
|
-
const readFileSync = require('fs').readFileSync;
|
|
1
|
+
const { existsSync, readFileSync } = require('fs');
|
|
3
2
|
const glob = require('glob');
|
|
4
3
|
const fsPath = require('path');
|
|
5
|
-
const resolve = require('path')
|
|
4
|
+
const { resolve } = require('path');
|
|
6
5
|
|
|
7
6
|
const container = require('./container');
|
|
8
7
|
const Config = require('./config');
|
|
@@ -5,11 +5,9 @@ const mkdirp = require('mkdirp');
|
|
|
5
5
|
const path = require('path');
|
|
6
6
|
const util = require('util');
|
|
7
7
|
|
|
8
|
-
const print = require('../output')
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const fileExists = require('../utils').fileExists;
|
|
12
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
8
|
+
const { print, success, error } = require('../output');
|
|
9
|
+
const { fileExists } = require('../utils');
|
|
10
|
+
const { getTestRoot } = require('./utils');
|
|
13
11
|
|
|
14
12
|
module.exports = function (initPath) {
|
|
15
13
|
const testsPath = getTestRoot(initPath);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
const getConfig = require('./utils')
|
|
5
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
4
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
6
5
|
const Codecept = require('../codecept');
|
|
7
6
|
const container = require('../container');
|
|
8
7
|
const output = require('../output');
|
package/lib/command/dryRun.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const getConfig = require('./utils')
|
|
2
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
1
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
3
2
|
const Config = require('../config');
|
|
4
3
|
const Codecept = require('../codecept');
|
|
5
4
|
const output = require('../output');
|
|
@@ -4,7 +4,7 @@ const path = require('path');
|
|
|
4
4
|
const mkdirp = require('mkdirp');
|
|
5
5
|
|
|
6
6
|
const output = require('../../output');
|
|
7
|
-
const { fileExists
|
|
7
|
+
const { fileExists } = require('../../utils');
|
|
8
8
|
const {
|
|
9
9
|
getConfig, getTestRoot, updateConfig, safeFileWrite,
|
|
10
10
|
} = require('../utils');
|
|
@@ -4,8 +4,8 @@ const { Parser } = require('gherkin');
|
|
|
4
4
|
const glob = require('glob');
|
|
5
5
|
const fsPath = require('path');
|
|
6
6
|
|
|
7
|
-
const getConfig = require('../utils')
|
|
8
|
-
const getTestRoot = require('../utils')
|
|
7
|
+
const { getConfig } = require('../utils');
|
|
8
|
+
const { getTestRoot } = require('../utils');
|
|
9
9
|
const Codecept = require('../../codecept');
|
|
10
10
|
const output = require('../../output');
|
|
11
11
|
const { matchStep } = require('../../interfaces/bdd');
|
|
@@ -97,7 +97,7 @@ module.exports = function (genPath, options) {
|
|
|
97
97
|
|
|
98
98
|
let stepFile = options.path || config.gherkin.steps[0];
|
|
99
99
|
if (!fs.existsSync(stepFile)) {
|
|
100
|
-
output.error(
|
|
100
|
+
output.error(`Please enter a valid step file path ${stepFile}`);
|
|
101
101
|
process.exit(1);
|
|
102
102
|
}
|
|
103
103
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
const getConfig = require('../utils')
|
|
2
|
-
const getTestRoot = require('../utils')
|
|
1
|
+
const { getConfig } = require('../utils');
|
|
2
|
+
const { getTestRoot } = require('../utils');
|
|
3
3
|
const Codecept = require('../../codecept');
|
|
4
|
-
const container = require('../../container');
|
|
5
4
|
const output = require('../../output');
|
|
6
5
|
const { getSteps } = require('../../interfaces/bdd');
|
|
7
6
|
|
package/lib/command/info.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
const envinfo = require('envinfo');
|
|
2
2
|
|
|
3
|
-
const getConfig = require('./utils')
|
|
4
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
3
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
5
4
|
const Codecept = require('../codecept');
|
|
6
5
|
const output = require('../output');
|
|
7
6
|
|
package/lib/command/init.js
CHANGED
|
@@ -21,7 +21,7 @@ const defaultConfig = {
|
|
|
21
21
|
mocha: {},
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
-
const helpers =
|
|
24
|
+
const helpers = require('../plugin/standardActingHelpers').slice();
|
|
25
25
|
const translations = Object.keys(require('../../translations'));
|
|
26
26
|
|
|
27
27
|
const noTranslation = 'English (no localization)';
|
|
@@ -32,7 +32,7 @@ let packages;
|
|
|
32
32
|
const configHeader = `const { setHeadlessWhen } = require('@codeceptjs/configure');
|
|
33
33
|
|
|
34
34
|
// turn on headless mode when running with HEADLESS=true environment variable
|
|
35
|
-
// HEADLESS=true npx
|
|
35
|
+
// export HEADLESS=true && npx codeceptjs run
|
|
36
36
|
setHeadlessWhen(process.env.HEADLESS);
|
|
37
37
|
|
|
38
38
|
`;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
const getConfig = require('./utils')
|
|
2
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
1
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
3
2
|
const recorder = require('../recorder');
|
|
4
3
|
const Codecept = require('../codecept');
|
|
5
4
|
const event = require('../event');
|
package/lib/command/list.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
const getConfig = require('./utils')
|
|
2
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
1
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
3
2
|
const Codecept = require('../codecept');
|
|
4
3
|
const container = require('../container');
|
|
5
|
-
const getParamsToString = require('../parser')
|
|
6
|
-
const methodsOfObject = require('../utils')
|
|
4
|
+
const { getParamsToString } = require('../parser');
|
|
5
|
+
const { methodsOfObject } = require('../utils');
|
|
7
6
|
const output = require('../output');
|
|
8
7
|
|
|
9
8
|
module.exports = function (path) {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
const fork = require('child_process')
|
|
1
|
+
const { fork } = require('child_process');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const crypto = require('crypto');
|
|
4
4
|
|
|
5
5
|
const runHook = require('../hooks');
|
|
6
6
|
const event = require('../event');
|
|
7
7
|
const collection = require('./run-multiple/collection');
|
|
8
|
-
const clearString = require('../utils')
|
|
9
|
-
const replaceValueDeep = require('../utils').replaceValueDeep;
|
|
8
|
+
const { clearString, replaceValueDeep } = require('../utils');
|
|
10
9
|
const {
|
|
11
10
|
getConfig, getTestRoot, fail,
|
|
12
11
|
} = require('./utils');
|
package/lib/command/run-rerun.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
const getConfig = require('./utils')
|
|
2
|
-
const
|
|
3
|
-
const printError = require('./utils').printError;
|
|
4
|
-
const createOutputDir = require('./utils').createOutputDir;
|
|
1
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
2
|
+
const { printError, createOutputDir } = require('./utils');
|
|
5
3
|
const Config = require('../config');
|
|
6
4
|
const Codecept = require('../rerun');
|
|
7
5
|
|
package/lib/command/run.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
const mkdirp = require('mkdirp');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
const getConfig = require('./utils')
|
|
5
|
-
const getTestRoot = require('./utils').getTestRoot;
|
|
4
|
+
const { getConfig, getTestRoot } = require('./utils');
|
|
6
5
|
const printError = require('./utils').printError;
|
|
7
6
|
const createOutputDir = require('./utils').createOutputDir;
|
|
8
7
|
const Config = require('../config');
|
package/lib/container.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const glob = require('glob');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
const fileExists = require('./utils')
|
|
4
|
+
const { fileExists } = require('./utils');
|
|
5
5
|
const Translation = require('./translation');
|
|
6
6
|
const MochaFactory = require('./mochaFactory');
|
|
7
7
|
const recorder = require('./recorder');
|
|
@@ -163,7 +163,7 @@ function createHelpers(config) {
|
|
|
163
163
|
}
|
|
164
164
|
helpers[helperName] = new HelperClass(config[helperName]);
|
|
165
165
|
} catch (err) {
|
|
166
|
-
throw new Error(`Could not load helper ${helperName} from module '${moduleName}':\n${err.message}`);
|
|
166
|
+
throw new Error(`Could not load helper ${helperName} from module '${moduleName}':\n${err.message}\n${err.stack}`);
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
169
|
|
package/lib/data/context.js
CHANGED
package/lib/event.js
CHANGED
package/lib/helper/Appium.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
let webdriverio;
|
|
2
2
|
let wdioV4;
|
|
3
|
-
let SCREEN_SIZE;
|
|
4
3
|
|
|
5
4
|
const fs = require('fs');
|
|
6
5
|
const requireg = require('requireg');
|
|
7
6
|
|
|
8
7
|
const Webdriver = require('./WebDriver');
|
|
9
8
|
const AssertionFailedError = require('../assert/error');
|
|
10
|
-
const truth = require('../assert/truth')
|
|
9
|
+
const { truth } = require('../assert/truth');
|
|
11
10
|
const recorder = require('../recorder');
|
|
12
11
|
const Locator = require('../locator');
|
|
13
12
|
const ConnectionRefused = require('./errors/ConnectionRefused');
|
package/lib/helper/FileSystem.js
CHANGED
|
@@ -3,9 +3,9 @@ const path = require('path');
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
|
|
5
5
|
const Helper = require('../helper');
|
|
6
|
-
const fileExists = require('../utils')
|
|
7
|
-
const fileIncludes = require('../assert/include')
|
|
8
|
-
const fileEquals = require('../assert/equal')
|
|
6
|
+
const { fileExists } = require('../utils');
|
|
7
|
+
const { fileIncludes } = require('../assert/include');
|
|
8
|
+
const { fileEquals } = require('../assert/equal');
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Helper for testing filesystem.
|
package/lib/helper/Nightmare.js
CHANGED
|
@@ -3,11 +3,11 @@ const requireg = require('requireg');
|
|
|
3
3
|
const urlResolve = require('url').resolve;
|
|
4
4
|
|
|
5
5
|
const Helper = require('../helper');
|
|
6
|
-
const stringIncludes = require('../assert/include')
|
|
7
|
-
const urlEquals = require('../assert/equal')
|
|
8
|
-
const equals = require('../assert/equal')
|
|
9
|
-
const empty = require('../assert/empty')
|
|
10
|
-
const truth = require('../assert/truth')
|
|
6
|
+
const { includes: stringIncludes } = require('../assert/include');
|
|
7
|
+
const { urlEquals } = require('../assert/equal');
|
|
8
|
+
const { equals } = require('../assert/equal');
|
|
9
|
+
const { empty } = require('../assert/empty');
|
|
10
|
+
const { truth } = require('../assert/truth');
|
|
11
11
|
const Locator = require('../locator');
|
|
12
12
|
const ElementNotFound = require('./errors/ElementNotFound');
|
|
13
13
|
const {
|
|
@@ -1066,6 +1066,55 @@ class Nightmare extends Helper {
|
|
|
1066
1066
|
return this.browser.refresh();
|
|
1067
1067
|
}
|
|
1068
1068
|
|
|
1069
|
+
/**
|
|
1070
|
+
* {{> saveElementScreenshot }}
|
|
1071
|
+
*
|
|
1072
|
+
*/
|
|
1073
|
+
async saveElementScreenshot(locator, fileName) {
|
|
1074
|
+
const outputFile = screenshotOutputFolder(fileName);
|
|
1075
|
+
|
|
1076
|
+
const rect = await this.grabElementBoundingRect(locator);
|
|
1077
|
+
|
|
1078
|
+
const button_clip = {
|
|
1079
|
+
x: Math.floor(rect.x),
|
|
1080
|
+
y: Math.floor(rect.y),
|
|
1081
|
+
width: Math.floor(rect.width),
|
|
1082
|
+
height: Math.floor(rect.height),
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
|
|
1086
|
+
// take the screenshot
|
|
1087
|
+
await this.browser.screenshot(outputFile, button_clip);
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* {{> grabElementBoundingRect }}
|
|
1092
|
+
*/
|
|
1093
|
+
async grabElementBoundingRect(locator, prop) {
|
|
1094
|
+
locator = new Locator(locator, 'css');
|
|
1095
|
+
|
|
1096
|
+
const rect = await this.browser.evaluate(async (by, locator) => {
|
|
1097
|
+
// store the button in a variable
|
|
1098
|
+
|
|
1099
|
+
const build_cluster_btn = await window.codeceptjs.findElement(by, locator);
|
|
1100
|
+
|
|
1101
|
+
// use the getClientRects() function on the button to determine
|
|
1102
|
+
// the size and location
|
|
1103
|
+
const rect = build_cluster_btn.getBoundingClientRect();
|
|
1104
|
+
|
|
1105
|
+
// convert the rectangle to a clip object and return it
|
|
1106
|
+
return {
|
|
1107
|
+
x: rect.left,
|
|
1108
|
+
y: rect.top,
|
|
1109
|
+
width: rect.width,
|
|
1110
|
+
height: rect.height,
|
|
1111
|
+
};
|
|
1112
|
+
}, locator.type, locator.value);
|
|
1113
|
+
|
|
1114
|
+
if (prop) return rect[prop];
|
|
1115
|
+
return rect;
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1069
1118
|
/**
|
|
1070
1119
|
* {{> saveScreenshot }}
|
|
1071
1120
|
*/
|