codeceptjs 3.3.4 → 3.3.5-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/docs/bdd.md +12 -0
  2. package/docs/build/Playwright.js +42 -36
  3. package/docs/build/Puppeteer.js +54 -43
  4. package/docs/build/REST.js +18 -8
  5. package/docs/build/WebDriver.js +34 -25
  6. package/docs/changelog.md +0 -38
  7. package/docs/community-helpers.md +1 -0
  8. package/docs/configuration.md +21 -18
  9. package/docs/helpers/Appium.md +0 -723
  10. package/docs/helpers/Playwright.md +269 -263
  11. package/docs/helpers/Puppeteer.md +230 -222
  12. package/docs/helpers/REST.md +20 -7
  13. package/docs/helpers/WebDriver.md +265 -259
  14. package/docs/reports.md +11 -0
  15. package/docs/wiki/.git/FETCH_HEAD +1 -0
  16. package/docs/wiki/.git/HEAD +1 -0
  17. package/docs/wiki/.git/ORIG_HEAD +1 -0
  18. package/docs/wiki/.git/config +11 -0
  19. package/docs/wiki/.git/description +1 -0
  20. package/docs/wiki/.git/hooks/applypatch-msg.sample +15 -0
  21. package/docs/wiki/.git/hooks/commit-msg.sample +24 -0
  22. package/docs/wiki/.git/hooks/fsmonitor-watchman.sample +173 -0
  23. package/docs/wiki/.git/hooks/post-update.sample +8 -0
  24. package/docs/wiki/.git/hooks/pre-applypatch.sample +14 -0
  25. package/docs/wiki/.git/hooks/pre-commit.sample +49 -0
  26. package/docs/wiki/.git/hooks/pre-merge-commit.sample +13 -0
  27. package/docs/wiki/.git/hooks/pre-push.sample +53 -0
  28. package/docs/wiki/.git/hooks/pre-rebase.sample +169 -0
  29. package/docs/wiki/.git/hooks/pre-receive.sample +24 -0
  30. package/docs/wiki/.git/hooks/prepare-commit-msg.sample +42 -0
  31. package/docs/wiki/.git/hooks/push-to-checkout.sample +78 -0
  32. package/docs/wiki/.git/hooks/update.sample +128 -0
  33. package/docs/wiki/.git/index +0 -0
  34. package/docs/wiki/.git/info/exclude +6 -0
  35. package/docs/wiki/.git/logs/HEAD +1 -0
  36. package/docs/wiki/.git/logs/refs/heads/master +1 -0
  37. package/docs/wiki/.git/logs/refs/remotes/origin/HEAD +1 -0
  38. package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.idx +0 -0
  39. package/docs/wiki/.git/objects/pack/pack-5938044f9d30daf1c195fda4dec1d54850933935.pack +0 -0
  40. package/docs/wiki/.git/packed-refs +2 -0
  41. package/docs/wiki/.git/refs/heads/master +1 -0
  42. package/docs/wiki/.git/refs/remotes/origin/HEAD +1 -0
  43. package/docs/wiki/Community-Helpers-&-Plugins.md +7 -3
  44. package/docs/wiki/Converting-Playwright-to-Istanbul-Coverage.md +29 -0
  45. package/docs/wiki/Examples.md +39 -48
  46. package/docs/wiki/Release-Process.md +8 -8
  47. package/docs/wiki/Tests.md +62 -60
  48. package/docs/wiki/Upgrading-to-CodeceptJS-3.md +2 -2
  49. package/lib/command/generate.js +3 -0
  50. package/lib/command/init.js +88 -41
  51. package/lib/config.js +9 -0
  52. package/lib/helper/Playwright.js +42 -36
  53. package/lib/helper/Puppeteer.js +54 -43
  54. package/lib/helper/REST.js +18 -8
  55. package/lib/helper/WebDriver.js +34 -25
  56. package/lib/interfaces/gherkin.js +1 -1
  57. package/lib/secret.js +1 -1
  58. package/lib/step.js +21 -9
  59. package/lib/utils.js +1 -6
  60. package/package.json +3 -3
  61. package/typings/index.d.ts +158 -0
  62. package/typings/types.d.ts +340 -94
@@ -1,7 +1,7 @@
1
- 🚀 CodeceptJS 3 is in beta now. Install it:
1
+ 🚀 CodeceptJS 3 is out now. Install it:
2
2
 
3
3
  ```
4
- npm i codeceptjs@3.0.0-beta.3
4
+ npm i codeceptjs
5
5
  ```
6
6
 
7
7
  * [COMPLETE CHANGELOG](https://github.com/Codeception/CodeceptJS/blob/codeceptjs-v3.0/CHANGELOG.md#300-beta)
@@ -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',
@@ -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
- let packages;
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);
@@ -80,11 +81,23 @@ module.exports = function (initPath) {
80
81
  return;
81
82
  }
82
83
 
