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.
Files changed (97) hide show
  1. package/CHANGELOG.md +33 -6
  2. package/README.md +11 -11
  3. package/docs/advanced.md +21 -0
  4. package/docs/basics.md +6 -5
  5. package/docs/bdd.md +1 -2
  6. package/docs/books.md +1 -1
  7. package/docs/build/Appium.js +1 -2
  8. package/docs/build/FileSystem.js +3 -3
  9. package/docs/build/Mochawesome.js +1 -1
  10. package/docs/build/Nightmare.js +81 -5
  11. package/docs/build/Playwright.js +100 -17
  12. package/docs/build/Protractor.js +34 -2
  13. package/docs/build/Puppeteer.js +59 -2
  14. package/docs/build/TestCafe.js +23 -0
  15. package/docs/build/WebDriver.js +62 -16
  16. package/docs/changelog.md +152 -125
  17. package/docs/community-helpers.md +7 -3
  18. package/docs/configuration.md +1 -1
  19. package/docs/custom-helpers.md +2 -2
  20. package/docs/data.md +1 -1
  21. package/docs/detox.md +2 -2
  22. package/docs/email.md +1 -1
  23. package/docs/examples.md +12 -2
  24. package/docs/helpers/Appium.md +24 -5
  25. package/docs/helpers/Nightmare.md +42 -0
  26. package/docs/helpers/Playwright.md +41 -4
  27. package/docs/helpers/Protractor.md +14 -0
  28. package/docs/helpers/Puppeteer.md +38 -1
  29. package/docs/helpers/TestCafe.md +14 -0
  30. package/docs/helpers/WebDriver.md +24 -5
  31. package/docs/hooks.md +14 -14
  32. package/docs/locators.md +1 -1
  33. package/docs/playwright.md +13 -0
  34. package/docs/translation.md +21 -1
  35. package/docs/ui.md +2 -2
  36. package/docs/videos.md +4 -4
  37. package/docs/webapi/saveElementScreenshot.mustache +9 -0
  38. package/docs/webapi/type.mustache +11 -6
  39. package/docs/wiki/{Community-Helpers.md → Community-Helpers-&-Plugins.md} +6 -2
  40. package/docs/wiki/Examples.md +11 -1
  41. package/docs/wiki/Google-Summer-of-Code-(GSoC)-2020.md +68 -0
  42. package/docs/wiki/Home.md +9 -4
  43. package/docs/wiki/Release-Process.md +24 -0
  44. package/docs/wiki/Tests.md +1391 -0
  45. package/docs/wiki/Upgrading-to-CodeceptJS-3.md +153 -0
  46. package/docs/wiki/Videos.md +3 -3
  47. package/lib/actor.js +1 -1
  48. package/lib/assert/empty.js +1 -1
  49. package/lib/assert/equal.js +1 -1
  50. package/lib/assert/include.js +1 -1
  51. package/lib/assert/truth.js +1 -1
  52. package/lib/codecept.js +2 -3
  53. package/lib/command/configMigrate.js +3 -5
  54. package/lib/command/definitions.js +1 -2
  55. package/lib/command/dryRun.js +1 -2
  56. package/lib/command/gherkin/init.js +1 -1
  57. package/lib/command/gherkin/snippets.js +3 -3
  58. package/lib/command/gherkin/steps.js +2 -3
  59. package/lib/command/info.js +1 -2
  60. package/lib/command/init.js +2 -2
  61. package/lib/command/interactive.js +1 -2
  62. package/lib/command/list.js +3 -4
  63. package/lib/command/run-multiple.js +2 -3
  64. package/lib/command/run-rerun.js +2 -4
  65. package/lib/command/run.js +1 -2
  66. package/lib/container.js +2 -2
  67. package/lib/data/context.js +1 -1
  68. package/lib/event.js +1 -1
  69. package/lib/helper/Appium.js +1 -2
  70. package/lib/helper/FileSystem.js +3 -3
  71. package/lib/helper/Mochawesome.js +1 -1
  72. package/lib/helper/Nightmare.js +54 -5
  73. package/lib/helper/Playwright.js +75 -17
  74. package/lib/helper/Protractor.js +26 -2
  75. package/lib/helper/Puppeteer.js +34 -2
  76. package/lib/helper/TestCafe.js +15 -0
  77. package/lib/helper/WebDriver.js +43 -11
  78. package/lib/helper/clientscripts/PollyWebDriverExt.js +1 -1
  79. package/lib/hooks.js +1 -2
  80. package/lib/interfaces/gherkin.js +0 -1
  81. package/lib/listener/helpers.js +1 -2
  82. package/lib/listener/mocha.js +0 -1
  83. package/lib/locator.js +2 -2
  84. package/lib/pause.js +1 -1
  85. package/lib/plugin/allure.js +1 -1
  86. package/lib/plugin/autoDelay.js +3 -3
  87. package/lib/plugin/autoLogin.js +1 -1
  88. package/lib/plugin/screenshotOnFail.js +2 -1
  89. package/lib/plugin/standardActingHelpers.js +0 -3
  90. package/lib/recorder.js +1 -1
  91. package/lib/step.js +3 -0
  92. package/lib/ui.js +1 -0
  93. package/package.json +3 -2
  94. package/translations/fr-FR.js +63 -0
  95. package/translations/index.js +5 -4
  96. package/typings/types.d.ts +140 -8
  97. package/docs/wiki/Release-process.md +0 -25
