codeceptjs 3.3.4 → 3.3.5-beta.1
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/docs/bdd.md +12 -0
- package/docs/build/Playwright.js +42 -36
- package/docs/build/Puppeteer.js +54 -43
- package/docs/build/REST.js +18 -8
- package/docs/build/WebDriver.js +34 -25
- package/docs/changelog.md +0 -38
- package/docs/community-helpers.md +1 -0
- package/docs/configuration.md +21 -18
- package/docs/helpers/Appium.md +0 -723
- package/docs/helpers/Playwright.md +269 -263
- package/docs/helpers/Puppeteer.md +230 -222
- package/docs/helpers/REST.md +20 -7
- package/docs/helpers/WebDriver.md +265 -259
- package/docs/reports.md +11 -0
- package/docs/wiki/.git/FETCH_HEAD +1 -0
- package/docs/wiki/.git/HEAD +1 -0
- package/docs/wiki/.git/ORIG_HEAD +1 -0
- package/docs/wiki/.git/config +11 -0
- package/docs/wiki/.git/description +1 -0
- package/docs/wiki/.git/hooks/applypatch-msg.sample +15 -0
- package/docs/wiki/.git/hooks/commit-msg.sample +24 -0
- package/docs/wiki/.git/hooks/fsmonitor-watchman.sample +173 -0
- package/docs/wiki/.git/hooks/post-update.sample +8 -0
- package/docs/wiki/.git/hooks/pre-applypatch.sample +14 -0
- package/docs/wiki/.git/hooks/pre-commit.sample +49 -0
- package/docs/wiki/.git/hooks/pre-merge-commit.sample +13 -0
- package/docs/wiki/.git/hooks/pre-push.sample +53 -0
- package/docs/wiki/.git/hooks/pre-rebase.sample +169 -0
- package/docs/wiki/.git/hooks/pre-receive.sample +24 -0
- package/docs/wiki/.git/hooks/prepare-commit-msg.sample +42 -0
- package/docs/wiki/.git/hooks/push-to-checkout.sample +78 -0
- package/docs/wiki/.git/hooks/update.sample +128 -0
- package/docs/wiki/.git/index +0 -0
- package/docs/wiki/.git/info/exclude +6 -0
- package/docs/wiki/.git/logs/HEAD +1 -0
- package/docs/wiki/.git/logs/refs/heads/master +1 -0
- package/docs/wiki/.git/logs/refs/remotes/origin/HEAD +1 -0
- package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.idx +0 -0
- package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.pack +0 -0
- package/docs/wiki/.git/packed-refs +2 -0
- package/docs/wiki/.git/refs/heads/master +1 -0
- package/docs/wiki/.git/refs/remotes/origin/HEAD +1 -0
- package/docs/wiki/Community-Helpers-&-Plugins.md +7 -3
- package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +29 -0
- package/docs/wiki/Examples.md +39 -48
- package/docs/wiki/Release-Process.md +8 -8
- package/docs/wiki/Tests.md +62 -60
- package/docs/wiki/Upgrading-to-CodeceptJS-3.md +2 -2
- package/lib/command/generate.js +3 -0
- package/lib/command/init.js +83 -24
- package/lib/helper/Playwright.js +42 -36
- package/lib/helper/Puppeteer.js +54 -43
- package/lib/helper/REST.js +18 -8
- package/lib/helper/WebDriver.js +34 -25
- package/lib/interfaces/gherkin.js +1 -1
- package/lib/secret.js +1 -1
- package/lib/step.js +21 -9
- package/lib/utils.js +1 -6
- package/package.json +3 -3
- package/typings/index.d.ts +158 -0
- package/typings/types.d.ts +340 -94
package/lib/command/generate.js
CHANGED
|
@@ -33,6 +33,7 @@ module.exports.test = function (genPath) {
|
|
|
33
33
|
type: 'input',
|
|
34
34
|
name: 'feature',
|
|
35
35
|
message: 'Feature which is being tested (ex: account, login, etc)',
|
|
36
|
+
validate: (val) => !!val,
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
39
|
type: 'input',
|
|
@@ -85,6 +86,7 @@ module.exports.pageObject = function (genPath, opts) {
|
|
|
85
86
|
type: 'input',
|
|
86
87
|
name: 'name',
|
|
87
88
|
message: `Name of a ${kind} object`,
|
|
89
|
+
validate: (val) => !!val,
|
|
88
90
|
}, {
|
|
89
91
|
type: 'input',
|
|
90
92
|
name: 'filename',
|
|
@@ -156,6 +158,7 @@ module.exports.helper = function (genPath) {
|
|
|
156
158
|
type: 'input',
|
|
157
159
|
name: 'name',
|
|
158
160
|
message: 'Name of a Helper',
|
|
161
|
+
validate: (val) => !!val,
|
|
159
162
|
}, {
|
|
160
163
|
type: 'input',
|
|
161
164
|
name: 'filename',
|
package/lib/command/init.js
CHANGED
|
@@ -18,8 +18,6 @@ const defaultConfig = {
|
|
|
18
18
|
output: '',
|
|
19
19
|
helpers: {},
|
|
20
20
|
include: {},
|
|
21
|
-
bootstrap: null,
|
|
22
|
-
mocha: {},
|
|
23
21
|
};
|
|
24
22
|
|
|
25
23
|
const helpers = ['Playwright', 'WebDriver', 'Puppeteer', 'REST', 'GraphQL', 'Appium', 'TestCafe', 'Nightmare'];
|
|
@@ -28,10 +26,13 @@ const translations = Object.keys(require('../../translations'));
|
|
|
28
26
|
const noTranslation = 'English (no localization)';
|
|
29
27
|
translations.unshift(noTranslation);
|
|
30
28
|
|
|
31
|
-
|
|
29
|
+
const packages = [];
|
|
30
|
+
let isTypeScript = false;
|
|
31
|
+
let extension = 'js';
|
|
32
32
|
|
|
33
33
|
const configHeader = `const { setHeadlessWhen, setCommonPlugins } = require('@codeceptjs/configure');
|
|
34
34
|
|
|
35
|
+
|
|
35
36
|
// turn on headless mode when running with HEADLESS=true environment variable
|
|
36
37
|
// export HEADLESS=true && npx codeceptjs run
|
|
37
38
|
setHeadlessWhen(process.env.HEADLESS);
|
|
@@ -53,6 +54,10 @@ module.exports = function() {
|
|
|
53
54
|
}
|
|
54
55
|
`;
|
|
55
56
|
|
|
57
|
+
const tsNodeRequired = `require('ts-node/register');
|
|
58
|
+
|
|
59
|
+
`;
|
|
60
|
+
|
|
56
61
|
module.exports = function (initPath) {
|
|
57
62
|
const testsPath = getTestRoot(initPath);
|
|
58
63
|
|
|
@@ -80,11 +85,23 @@ module.exports = function (initPath) {
|
|
|
80
85
|
return;
|
|
81
86
|
}
|
|
82
87
|
|
|
88
|
+
const typeScriptconfigFile = path.join(testsPath, 'codecept.conf.ts');
|
|
89
|
+
if (fileExists(typeScriptconfigFile)) {
|
|
90
|
+
error(`Config is already created at ${typeScriptconfigFile}`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
83
94
|
inquirer.prompt([
|
|
95
|
+
{
|
|
96
|
+
name: 'typescript',
|
|
97
|
+
type: 'confirm',
|
|
98
|
+
default: false,
|
|
99
|
+
message: 'Do you plan to write tests in TypeScript?',
|
|
100
|
+
},
|
|
84
101
|
{
|
|
85
102
|
name: 'tests',
|
|
86
103
|
type: 'input',
|
|
87
|
-
default:
|
|
104
|
+
default: (answers) => `./*_test.${answers.typescript ? 'ts' : 'js'}`,
|
|
88
105
|
message: 'Where are your tests located?',
|
|
89
106
|
},
|
|
90
107
|
{
|
|
@@ -105,23 +122,29 @@ module.exports = function (initPath) {
|
|
|
105
122
|
choices: translations,
|
|
106
123
|
},
|
|
107
124
|
]).then((result) => {
|
|
125
|
+
if (result.typescript === true) {
|
|
126
|
+
isTypeScript = true;
|
|
127
|
+
extension = isTypeScript === true ? 'ts' : 'js';
|
|
128
|
+
packages.push('typescript');
|
|
129
|
+
packages.push('ts-node');
|
|
130
|
+
packages.push('@types/node');
|
|
131
|
+
}
|
|
132
|
+
|
|
108
133
|
const config = defaultConfig;
|
|
109
134
|
config.name = testsPath.split(path.sep).pop();
|
|
110
135
|
config.output = result.output;
|
|
111
136
|
|
|
112
137
|
config.tests = result.tests;
|
|
138
|
+
if (isTypeScript) {
|
|
139
|
+
config.tests = `${config.tests.replace(/\.js$/, `.${extension}`)}`;
|
|
140
|
+
}
|
|
141
|
+
|
|
113
142
|
// create a directory tests if it is included in tests path
|
|
114
143
|
const matchResults = config.tests.match(/[^*.]+/);
|
|
115
144
|
if (matchResults) {
|
|
116
145
|
mkdirp.sync(path.join(testsPath, matchResults[0]));
|
|
117
146
|
}
|
|
118
147
|
|
|
119
|
-
// append file mask to the end of tests
|
|
120
|
-
if (!config.tests.match(/\*(.*?)$/)) {
|
|
121
|
-
config.tests = `${config.tests.replace(/\/+$/, '')}/*_test.js`;
|
|
122
|
-
print(`Adding default test mask: ${config.tests}`);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
148
|
if (result.translation !== noTranslation) config.translation = result.translation;
|
|
126
149
|
|
|
127
150
|
const helperName = result.helper;
|
|
@@ -132,7 +155,7 @@ module.exports = function (initPath) {
|
|
|
132
155
|
try {
|
|
133
156
|
const Helper = require(`../helper/${helperName}`);
|
|
134
157
|
if (Helper._checkRequirements) {
|
|
135
|
-
packages
|
|
158
|
+
packages.concat(Helper._checkRequirements());
|
|
136
159
|
}
|
|
137
160
|
|
|
138
161
|
if (!Helper._config()) return;
|
|
@@ -148,20 +171,28 @@ module.exports = function (initPath) {
|
|
|
148
171
|
|
|
149
172
|
const finish = async () => {
|
|
150
173
|
// create steps file by default
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
174
|
+
if (!isTypeScript) { // no extra step file for typescript (as it doesn't match TS conventions)
|
|
175
|
+
const stepFile = `./steps_file.${extension}`;
|
|
176
|
+
fs.writeFileSync(path.join(testsPath, stepFile), defaultActor);
|
|
177
|
+
config.include.I = stepFile;
|
|
178
|
+
print(`Steps file created at ${stepFile}`);
|
|
179
|
+
}
|
|
155
180
|
|
|
156
|
-
let configSource = beautify(
|
|
181
|
+
let configSource = beautify(`/** @type {CodeceptJS.MainConfig} */\nexports.config = ${inspect(config, false, 4, false)}`);
|
|
157
182
|
|
|
158
183
|
if (require.resolve('@codeceptjs/configure') && isLocal && !initPath) {
|
|
159
184
|
// prepend @codeceptjs/configure only when this module can be required in config
|
|
160
185
|
configSource = configHeader + configSource;
|
|
161
186
|
}
|
|
162
187
|
|
|
163
|
-
|
|
164
|
-
|
|
188
|
+
if (isTypeScript) {
|
|
189
|
+
configSource = `${tsNodeRequired}\n${configSource}`;
|
|
190
|
+
fs.writeFileSync(typeScriptconfigFile, configSource, 'utf-8');
|
|
191
|
+
print(`Config created at ${typeScriptconfigFile}`);
|
|
192
|
+
} else {
|
|
193
|
+
fs.writeFileSync(configFile, configSource, 'utf-8');
|
|
194
|
+
print(`Config created at ${configFile}`);
|
|
195
|
+
}
|
|
165
196
|
|
|
166
197
|
if (config.output) {
|
|
167
198
|
if (!fileExists(config.output)) {
|
|
@@ -177,13 +208,41 @@ module.exports = function (initPath) {
|
|
|
177
208
|
allowJs: true,
|
|
178
209
|
},
|
|
179
210
|
};
|
|
180
|
-
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
211
|
+
|
|
212
|
+
const tsconfig = {
|
|
213
|
+
'ts-node': {
|
|
214
|
+
files: true,
|
|
215
|
+
},
|
|
216
|
+
compilerOptions: {
|
|
217
|
+
target: 'es2018',
|
|
218
|
+
lib: ['es2018', 'DOM'],
|
|
219
|
+
esModuleInterop: true,
|
|
220
|
+
module: 'commonjs',
|
|
221
|
+
strictNullChecks: false,
|
|
222
|
+
types: ['codeceptjs', 'node'],
|
|
223
|
+
declaration: true,
|
|
224
|
+
skipLibCheck: true,
|
|
225
|
+
},
|
|
226
|
+
exclude: ['node_modules'],
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
if (isTypeScript) {
|
|
230
|
+
const tsconfigJson = beautify(JSON.stringify(tsconfig));
|
|
231
|
+
const tsconfigFile = path.join(testsPath, 'tsconfig.json');
|
|
232
|
+
if (fileExists(tsconfigFile)) {
|
|
233
|
+
print(`tsconfig.json already exists at ${tsconfigFile}`);
|
|
234
|
+
} else {
|
|
235
|
+
fs.writeFileSync(tsconfigFile, tsconfigJson);
|
|
236
|
+
}
|
|
184
237
|
} else {
|
|
185
|
-
|
|
186
|
-
|
|
238
|
+
const jsconfigJson = beautify(JSON.stringify(jsconfig));
|
|
239
|
+
const jsconfigFile = path.join(testsPath, 'jsconfig.json');
|
|
240
|
+
if (fileExists(jsconfigFile)) {
|
|
241
|
+
print(`jsconfig.json already exists at ${jsconfigFile}`);
|
|
242
|
+
} else {
|
|
243
|
+
fs.writeFileSync(jsconfigFile, jsconfigJson);
|
|
244
|
+
print(`Intellisense enabled in ${jsconfigFile}`);
|
|
245
|
+
}
|
|
187
246
|
}
|
|
188
247
|
|
|
189
248
|
const generateDefinitionsManually = colors.bold(`To get auto-completion support, please generate type definitions: ${colors.green('npx codeceptjs def')}`);
|
package/lib/helper/Playwright.js
CHANGED
|
@@ -44,6 +44,46 @@ const {
|
|
|
44
44
|
} = require('./extras/PlaywrightRestartOpts');
|
|
45
45
|
const { createValueEngine, createDisabledEngine } = require('./extras/PlaywrightPropEngine');
|
|
46
46
|
|
|
47
|
+
/**
|
|
48
|
+
* ## Configuration
|
|
49
|
+
*
|
|
50
|
+
* This helper should be configured in codecept.conf.js
|
|
51
|
+
*
|
|
52
|
+
* @typedef PlaywrightConfig
|
|
53
|
+
* @type {object}
|
|
54
|
+
* @prop {string} url - base url of website to be tested
|
|
55
|
+
* @prop {string} browser - a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
|
|
56
|
+
* @prop {boolean} [show=false] - show browser window.
|
|
57
|
+
* @prop {string|boolean} [restart=false] - restart strategy between tests. Possible values:
|
|
58
|
+
* * 'context' or **false** - restarts [browser context](https://playwright.dev/docs/api/class-browsercontext) but keeps running browser. Recommended by Playwright team to keep tests isolated.
|
|
59
|
+
* * 'browser' or **true** - closes browser and opens it again between tests.
|
|
60
|
+
* * 'session' or 'keep' - keeps browser context and session, but cleans up cookies and localStorage between tests. The fastest option when running tests in windowed mode. Works with `keepCookies` and `keepBrowserState` options. This behavior was default before CodeceptJS 3.1
|
|
61
|
+
* @prop {number} [timeout=1000] - - [timeout](https://playwright.dev/docs/api/class-page#page-set-default-timeout) in ms of all Playwright actions .
|
|
62
|
+
* @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
|
|
63
|
+
* @prop {any} [emulate] - browser in device emulation mode.
|
|
64
|
+
* @prop {boolean} [video=false] - enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
65
|
+
* @prop {boolean} [trace=false] - record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
|
|
66
|
+
* @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
|
|
67
|
+
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
68
|
+
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to 'session'.
|
|
69
|
+
* @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to 'session'.
|
|
70
|
+
* @prop {number} [waitForAction] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
71
|
+
* @prop {number} [waitForNavigation] - When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle`. Choose one of those options is possible. See [Playwright API](https://github.com/microsoft/playwright/blob/main/docs/api.md#pagewaitfornavigationoptions).
|
|
72
|
+
* @prop {number} [pressKeyDelay=10] - Delay between key presses in ms. Used when calling Playwrights page.type(...) in fillField/appendField
|
|
73
|
+
* @prop {number} [getPageTimeout] - config option to set maximum navigation time in milliseconds.
|
|
74
|
+
* @prop {number} [waitForTimeout] - default wait* timeout in ms. Default: 1000.
|
|
75
|
+
* @prop {object} [basicAuth] - the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
76
|
+
* @prop {string} [windowSize] - default window size. Set a dimension like `640x480`.
|
|
77
|
+
* @prop {string} [colorScheme] - default color scheme. Possible values: `dark` | `light` | `no-preference`.
|
|
78
|
+
* @prop {string} [userAgent] - user-agent string.
|
|
79
|
+
* @prop {string} [locale] - locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
|
|
80
|
+
* @prop {boolean} [manualStart] - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
|
|
81
|
+
* @prop {object} [chromium] - pass additional chromium options
|
|
82
|
+
* @prop {object} [electron] - (pass additional electron options
|
|
83
|
+
* @prop {any} [channel] - (While Playwright can operate against the stock Google Chrome and Microsoft Edge browsers available on the machine. In particular, current Playwright version will support Stable and Beta channels of these browsers. See [Google Chrome & Microsoft Edge](https://playwright.dev/docs/browsers/#google-chrome--microsoft-edge).
|
|
84
|
+
*/
|
|
85
|
+
const config = {};
|
|
86
|
+
|
|
47
87
|
/**
|
|
48
88
|
* Uses [Playwright](https://github.com/microsoft/playwright) library to run tests inside:
|
|
49
89
|
*
|
|
@@ -65,46 +105,14 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
65
105
|
*
|
|
66
106
|
* Using playwright-core package, will prevent the download of browser binaries and allow connecting to an existing browser installation or for connecting to a remote one.
|
|
67
107
|
*
|
|
68
|
-
* ## Configuration
|
|
69
108
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
* * `url`: base url of website to be tested
|
|
73
|
-
* * `browser`: a browser to test on, either: `chromium`, `firefox`, `webkit`, `electron`. Default: chromium.
|
|
74
|
-
* * `show`: (optional, default: false) - show browser window.
|
|
75
|
-
* * `restart`: (optional, default: false) - restart strategy between tests. Possible values:
|
|
76
|
-
* * 'context' or **false** - restarts [browser context](https://playwright.dev/docs/api/class-browsercontext) but keeps running browser. Recommended by Playwright team to keep tests isolated.
|
|
77
|
-
* * 'browser' or **true** - closes browser and opens it again between tests.
|
|
78
|
-
* * 'session' or 'keep' - keeps browser context and session, but cleans up cookies and localStorage between tests. The fastest option when running tests in windowed mode. Works with `keepCookies` and `keepBrowserState` options. This behavior was default before CodeceptJS 3.1
|
|
79
|
-
* * `timeout`: (optional, default: 1000) - [timeout](https://playwright.dev/docs/api/class-page#page-set-default-timeout) in ms of all Playwright actions .
|
|
80
|
-
* * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
|
|
81
|
-
* * `emulate`: (optional, default: {}) launch browser in device emulation mode.
|
|
82
|
-
* * `video`: (optional, default: false) enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
83
|
-
* * `trace`: (optional, default: false) record [tracing information](https://playwright.dev/docs/trace-viewer) with screenshots and snapshots.
|
|
84
|
-
* * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
|
|
85
|
-
* * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
86
|
-
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to 'session'.
|
|
87
|
-
* * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` is set to 'session'.
|
|
88
|
-
* * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
89
|
-
* * `waitForNavigation`: (optional, default: 'load'). When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle`. Choose one of those options is possible. See [Playwright API](https://github.com/microsoft/playwright/blob/main/docs/api.md#pagewaitfornavigationoptions).
|
|
90
|
-
* * `pressKeyDelay`: (optional, default: '10'). Delay between key presses in ms. Used when calling Playwrights page.type(...) in fillField/appendField
|
|
91
|
-
* * `getPageTimeout` (optional, default: '0') config option to set maximum navigation time in milliseconds.
|
|
92
|
-
* * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
|
|
93
|
-
* * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
94
|
-
* * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
|
|
95
|
-
* * `colorScheme`: (optional) default color scheme. Possible values: `dark` | `light` | `no-preference`.
|
|
96
|
-
* * `userAgent`: (optional) user-agent string.
|
|
97
|
-
* * `locale`: (optional) locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
|
|
98
|
-
* * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
|
|
99
|
-
* * `chromium`: (optional) pass additional chromium options
|
|
100
|
-
* * `electron`: (optional) pass additional electron options
|
|
101
|
-
* * `channel`: (optional) While Playwright can operate against the stock Google Chrome and Microsoft Edge browsers available on the machine. In particular, current Playwright version will support Stable and Beta channels of these browsers. See [Google Chrome & Microsoft Edge](https://playwright.dev/docs/browsers/#google-chrome--microsoft-edge).
|
|
109
|
+
* <!-- configuration -->
|
|
102
110
|
*
|
|
103
111
|
* #### Video Recording Customization
|
|
104
112
|
*
|
|
105
113
|
* By default, video is saved to `output/video` dir. You can customize this path by passing `dir` option to `recordVideo` option.
|
|
106
114
|
*
|
|
107
|
-
*
|
|
115
|
+
* `video`: enables video recording for failed tests; videos are saved into `output/videos` folder
|
|
108
116
|
* * `keepVideoForPassedTests`: - save videos for passed tests
|
|
109
117
|
* * `recordVideo`: [additional options for videos customization](https://playwright.dev/docs/next/api/class-browser#browser-new-context)
|
|
110
118
|
*
|
|
@@ -257,8 +265,6 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
257
265
|
* const { browserContext } = this.helpers.Playwright;
|
|
258
266
|
* await browserContext.cookies(); // get current browser context
|
|
259
267
|
* ```
|
|
260
|
-
*
|
|
261
|
-
* ## Methods
|
|
262
268
|
*/
|
|
263
269
|
class Playwright extends Helper {
|
|
264
270
|
constructor(config) {
|
package/lib/helper/Puppeteer.js
CHANGED
|
@@ -39,6 +39,35 @@ let perfTiming;
|
|
|
39
39
|
const popupStore = new Popup();
|
|
40
40
|
const consoleLogStore = new Console();
|
|
41
41
|
|
|
42
|
+
/**
|
|
43
|
+
* ## Configuration
|
|
44
|
+
*
|
|
45
|
+
* This helper should be configured in codecept.conf.js
|
|
46
|
+
*
|
|
47
|
+
* @typedef PuppeteerConfig
|
|
48
|
+
* @type {object}
|
|
49
|
+
* @prop {string} url - base url of website to be tested
|
|
50
|
+
* @prop {object} [basicAuth] (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
51
|
+
* @prop {boolean} [show] - show Google Chrome window for debug.
|
|
52
|
+
* @prop {boolean} [restart=true] - restart browser between tests.
|
|
53
|
+
* @prop {boolean} [disableScreenshots=false] - don't save screenshot on failure.
|
|
54
|
+
* @prop {boolean} [fullPageScreenshots=false] - make full page screenshots on failure.
|
|
55
|
+
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
56
|
+
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to false.
|
|
57
|
+
* @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` is set to false.
|
|
58
|
+
* @prop {number} [waitForAction=100] - how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
59
|
+
* @prop {string} [waitForNavigation=load] - when to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions). Array values are accepted as well.
|
|
60
|
+
* @prop {number} [pressKeyDelay=10] - delay between key presses in ms. Used when calling Puppeteers page.type(...) in fillField/appendField
|
|
61
|
+
* @prop {number} [getPageTimeout=30000] - config option to set maximum navigation time in milliseconds. If the timeout is set to 0, then timeout will be disabled.
|
|
62
|
+
* @prop {number} [waitForTimeout=1000] - default wait* timeout in ms.
|
|
63
|
+
* @prop {string} [windowSize] - default window size. Set a dimension in format WIDTHxHEIGHT like `640x480`.
|
|
64
|
+
* @prop {string} [userAgent] - user-agent string.
|
|
65
|
+
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
66
|
+
* @prop {string} [browser=chrome] - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
67
|
+
* @prop {object} [chrome] - pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
68
|
+
*/
|
|
69
|
+
const config = {};
|
|
70
|
+
|
|
42
71
|
/**
|
|
43
72
|
* Uses [Google Chrome's Puppeteer](https://github.com/GoogleChrome/puppeteer) library to run tests inside headless Chrome.
|
|
44
73
|
* Browser control is executed via DevTools Protocol (instead of Selenium).
|
|
@@ -56,30 +85,7 @@ const consoleLogStore = new Console();
|
|
|
56
85
|
*
|
|
57
86
|
* > Experimental Firefox support [can be activated](https://codecept.io/helpers/Puppeteer-firefox).
|
|
58
87
|
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* This helper should be configured in codecept.json or codecept.conf.js
|
|
62
|
-
*
|
|
63
|
-
* * `url`: base url of website to be tested
|
|
64
|
-
* * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
65
|
-
* * `show`: (optional, default: false) - show Google Chrome window for debug.
|
|
66
|
-
* * `restart`: (optional, default: true) - restart browser between tests.
|
|
67
|
-
* * `disableScreenshots`: (optional, default: false) - don't save screenshot on failure.
|
|
68
|
-
* * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
|
|
69
|
-
* * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
70
|
-
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
|
|
71
|
-
* * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` is set to false.
|
|
72
|
-
* * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
|
|
73
|
-
* * `waitForNavigation`: (optional, default: 'load'). When to consider navigation succeeded. Possible options: `load`, `domcontentloaded`, `networkidle0`, `networkidle2`. See [Puppeteer API](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions). Array values are accepted as well.
|
|
74
|
-
* * `pressKeyDelay`: (optional, default: '10'). Delay between key presses in ms. Used when calling Puppeteers page.type(...) in fillField/appendField
|
|
75
|
-
* * `getPageTimeout` (optional, default: '30000') config option to set maximum navigation time in milliseconds. If the timeout is set to 0, then timeout will be disabled.
|
|
76
|
-
* * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
|
|
77
|
-
* * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
|
|
78
|
-
* * `userAgent`: (optional) user-agent string.
|
|
79
|
-
* * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Puppeteer"]._startBrowser()`.
|
|
80
|
-
* * `browser`: (optional, default: chrome) - can be changed to `firefox` when using [puppeteer-firefox](https://codecept.io/helpers/Puppeteer-firefox).
|
|
81
|
-
* * `chrome`: (optional) pass additional [Puppeteer run options](https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#puppeteerlaunchoptions).
|
|
82
|
-
*
|
|
88
|
+
* <!-- configuration -->
|
|
83
89
|
*
|
|
84
90
|
* #### Example #1: Wait for 0 network connections.
|
|
85
91
|
*
|
|
@@ -192,7 +198,6 @@ class Puppeteer extends Helper {
|
|
|
192
198
|
super(config);
|
|
193
199
|
|
|
194
200
|
puppeteer = requireWithFallback('puppeteer', 'puppeteer-core');
|
|
195
|
-
|
|
196
201
|
// set defaults
|
|
197
202
|
this.isRemoteBrowser = false;
|
|
198
203
|
this.isRunning = false;
|
|
@@ -372,22 +377,22 @@ class Puppeteer extends Helper {
|
|
|
372
377
|
}
|
|
373
378
|
|
|
374
379
|
/**
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
380
|
+
* Use Puppeteer API inside a test.
|
|
381
|
+
*
|
|
382
|
+
* First argument is a description of an action.
|
|
383
|
+
* Second argument is async function that gets this helper as parameter.
|
|
384
|
+
*
|
|
385
|
+
* { [`page`](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-page), [`browser`](https://github.com/puppeteer/puppeteer/blob/master/docs/api.md#class-browser) } from Puppeteer API are available.
|
|
386
|
+
*
|
|
387
|
+
* ```js
|
|
388
|
+
* I.usePuppeteerTo('emulate offline mode', async ({ page }) {
|
|
389
|
+
* await page.setOfflineMode(true);
|
|
390
|
+
* });
|
|
391
|
+
* ```
|
|
392
|
+
*
|
|
393
|
+
* @param {string} description used to show in logs.
|
|
394
|
+
* @param {function} fn async function that is executed with Puppeteer as argument
|
|
395
|
+
*/
|
|
391
396
|
usePuppeteerTo(description, fn) {
|
|
392
397
|
return this._useTo(...arguments);
|
|
393
398
|
}
|
|
@@ -749,7 +754,8 @@ class Puppeteer extends Helper {
|
|
|
749
754
|
if (locator) {
|
|
750
755
|
const els = await this._locate(locator);
|
|
751
756
|
assertElementExists(els, locator, 'Element');
|
|
752
|
-
|
|
757
|
+
const el = els[0];
|
|
758
|
+
await el.evaluate((el) => el.scrollIntoView());
|
|
753
759
|
const elementCoordinates = await getClickablePoint(els[0]);
|
|
754
760
|
await this.executeScript((x, y) => window.scrollBy(x, y), elementCoordinates.x + offsetX, elementCoordinates.y + offsetY);
|
|
755
761
|
} else {
|
|
@@ -1069,7 +1075,12 @@ class Puppeteer extends Helper {
|
|
|
1069
1075
|
fs.mkdirSync(downloadPath, '0777');
|
|
1070
1076
|
}
|
|
1071
1077
|
fsExtra.emptyDirSync(downloadPath);
|
|
1072
|
-
|
|
1078
|
+
|
|
1079
|
+
try {
|
|
1080
|
+
return this.page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath });
|
|
1081
|
+
} catch (e) {
|
|
1082
|
+
return this.page._client().send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath });
|
|
1083
|
+
}
|
|
1073
1084
|
}
|
|
1074
1085
|
|
|
1075
1086
|
/**
|
package/lib/helper/REST.js
CHANGED
|
@@ -4,18 +4,26 @@ const Secret = require('../secret');
|
|
|
4
4
|
const Helper = require('../helper');
|
|
5
5
|
const { beautify } = require('../utils');
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* ## Configuration
|
|
9
|
+
*
|
|
10
|
+
* @typedef RESTConfig
|
|
11
|
+
* @type {object}
|
|
12
|
+
* @prop {string} endpoint - API base URL
|
|
13
|
+
* @prop {boolean} [prettyPrintJson=false] - pretty print json for response/request on console logs
|
|
14
|
+
* @prop {number} [timeout=1000] - timeout for requests in milliseconds. 10000ms by default
|
|
15
|
+
* @prop {object} [defaultHeaders] - a list of default headers
|
|
16
|
+
* @prop {function} [onRequest] - a async function which can update request object.
|
|
17
|
+
* @prop {function} [onResponse] - a async function which can update response object.
|
|
18
|
+
* @prop {number} [maxUploadFileSize] - set the max content file size in MB when performing api calls.
|
|
19
|
+
*/
|
|
20
|
+
const config = {};
|
|
21
|
+
|
|
7
22
|
/**
|
|
8
23
|
* REST helper allows to send additional requests to the REST API during acceptance tests.
|
|
9
24
|
* [Axios](https://github.com/axios/axios) library is used to perform requests.
|
|
10
25
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* * endpoint: API base URL
|
|
14
|
-
* * prettyPrintJson: pretty print json for response/request on console logs
|
|
15
|
-
* * timeout: timeout for requests in milliseconds. 10000ms by default
|
|
16
|
-
* * defaultHeaders: a list of default headers
|
|
17
|
-
* * onRequest: a async function which can update request object.
|
|
18
|
-
* * maxUploadFileSize: set the max content file size in MB when performing api calls.
|
|
26
|
+
* <!-- configuration -->
|
|
19
27
|
*
|
|
20
28
|
* ## Example
|
|
21
29
|
*
|
|
@@ -53,6 +61,8 @@ class REST extends Helper {
|
|
|
53
61
|
defaultHeaders: {},
|
|
54
62
|
endpoint: '',
|
|
55
63
|
prettyPrintJson: false,
|
|
64
|
+
onRequest: null,
|
|
65
|
+
onResponse: null,
|
|
56
66
|
};
|
|
57
67
|
|
|
58
68
|
if (this.options.maxContentLength) {
|
package/lib/helper/WebDriver.js
CHANGED
|
@@ -32,37 +32,43 @@ const SHADOW = 'shadow';
|
|
|
32
32
|
const webRoot = 'body';
|
|
33
33
|
|
|
34
34
|
let version;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* ## Configuration
|
|
38
|
+
*
|
|
39
|
+
* This helper should be configured in codecept.conf.js
|
|
40
|
+
*
|
|
41
|
+
* @typedef WebDriverConfig
|
|
42
|
+
* @type {object}
|
|
43
|
+
* @prop {string} url - base url of website to be tested.
|
|
44
|
+
* @prop {string} browser browser in which to perform testing.
|
|
45
|
+
* @prop {string} [basicAuth] - (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
46
|
+
* @prop {string} [host=localhost] - WebDriver host to connect.
|
|
47
|
+
* @prop {string} [port=4444] - WebDriver port to connect.
|
|
48
|
+
* @prop {string} [protocol=http] - protocol for WebDriver server.
|
|
49
|
+
* @prop {string} [path=/wd/hub] - path to WebDriver server,
|
|
50
|
+
* @prop {boolean} [restart=true] - restart browser between tests.
|
|
51
|
+
* @prop {boolean} [smartWait=false] - **enables [SmartWait](http://codecept.io/acceptance/#smartwait)**; wait for additional milliseconds for element to appear. Enable for 5 secs: "smartWait": 5000.
|
|
52
|
+
* @prop {boolean} [disableScreenshots=false] - don't save screenshots on failure.
|
|
53
|
+
* @prop {boolean} [fullPageScreenshots=false] (optional - make full page screenshots on failure.
|
|
54
|
+
* @prop {boolean} [uniqueScreenshotNames=false] - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
55
|
+
* @prop {boolean} [keepBrowserState=false] - keep browser state between tests when `restart` is set to false.
|
|
56
|
+
* @prop {boolean} [keepCookies=false] - keep cookies between tests when `restart` set to false.
|
|
57
|
+
* @prop {string} [windowSize=window] default window size. Set to `maximize` or a dimension in the format `640x480`.
|
|
58
|
+
* @prop {number} [waitForTimeout=1000] sets default wait time in *ms* for all `wait*` functions.
|
|
59
|
+
* @prop {object} [desiredCapabilities] Selenium's [desired capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities).
|
|
60
|
+
* @prop {boolean} [manualStart=false] - do not start browser before a test, start it manually inside a helper with `this.helpers["WebDriver"]._startBrowser()`.
|
|
61
|
+
* @prop {object} [timeouts] [WebDriver timeouts](http://webdriver.io/docs/timeouts.html) defined as hash.
|
|
62
|
+
*/
|
|
63
|
+
const config = {};
|
|
64
|
+
|
|
35
65
|
/**
|
|
36
66
|
* WebDriver helper which wraps [webdriverio](http://webdriver.io/) library to
|
|
37
67
|
* manipulate browser using Selenium WebDriver or PhantomJS.
|
|
38
68
|
*
|
|
39
69
|
* WebDriver requires Selenium Server and ChromeDriver/GeckoDriver to be installed. Those tools can be easily installed via NPM. Please check [Testing with WebDriver](https://codecept.io/webdriver/#testing-with-webdriver) for more details.
|
|
40
70
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
* This helper should be configured in codecept.json or codecept.conf.js
|
|
44
|
-
*
|
|
45
|
-
* * `url`: base url of website to be tested.
|
|
46
|
-
* * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
|
|
47
|
-
* * `browser`: browser in which to perform testing.
|
|
48
|
-
* * `host`: (optional, default: localhost) - WebDriver host to connect.
|
|
49
|
-
* * `port`: (optional, default: 4444) - WebDriver port to connect.
|
|
50
|
-
* * `protocol`: (optional, default: http) - protocol for WebDriver server.
|
|
51
|
-
* * `path`: (optional, default: /wd/hub) - path to WebDriver server,
|
|
52
|
-
* * `restart`: (optional, default: true) - restart browser between tests.
|
|
53
|
-
* * `smartWait`: (optional) **enables [SmartWait](http://codecept.io/acceptance/#smartwait)**; wait for additional milliseconds for element to appear. Enable for 5 secs: "smartWait": 5000.
|
|
54
|
-
* * `disableScreenshots`: (optional, default: false) - don't save screenshots on failure.
|
|
55
|
-
* * `fullPageScreenshots` (optional, default: false) - make full page screenshots on failure.
|
|
56
|
-
* * `uniqueScreenshotNames`: (optional, default: false) - option to prevent screenshot override if you have scenarios with the same name in different suites.
|
|
57
|
-
* * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
|
|
58
|
-
* * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` set to false.
|
|
59
|
-
* * `windowSize`: (optional) default window size. Set to `maximize` or a dimension in the format `640x480`.
|
|
60
|
-
* * `waitForTimeout`: (optional, default: 1000) sets default wait time in *ms* for all `wait*` functions.
|
|
61
|
-
* * `desiredCapabilities`: Selenium's [desired
|
|
62
|
-
* capabilities](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities).
|
|
63
|
-
* * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper
|
|
64
|
-
* with `this.helpers["WebDriver"]._startBrowser()`.
|
|
65
|
-
* * `timeouts`: [WebDriver timeouts](http://webdriver.io/docs/timeouts.html) defined as hash.
|
|
71
|
+
* <!-- configuration -->
|
|
66
72
|
*
|
|
67
73
|
* Example:
|
|
68
74
|
*
|
|
@@ -567,6 +573,9 @@ class WebDriver extends Helper {
|
|
|
567
573
|
});
|
|
568
574
|
}
|
|
569
575
|
|
|
576
|
+
if (this.browser.capabilities && this.browser.capabilities.platformName) {
|
|
577
|
+
this.browser.capabilities.platformName = this.browser.capabilities.platformName.toLowerCase();
|
|
578
|
+
}
|
|
570
579
|
return this.browser;
|
|
571
580
|
}
|
|
572
581
|
|
|
@@ -91,7 +91,7 @@ module.exports = (text, file) => {
|
|
|
91
91
|
current[placeholder] = value;
|
|
92
92
|
exampleSteps = exampleSteps.map((step) => {
|
|
93
93
|
step = { ...step };
|
|
94
|
-
step.text = step.text.
|
|
94
|
+
step.text = step.text.split(`<${placeholder}>`).join(value);
|
|
95
95
|
return step;
|
|
96
96
|
});
|
|
97
97
|
}
|
package/lib/secret.js
CHANGED
package/lib/step.js
CHANGED
|
@@ -269,15 +269,27 @@ class MetaStep extends Step {
|
|
|
269
269
|
};
|
|
270
270
|
event.dispatcher.prependListener(event.step.before, registerStep);
|
|
271
271
|
let rethrownError = null;
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
272
|
+
if (fn.constructor.name === 'AsyncFunction') {
|
|
273
|
+
result = fn.apply(this.context, this.args).then((result) => {
|
|
274
|
+
return result;
|
|
275
|
+
}).catch(function (error) {
|
|
276
|
+
this.setStatus('failed');
|
|
277
|
+
rethrownError = error;
|
|
278
|
+
}).finally(() => {
|
|
279
|
+
this.endTime = Date.now();
|
|
280
|
+
event.dispatcher.removeListener(event.step.before, registerStep);
|
|
281
|
+
});
|
|
282
|
+
} else {
|
|
283
|
+
try {
|
|
284
|
+
this.startTime = Date.now();
|
|
285
|
+
result = fn.apply(this.context, this.args);
|
|
286
|
+
} catch (error) {
|
|
287
|
+
this.setStatus('failed');
|
|
288
|
+
rethrownError = error;
|
|
289
|
+
} finally {
|
|
290
|
+
this.endTime = Date.now();
|
|
291
|
+
event.dispatcher.removeListener(event.step.before, registerStep);
|
|
292
|
+
}
|
|
281
293
|
}
|
|
282
294
|
if (rethrownError) { throw rethrownError; }
|
|
283
295
|
return result;
|