84
+ const typeScriptconfigFile = path.join(testsPath, 'codecept.conf.ts');
85
+ if (fileExists(typeScriptconfigFile)) {
86
+ error(`Config is already created at ${typeScriptconfigFile}`);
87
+ return;
88
+ }
89
+
83
90
  inquirer.prompt([
91
+ {
92
+ name: 'typescript',
93
+ type: 'confirm',
94
+ default: false,
95
+ message: 'Do you plan to write tests in TypeScript?',
96
+ },
84
97
  {
85
98
  name: 'tests',
86
99
  type: 'input',
87
- default: './*_test.js',
100
+ default: (answers) => `./*_test.${answers.typescript ? 'ts' : 'js'}`,
88
101
  message: 'Where are your tests located?',
89
102
  },
90
103
  {
@@ -105,23 +118,29 @@ module.exports = function (initPath) {
105
118
  choices: translations,
106
119
  },
107
120
  ]).then((result) => {
121
+ if (result.typescript === true) {
122
+ isTypeScript = true;
123
+ extension = isTypeScript === true ? 'ts' : 'js';
124
+ packages.push('typescript');
125
+ packages.push('ts-node');
126
+ packages.push('@types/node');
127
+ }
128
+
108
129
  const config = defaultConfig;
109
130
  config.name = testsPath.split(path.sep).pop();
110
131
  config.output = result.output;
111
132
 
112
133
  config.tests = result.tests;
134
+ if (isTypeScript) {
135
+ config.tests = `${config.tests.replace(/\.js$/, `.${extension}`)}`;
136
+ }
137
+
113
138
  // create a directory tests if it is included in tests path
114
139
  const matchResults = config.tests.match(/[^*.]+/);
115
140
  if (matchResults) {
116
141
  mkdirp.sync(path.join(testsPath, matchResults[0]));
117
142
  }
118
143
 
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
144
  if (result.translation !== noTranslation) config.translation = result.translation;
126
145
 
127
146
  const helperName = result.helper;
@@ -132,7 +151,7 @@ module.exports = function (initPath) {
132
151
  try {
133
152
  const Helper = require(`../helper/${helperName}`);
134
153
  if (Helper._checkRequirements) {
135
- packages = Helper._checkRequirements();
154
+ packages.concat(Helper._checkRequirements());
136
155
  }
137
156
 
138
157
  if (!Helper._config()) return;
@@ -148,20 +167,28 @@ module.exports = function (initPath) {
148
167
 
149
168
  const finish = async () => {
150
169
  // create steps file by default
151
- const stepFile = './steps_file.js';
152
- fs.writeFileSync(path.join(testsPath, stepFile), defaultActor);
153
- config.include.I = stepFile;
154
- print(`Steps file created at ${stepFile}`);
170
+ if (!isTypeScript) { // no extra step file for typescript (as it doesn't match TS conventions)
171
+ const stepFile = `./steps_file.${extension}`;
172
+ fs.writeFileSync(path.join(testsPath, stepFile), defaultActor);
173
+ config.include.I = stepFile;
174
+ print(`Steps file created at ${stepFile}`);
175
+ }
155
176
 
156
- let configSource = beautify(`exports.config = ${inspect(config, false, 4, false)}`);
177
+ let configSource = beautify(`/** @type {CodeceptJS.MainConfig} */\nexports.config = ${inspect(config, false, 4, false)}`);
157
178
 
158
179
  if (require.resolve('@codeceptjs/configure') && isLocal && !initPath) {
159
180
  // prepend @codeceptjs/configure only when this module can be required in config
160
181
  configSource = configHeader + configSource;
161
182
  }
162
183
 
163
- fs.writeFileSync(configFile, configSource, 'utf-8');
164
- print(`Config created at ${configFile}`);
184
+ if (isTypeScript) {
185
+ configSource = beautify(`export const config : CodeceptJS.MainConfig = ${inspect(config, false, 4, false)}`);
186
+ fs.writeFileSync(typeScriptconfigFile, configSource, 'utf-8');
187
+ print(`Config created at ${typeScriptconfigFile}`);
188
+ } else {
189
+ fs.writeFileSync(configFile, configSource, 'utf-8');
190
+ print(`Config created at ${configFile}`);
191
+ }
165
192
 
166
193
  if (config.output) {
167
194
  if (!fileExists(config.output)) {
@@ -177,13 +204,41 @@ module.exports = function (initPath) {
177
204
  allowJs: true,
178
205
  },
179
206
  };
180
- const jsconfigJson = beautify(JSON.stringify(jsconfig));
181
- const jsconfigFile = path.join(testsPath, 'jsconfig.json');
182
- if (fileExists(jsconfigFile)) {
183
- print(`jsconfig.json already exists at ${jsconfigFile}`);
207
+
208
+ const tsconfig = {
209
+ 'ts-node': {
210
+ files: true,
211
+ },
212
+ compilerOptions: {
213
+ target: 'es2018',
214
+ lib: ['es2018', 'DOM'],
215
+ esModuleInterop: true,
216
+ module: 'commonjs',
217
+ strictNullChecks: false,
218
+ types: ['codeceptjs', 'node'],
219
+ declaration: true,
220
+ skipLibCheck: true,
221
+ },
222
+ exclude: ['node_modules'],
223
+ };
224
+
225
+ if (isTypeScript) {
226
+ const tsconfigJson = beautify(JSON.stringify(tsconfig));
227
+ const tsconfigFile = path.join(testsPath, 'tsconfig.json');
228
+ if (fileExists(tsconfigFile)) {
229
+ print(`tsconfig.json already exists at ${tsconfigFile}`);
230
+ } else {
231
+ fs.writeFileSync(tsconfigFile, tsconfigJson);
232
+ }
184
233
  } else {
185
- fs.writeFileSync(jsconfigFile, jsconfigJson);
186
- print(`Intellisense enabled in ${jsconfigFile}`);
234
+ const jsconfigJson = beautify(JSON.stringify(jsconfig));
235
+ const jsconfigFile = path.join(testsPath, 'jsconfig.json');
236
+ if (fileExists(jsconfigFile)) {
237
+ print(`jsconfig.json already exists at ${jsconfigFile}`);
238
+ } else {
239
+ fs.writeFileSync(jsconfigFile, jsconfigJson);
240
+ print(`Intellisense enabled in ${jsconfigFile}`);
241
+ }
187
242
  }
188
243
 
189
244
  const generateDefinitionsManually = colors.bold(`To get auto-completion support, please generate type definitions: ${colors.green('npx codeceptjs def')}`);
@@ -191,15 +246,6 @@ module.exports = function (initPath) {
191
246
  if (packages) {
192
247
  try {
193
248
  install(packages);
194
-
195
- if (testsPath) {
196
- print(generateDefinitionsManually);
197
- } else {
198
- const { code } = spawn.sync('npx', ['codeceptjs', 'def']);
199
- if (code !== 0) {
200
- print(generateDefinitionsManually);
201
- }
202
- }
203
249
  } catch (err) {
204
250
  print(colors.bold.red(err.toString()));
205
251
  print();
@@ -212,14 +258,15 @@ module.exports = function (initPath) {
212
258
  print(colors.bold.magenta('Find more information at https://codecept.io'));
213
259
  return;
214
260
  }
215
- } else {
216
- try {
217
- generateDefinitions(testsPath, {});
218
- } catch (err) {
219
- print(colors.bold.red('Couldn\'t generate type definitions'));
220
- print(colors.red(err.toString()));
221
- print('Skipping type definitions...');
222
- }
261
+ }
262
+
263
+ try {
264
+ generateDefinitions(testsPath, {});
265
+ } catch (err) {
266
+ print(colors.bold.red('Couldn\'t generate type definitions'));
267
+ print(colors.red(err.toString()));
268
+ print('Skipping type definitions...');
269
+ print(generateDefinitionsManually);
223
270
  }
224
271
 
225
272
  print('');
package/lib/config.js CHANGED
@@ -5,6 +5,7 @@ const {
5
5
  isFile,
6
6
  deepMerge,
7
7
  deepClone,
8
+ requireWithFallback,
8
9
  } = require('./utils');
9
10
 
10
11
  const defaultConfig = {
@@ -143,6 +144,14 @@ module.exports = Config;
143
144
  function loadConfigFile(configFile) {
144
145
  const extensionName = path.extname(configFile);
145
146
 
147
+ if (extensionName === '.ts') {
148
+ try {
149
+ require('ts-node/register');
150
+ } catch (err) {
151
+ console.log('ts-node package is required to parse codecept.conf.ts config correctly');
152
+ }
153
+ }
154
+
146
155
  // .conf.js config file
147
156
  if (extensionName === '.js' || extensionName === '.ts' || extensionName === '.cjs') {
148
157
  return Config.create(require(configFile).config);
@@ -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
- * This helper should be configured in codecept.json or codecept.conf.js
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
- * * `video`: enables video recording for failed tests; videos are saved into `output/videos` folder
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) {
@@ -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
- * ## Configuration
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
- * Use Puppeteer API inside a test.
376
- *
377
- * First argument is a description of an action.
378
- * Second argument is async function that gets this helper as parameter.
379
- *
380
- * { [`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.
381
- *
382
- * ```js
383
- * I.usePuppeteerTo('emulate offline mode', async ({ page }) {
384
- * await page.setOfflineMode(true);
385
- * });
386
- * ```
387
- *
388
- * @param {string} description used to show in logs.
389
- * @param {function} fn async function that is executed with Puppeteer as argument
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
- await els[0]._scrollIntoViewIfNeeded();
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
- return this.page._client.send('Page.setDownloadBehavior', { behavior: 'allow', downloadPath });
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
  /**
@@ -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
- * ## Configuration
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) {
@@ -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
- * ### Configuration
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.replace(`<${placeholder}>`, value);
94
+ step.text = step.text.split(`<${placeholder}>`).join(value);
95
95
  return step;
96
96
  });
97
97
  }