@@ -10,8 +10,8 @@ const requireg = require('requireg');
10
10
  const Helper = require('../helper');
11
11
  const stringIncludes = require('../assert/include').includes;
12
12
  const { urlEquals, equals } = require('../assert/equal');
13
- const empty = require('../assert/empty').empty;
14
- const truth = require('../assert/truth').truth;
13
+ const { empty } = require('../assert/empty');
14
+ const { truth } = require('../assert/truth');
15
15
  const {
16
16
  xpathLocator,
17
17
  fileExists,
@@ -1428,6 +1428,38 @@ class Protractor extends Helper {
1428
1428
  return this.browser.getCurrentUrl().then(currentUrl => urlEquals(this.options.url).negate(url, currentUrl));
1429
1429
  }
1430
1430
 
1431
+ /**
1432
+ * Saves screenshot of the specified locator to ouput folder (set in codecept.json or codecept.conf.js).
1433
+ * Filename is relative to output folder.
1434
+ *
1435
+ * ```js
1436
+ * I.saveElementScreenshot(`#submit`,'debug.png');
1437
+ * ```
1438
+ *
1439
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1440
+ * @param {string} fileName file name to save.
1441
+ *
1442
+ */
1443
+ async saveElementScreenshot(locator, fileName) {
1444
+ const outputFile = screenshotOutputFolder(fileName);
1445
+
1446
+ const writeFile = (png, outputFile) => {
1447
+ const fs = require('fs');
1448
+ const stream = fs.createWriteStream(outputFile);
1449
+ stream.write(Buffer.from(png, 'base64'));
1450
+ stream.end();
1451
+ return new Promise(resolve => stream.on('finish', resolve));
1452
+ };
1453
+
1454
+ const res = await this._locate(locator);
1455
+ assertElementExists(res, locator);
1456
+ if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`);
1457
+ const elem = res[0];
1458
+ this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
1459
+ const png = await elem.takeScreenshot();
1460
+ return writeFile(png, outputFile);
1461
+ }
1462
+
1431
1463
  /**
1432
1464
  * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
1433
1465
  * Filename is relative to output folder.
@@ -64,7 +64,7 @@ const consoleLogStore = new Console();
64
64
  * * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
65
65
  * * `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.
66
66
  * * `pressKeyDelay`: (optional, default: '10'). Delay between key presses in ms. Used when calling Puppeteers page.type(...) in fillField/appendField
67
- * * `getPageTimeout` (optional, default: '0') config option to set maximum navigation time in milliseconds.
67
+ * * `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.
68
68
  * * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
69
69
  * * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
70
70
  * * `userAgent`: (optional) user-agent string.
@@ -190,7 +190,7 @@ class Puppeteer extends Helper {
190
190
  disableScreenshots: false,
191
191
  uniqueScreenshotNames: false,
192
192
  manualStart: false,
193
- getPageTimeout: 0,
193
+ getPageTimeout: 30000,
194
194
  waitForNavigation: 'load',
195
195
  restart: true,
196
196
  keepCookies: false,
@@ -295,6 +295,9 @@ class Puppeteer extends Helper {
295
295
  await this.executeScript('localStorage.clear();').catch((err) => {
296
296
  if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
297
297
  });
298
+ await this.executeScript('sessionStorage.clear();').catch((err) => {
299
+ if (!(err.message.indexOf("Storage is disabled inside 'data:' URLs.") > -1)) throw err;
300
+ });
298
301
  }
299
302
  await this.closeOtherTabs();
300
303
  return this.browser;
@@ -1519,6 +1522,37 @@ class Puppeteer extends Helper {
1519
1522
  return this._waitForAction();
1520
1523
  }
1521
1524
 
1525
+ /**
1526
+ * Types out the given text into an active field.
1527
+ * To slow down typing use a second parameter, to set interval between key presses.
1528
+ * _Note:_ Should be used when [`fillField`](#fillfield) is not an option.
1529
+ *
1530
+ * ```js
1531
+ * // passing in a string
1532
+ * I.type('Type this out.');
1533
+ *
1534
+ * // typing values with a 100ms interval
1535
+ * I.type('4141555311111111', 100);
1536
+ *
1537
+ * // passing in an array
1538
+ * I.type(['T', 'E', 'X', 'T']);
1539
+ * ```
1540
+ *
1541
+ * @param {string|string[]} key or array of keys to type.
1542
+ * @param {?number} [delay=null] (optional) delay in ms between key presses
1543
+ *
1544
+ */
1545
+ async type(keys, delay = null) {
1546
+ if (!Array.isArray(keys)) {
1547
+ keys = keys.split('');
1548
+ }
1549
+
1550
+ for (const key of keys) {
1551
+ await this.page.keyboard.press(key);
1552
+ if (delay) await this.wait(delay / 1000);
1553
+ }
1554
+ }
1555
+
1522
1556
  /**
1523
1557
  * Fills a text field or textarea, after clearing its value, with the given string.
1524
1558
  * Field is located by name, label, CSS, or XPath.
@@ -2339,6 +2373,29 @@ class Puppeteer extends Helper {
2339
2373
  return array.length === 1 ? array[0] : array;
2340
2374
  }
2341
2375
 
2376
+ /**
2377
+ * Saves screenshot of the specified locator to ouput folder (set in codecept.json or codecept.conf.js).
2378
+ * Filename is relative to output folder.
2379
+ *
2380
+ * ```js
2381
+ * I.saveElementScreenshot(`#submit`,'debug.png');
2382
+ * ```
2383
+ *
2384
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
2385
+ * @param {string} fileName file name to save.
2386
+ *
2387
+ */
2388
+ async saveElementScreenshot(locator, fileName) {
2389
+ const outputFile = screenshotOutputFolder(fileName);
2390
+
2391
+ const res = await this._locate(locator);
2392
+ assertElementExists(res, locator);
2393
+ if (res.length > 1) this.debug(`[Elements] Using first element out of ${res.length}`);
2394
+ const elem = res[0];
2395
+ this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
2396
+ return elem.screenshot({ path: outputFile, type: 'png' });
2397
+ }
2398
+
2342
2399
  /**
2343
2400
  * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
2344
2401
  * Filename is relative to output folder.
@@ -1043,6 +1043,29 @@ class TestCafe extends Helper {
1043
1043
  stringIncludes('HTML source of a page').negate(text, source);
1044
1044
  }
1045
1045
 
1046
+ /**
1047
+ * Saves screenshot of the specified locator to ouput folder (set in codecept.json or codecept.conf.js).
1048
+ * Filename is relative to output folder.
1049
+ *
1050
+ * ```js
1051
+ * I.saveElementScreenshot(`#submit`,'debug.png');
1052
+ * ```
1053
+ *
1054
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
1055
+ * @param {string} fileName file name to save.
1056
+ *
1057
+ */
1058
+ async saveElementScreenshot(locator, fileName) {
1059
+ const outputFile = path.join(global.output_dir, fileName);
1060
+
1061
+ const sel = await findElements.call(this, this.context, locator);
1062
+ assertElementExists(sel);
1063
+ const firstElement = await sel.filterVisible().nth(0);
1064
+
1065
+ this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
1066
+ return this.t.takeElementScreenshot(firstElement, fileName);
1067
+ }
1068
+
1046
1069
  /**
1047
1070
  * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
1048
1071
  * Filename is relative to output folder.
@@ -2037,6 +2037,29 @@ class WebDriver extends Helper {
2037
2037
  return elem.moveTo({ xOffset, yOffset });
2038
2038
  }
2039
2039
 
2040
+ /**
2041
+ * Saves screenshot of the specified locator to ouput folder (set in codecept.json or codecept.conf.js).
2042
+ * Filename is relative to output folder.
2043
+ *
2044
+ * ```js
2045
+ * I.saveElementScreenshot(`#submit`,'debug.png');
2046
+ * ```
2047
+ *
2048
+ * @param {string|object} locator element located by CSS|XPath|strict locator.
2049
+ * @param {string} fileName file name to save.
2050
+ *
2051
+ */
2052
+ async saveElementScreenshot(locator, fileName) {
2053
+ const outputFile = screenshotOutputFolder(fileName);
2054
+
2055
+ const res = await this._locate(withStrictLocator(locator), true);
2056
+ assertElementExists(res, locator);
2057
+ const elem = usingFirstElement(res);
2058
+
2059
+ this.debug(`Screenshot of ${locator} element has been saved to ${outputFile}`);
2060
+ return elem.saveScreenshot(outputFile);
2061
+ }
2062
+
2040
2063
  /**
2041
2064
  * Saves a screenshot to ouput folder (set in codecept.json or codecept.conf.js).
2042
2065
  * Filename is relative to output folder.
@@ -2397,26 +2420,37 @@ class WebDriver extends Helper {
2397
2420
  }
2398
2421
 
2399
2422
  /**
2400
- *
2401
- * Types out the given string or the array of keys provided.
2402
- * _Note:_ Should only be used when using [`fillField`](#fillfield) is not an option.
2423
+ * Types out the given text into an active field.
2424
+ * To slow down typing use a second parameter, to set interval between key presses.
2425
+ * _Note:_ Should be used when [`fillField`](#fillfield) is not an option.
2403
2426
  *
2404
2427
  * ```js
2405
- * // When passing in a string
2428
+ * // passing in a string
2406
2429
  * I.type('Type this out.');
2407
- * // When passing in an array
2430
+ *
2431
+ * // typing values with a 100ms interval
2432
+ * I.type('4141555311111111', 100);
2433
+ *
2434
+ * // passing in an array
2408
2435
  * I.type(['T', 'E', 'X', 'T']);
2409
2436
  * ```
2410
2437
  *
2411
2438
  * @param {string|string[]} key or array of keys to type.
2412
- * Type out given array of keys or a string of text
2439
+ * @param {?number} [delay=null] (optional) delay in ms between key presses
2440
+ *
2413
2441
  */
2414
- async type(keys) {
2415
- if (Array.isArray(keys)) {
2416
- await this.browser.keys(keys);
2442
+ async type(keys, delay = null) {
2443
+ if (!Array.isArray(keys)) {
2444
+ keys = keys.split('');
2445
+ }
2446
+ if (delay) {
2447
+ for (const key of keys) {
2448
+ await this.browser.keys(key);
2449
+ await this.wait(delay / 1000);
2450
+ }
2417
2451
  return;
2418
2452
  }
2419
- await this.browser.keys(keys.split(''));
2453
+ await this.browser.keys(keys);
2420
2454
  }
2421
2455
 
2422
2456
  /**
@@ -2493,12 +2527,24 @@ class WebDriver extends Helper {
2493
2527
 
2494
2528
  // for chrome
2495
2529
  if (browser.isW3C) {
2496
- return browser.performActions([
2497
- { type: 'pointerDown', button: 0 },
2498
- {
2499
- type: 'pointerMove', origin: 'pointer', duration: 1000, x: offsetX, y: 0,
2500
- },
2501
- { type: 'pointerUp', button: 0 },
2530
+ const xOffset = await this.grabElementBoundingRect(locator, 'x');
2531
+ const yOffset = await this.grabElementBoundingRect(locator, 'y');
2532
+
2533
+ return browser.performActions([{
2534
+ type: 'pointer',
2535
+ id: 'pointer1',
2536
+ parameters: { pointerType: 'mouse' },
2537
+ actions: [
2538
+ {
2539
+ type: 'pointerMove', origin: 'pointer', duration: 1000, x: xOffset, y: yOffset,
2540
+ },
2541
+ { type: 'pointerDown', button: 0 },
2542
+ {
2543
+ type: 'pointerMove', origin: 'pointer', duration: 1000, x: offsetX, y: 0,
2544
+ },
2545
+ { type: 'pointerUp', button: 0 },
2546
+ ],
2547
+ },
2502
2548
  ]);
2503
2549
  }
2504
2550