codeceptjs 3.5.9 → 3.5.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 (52) hide show
  1. package/README.md +14 -16
  2. package/docs/build/Appium.js +49 -49
  3. package/docs/build/Expect.js +33 -33
  4. package/docs/build/Nightmare.js +50 -50
  5. package/docs/build/Playwright.js +239 -133
  6. package/docs/build/Protractor.js +59 -59
  7. package/docs/build/Puppeteer.js +127 -107
  8. package/docs/build/TestCafe.js +48 -48
  9. package/docs/build/WebDriver.js +112 -93
  10. package/docs/helpers/Appium.md +3 -3
  11. package/docs/helpers/Expect.md +33 -33
  12. package/docs/helpers/Playwright.md +431 -325
  13. package/docs/helpers/Puppeteer.md +50 -24
  14. package/docs/helpers/WebDriver.md +41 -13
  15. package/docs/internal-api.md +1 -0
  16. package/docs/parallel.md +114 -2
  17. package/docs/plugins.md +7 -5
  18. package/docs/react.md +2 -1
  19. package/docs/vue.md +22 -0
  20. package/docs/webapi/grabWebElement.mustache +9 -0
  21. package/docs/webapi/grabWebElements.mustache +9 -0
  22. package/docs/webapi/scrollIntoView.mustache +1 -1
  23. package/lib/ai.js +12 -3
  24. package/lib/colorUtils.js +10 -0
  25. package/lib/command/run-multiple.js +1 -1
  26. package/lib/command/run-workers.js +30 -4
  27. package/lib/command/workers/runTests.js +39 -0
  28. package/lib/event.js +2 -0
  29. package/lib/helper/Appium.js +13 -13
  30. package/lib/helper/Expect.js +33 -33
  31. package/lib/helper/Playwright.js +125 -37
  32. package/lib/helper/Puppeteer.js +49 -38
  33. package/lib/helper/WebDriver.js +29 -19
  34. package/lib/helper/extras/PlaywrightReactVueLocator.js +38 -0
  35. package/lib/html.js +3 -3
  36. package/lib/interfaces/gherkin.js +8 -1
  37. package/lib/interfaces/scenarioConfig.js +1 -0
  38. package/lib/locator.js +2 -2
  39. package/lib/pause.js +6 -3
  40. package/lib/plugin/autoLogin.js +4 -2
  41. package/lib/plugin/heal.js +40 -7
  42. package/lib/plugin/retryFailedStep.js +6 -1
  43. package/lib/plugin/stepByStepReport.js +2 -2
  44. package/lib/plugin/tryTo.js +5 -4
  45. package/lib/recorder.js +12 -5
  46. package/lib/ui.js +1 -0
  47. package/lib/workers.js +2 -0
  48. package/package.json +28 -25
  49. package/typings/index.d.ts +1 -1
  50. package/typings/promiseBasedTypes.d.ts +195 -76
  51. package/typings/types.d.ts +191 -145
  52. package/lib/helper/extras/PlaywrightReact.js +0 -9
@@ -33,7 +33,7 @@ const ElementNotFound = require('./errors/ElementNotFound');
33
33
  const RemoteBrowserConnectionRefused = require('./errors/RemoteBrowserConnectionRefused');
34
34
  const Popup = require('./extras/Popup');
35
35
  const Console = require('./extras/Console');
36
- const findReact = require('./extras/React');
36
+ const { findReact, findVue } = require('./extras/PlaywrightReactVueLocator');
37
37
 
38
38
  let playwright;
39
39
  let perfTiming;
@@ -94,6 +94,7 @@ const pathSeparator = path.sep;
94
94
  * @prop {boolean} [ignoreHTTPSErrors] - Allows access to untrustworthy pages, e.g. to a page with an expired certificate. Default value is `false`
95
95
  * @prop {boolean} [bypassCSP] - bypass Content Security Policy or CSP
96
96
  * @prop {boolean} [highlightElement] - highlight the interacting elements. Default: false. Note: only activate under verbose mode (--verbose).
97
+ * @prop {object} [recordHar] - record HAR and will be saved to `output/har`. See more of [HAR options](https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-har).
97
98
  */
98
99
  const config = {};
99
100
 
@@ -141,6 +142,21 @@ const config = {};
141
142
  * * `trace`: enables trace recording for failed tests; trace are saved into `output/trace` folder
142
143
  * * `keepTraceForPassedTests`: - save trace for passed tests
143
144
  *
145
+ * #### HAR Recording Customization
146
+ *
147
+ * A HAR file is an HTTP Archive file that contains a record of all the network requests that are made when a page is loaded.
148
+ * It contains information about the request and response headers, cookies, content, timings, and more. You can use HAR files to mock network requests in your tests.
149
+ * HAR will be saved to `output/har`. More info could be found here https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-har.
150
+ *
151
+ * ```
152
+ * ...
153
+ * recordHar: {
154
+ * mode: 'minimal', // possible values: 'minimal'|'full'.
155
+ * content: 'embed' // possible values: "omit"|"embed"|"attach".
156
+ * }
157
+ * ...
158
+ *```
159
+ *
144
160
  * #### Example #1: Wait for 0 network connections.
145
161
  *
146
162
  * ```js
@@ -346,7 +362,7 @@ class Playwright extends Helper {
346
362
  ignoreLog: ['warning', 'log'],
347
363
  uniqueScreenshotNames: false,
348
364
  manualStart: false,
349
- getPageTimeout: 0,
365
+ getPageTimeout: 30000,
350
366
  waitForNavigation: 'load',
351
367
  restart: false,
352
368
  keepCookies: false,
@@ -455,9 +471,10 @@ class Playwright extends Helper {
455
471
  }
456
472
  }
457
473
 
458
- async _before() {
474
+ async _before(test) {
475
+ this.currentRunningTest = test;
459
476
  recorder.retry({
460
- retries: 5,
477
+ retries: process.env.FAILED_STEP_RETRIES || 3,
461
478
  when: err => {
462
479
  if (!err || typeof (err.message) !== 'string') {
463
480
  return false;
@@ -487,6 +504,15 @@ class Playwright extends Helper {
487
504
  }
488
505
  if (this.options.bypassCSP) contextOptions.bypassCSP = this.options.bypassCSP;
489
506
  if (this.options.recordVideo) contextOptions.recordVideo = this.options.recordVideo;
507
+ if (this.options.recordHar) {
508
+ const harExt = this.options.recordHar.content && this.options.recordHar.content === 'attach' ? 'zip' : 'har';
509
+ const fileName = `${`${global.output_dir}${path.sep}har${path.sep}${uuidv4()}_${clearString(this.currentRunningTest.title)}`.slice(0, 245)}.${harExt}`;
510
+ const dir = path.dirname(fileName);
511
+ if (!fileExists(dir)) fs.mkdirSync(dir);
512
+ this.options.recordHar.path = fileName;
513
+ this.currentRunningTest.artifacts.har = fileName;
514
+ contextOptions.recordHar = this.options.recordHar;
515
+ }
490
516
  if (this.storageState) contextOptions.storageState = this.storageState;
491
517
  if (this.options.userAgent) contextOptions.userAgent = this.options.userAgent;
492
518
  if (this.options.locale) contextOptions.locale = this.options.locale;
@@ -640,7 +666,7 @@ class Playwright extends Helper {
640
666
  * ```
641
667
  *
642
668
  * @param {string} description used to show in logs.
643
- * @param {function} fn async function that executed with Playwright helper as argumen
669
+ * @param {function} fn async function that executed with Playwright helper as arguments
644
670
  */
645
671
  usePlaywrightTo(description, fn) {
646
672
  return this._useTo(...arguments);
@@ -842,6 +868,7 @@ class Playwright extends Helper {
842
868
  this.context = null;
843
869
  this.frame = null;
844
870
  popupStore.clear();
871
+ if (this.options.recordHar) await this.browserContext.close();
845
872
  await this.browser.close();
846
873
  }
847
874
 
@@ -938,16 +965,9 @@ class Playwright extends Helper {
938
965
  }
939
966
 
940
967
  /**
941
- * Resize the current window to provided width and height.
942
- * First parameter can be set to `maximize`.
943
- *
944
- * @param {number} width width in pixels or `maximize`.
945
- * @param {number} height height in pixels.
946
- * @returns {void} automatically synchronized promise through #recorder
947
- *
948
968
  *
949
969
  * Unlike other drivers Playwright changes the size of a viewport, not the window!
950
- * Playwright does not control the window of a browser so it can't adjust its real size.
970
+ * Playwright does not control the window of a browser, so it can't adjust its real size.
951
971
  * It also can't maximize a window.
952
972
  *
953
973
  * Update configuration to change real window size on start:
@@ -957,6 +977,14 @@ class Playwright extends Helper {
957
977
  * // @codeceptjs/configure package must be installed
958
978
  * { setWindowSize } = require('@codeceptjs/configure');
959
979
  * ````
980
+ *
981
+ * Resize the current window to provided width and height.
982
+ * First parameter can be set to `maximize`.
983
+ *
984
+ * @param {number} width width in pixels or `maximize`.
985
+ * @param {number} height height in pixels.
986
+ * @returns {void} automatically synchronized promise through #recorder
987
+ *
960
988
  */
961
989
  async resizeWindow(width, height) {
962
990
  if (width === 'maximize') {
@@ -994,7 +1022,7 @@ class Playwright extends Helper {
994
1022
  * I.moveCursorTo('#submit', 5,5);
995
1023
  * ```
996
1024
  *
997
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1025
+ * @param {string | object} locator located by CSS|XPath|strict locator.
998
1026
  * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
999
1027
  * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
1000
1028
  * @returns {void} automatically synchronized promise through #recorder
@@ -1022,7 +1050,7 @@ class Playwright extends Helper {
1022
1050
  * I.see('#add-to-cart-bnt');
1023
1051
  * ```
1024
1052
  *
1025
- * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1053
+ * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
1026
1054
  * @param {any} [options] Playwright only: [Additional options](https://playwright.dev/docs/api/class-locator#locator-focus) for available options object as 2nd argument.
1027
1055
  * @returns {void} automatically synchronized promise through #recorder
1028
1056
  *
@@ -1052,7 +1080,7 @@ class Playwright extends Helper {
1052
1080
  * I.dontSee('#add-to-cart-btn');
1053
1081
  * ```
1054
1082
  *
1055
- * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
1083
+ * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
1056
1084
  * @param {any} [options] Playwright only: [Additional options](https://playwright.dev/docs/api/class-locator#locator-blur) for available options object as 2nd argument.
1057
1085
  * @returns {void} automatically synchronized promise through #recorder
1058
1086
  *
@@ -1068,7 +1096,7 @@ class Playwright extends Helper {
1068
1096
  /**
1069
1097
  * Return the checked status of given element.
1070
1098
  *
1071
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1099
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
1072
1100
  * @param {object} [options] See https://playwright.dev/docs/api/class-locator#locator-is-checked
1073
1101
  * @return {Promise<boolean>}
1074
1102
  *
@@ -1087,7 +1115,7 @@ class Playwright extends Helper {
1087
1115
  /**
1088
1116
  * Return the disabled status of given element.
1089
1117
  *
1090
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1118
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
1091
1119
  * @param {object} [options] See https://playwright.dev/docs/api/class-locator#locator-is-disabled
1092
1120
  * @return {Promise<boolean>}
1093
1121
  *
@@ -1099,24 +1127,26 @@ class Playwright extends Helper {
1099
1127
  }
1100
1128
 
1101
1129
  /**
1130
+ *
1131
+ * ```js
1132
+ * // specify coordinates for source position
1133
+ * I.dragAndDrop('img.src', 'img.dst', { sourcePosition: {x: 10, y: 10} })
1134
+ * ```
1135
+ *
1136
+ * > When no option is set, custom drag and drop would be used, to use the dragAndDrop API from Playwright, please set options, for example `force: true`
1137
+ *
1102
1138
  * Drag an item to a destination element.
1103
1139
  *
1104
1140
  * ```js
1105
1141
  * I.dragAndDrop('#dragHandle', '#container');
1106
1142
  * ```
1107
1143
  *
1108
- * @param {LocatorOrString} srcElement located by CSS|XPath|strict locator.
1109
- * @param {LocatorOrString} destElement located by CSS|XPath|strict locator.
1144
+ * @param {string | object} srcElement located by CSS|XPath|strict locator.
1145
+ * @param {string | object} destElement located by CSS|XPath|strict locator.
1110
1146
  * @returns {void} automatically synchronized promise through #recorder
1111
1147
  *
1112
1148
  * @param {any} [options] [Additional options](https://playwright.dev/docs/api/class-page#page-drag-and-drop) can be passed as 3rd argument.
1113
1149
  *
1114
- * ```js
1115
- * // specify coordinates for source position
1116
- * I.dragAndDrop('img.src', 'img.dst', { sourcePosition: {x: 10, y: 10} })
1117
- * ```
1118
- *
1119
- * > When no option is set, custom drag and drop would be used, to use the dragAndDrop API from Playwright, please set options, for example `force: true`
1120
1150
  */
1121
1151
  async dragAndDrop(srcElement, destElement, options) {
1122
1152
  const src = new Locator(srcElement);
@@ -1172,6 +1202,33 @@ class Playwright extends Helper {
1172
1202
  return this.page.reload({ timeout: this.options.getPageTimeout, waitUntil: this.options.waitForNavigation });
1173
1203
  }
1174
1204
 
1205
+ /**
1206
+ * Replaying from HAR
1207
+ *
1208
+ * ```js
1209
+ * // Replay API requests from HAR.
1210
+ * // Either use a matching response from the HAR,
1211
+ * // or abort the request if nothing matches.
1212
+ * I.replayFromHar('./output/har/something.har', { url: "*\/**\/api/v1/fruits" });
1213
+ * I.amOnPage('https://demo.playwright.dev/api-mocking');
1214
+ * I.see('CodeceptJS');
1215
+ * ```
1216
+ *
1217
+ * @param {string} harFilePath Path to recorded HAR file
1218
+ * @param {object} [opts] [Options for replaying from HAR](https://playwright.dev/docs/api/class-page#page-route-from-har)
1219
+ *
1220
+ * @returns Promise<void>
1221
+ */
1222
+ async replayFromHar(harFilePath, opts) {
1223
+ const file = path.join(global.codecept_dir, harFilePath);
1224
+
1225
+ if (!fileExists(file)) {
1226
+ throw new Error(`File at ${file} cannot be found on local system`);
1227
+ }
1228
+
1229
+ await this.page.routeFromHAR(harFilePath, opts);
1230
+ }
1231
+
1175
1232
  /**
1176
1233
  * Scroll page to the top.
1177
1234
  *
@@ -1219,7 +1276,7 @@ class Playwright extends Helper {
1219
1276
  * I.scrollTo('#submit', 5, 5);
1220
1277
  * ```
1221
1278
  *
1222
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1279
+ * @param {string | object} locator located by CSS|XPath|strict locator.
1223
1280
  * @param {number} [offsetX=0] (optional, `0` by default) X-axis offset.
1224
1281
  * @param {number} [offsetY=0] (optional, `0` by default) Y-axis offset.
1225
1282
  * @returns {void} automatically synchronized promise through #recorder
@@ -1396,6 +1453,40 @@ class Playwright extends Helper {
1396
1453
  return findFields.call(this, locator);
1397
1454
  }
1398
1455
 
1456
+ /**
1457
+ * Grab WebElements for given locator
1458
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
1459
+ *
1460
+ * ```js
1461
+ * const webElements = await I.grabWebElements('#button');
1462
+ * ```
1463
+ *
1464
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
1465
+ * @returns {Promise<*>} WebElement of being used Web helper
1466
+ *
1467
+ *
1468
+ */
1469
+ async grabWebElements(locator) {
1470
+ return this._locate(locator);
1471
+ }
1472
+
1473
+ /**
1474
+ * Grab WebElement for given locator
1475
+ * Resumes test execution, so **should be used inside an async function with `await`** operator.
1476
+ *
1477
+ * ```js
1478
+ * const webElement = await I.grabWebElement('#button');
1479
+ * ```
1480
+ *
1481
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
1482
+ * @returns {Promise<*>} WebElement of being used Web helper
1483
+ *
1484
+ *
1485
+ */
1486
+ async grabWebElement(locator) {
1487
+ return this._locateElement(locator);
1488
+ }
1489
+
1399
1490
  /**
1400
1491
  * Switch focus to a particular tab by its number. It waits tabs loading and then switch tab
1401
1492
  *
@@ -1531,7 +1622,7 @@ class Playwright extends Helper {
1531
1622
  * ```js
1532
1623
  * I.seeElement('#modal');
1533
1624
  * ```
1534
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
1625
+ * @param {string | object} locator located by CSS|XPath|strict locator.
1535
1626
  * @returns {void} automatically synchronized promise through #recorder
1536
1627
  *
1537
1628
  *
@@ -1549,7 +1640,7 @@ class Playwright extends Helper {
1549
1640
  * I.dontSeeElement('.modal'); // modal is not shown
1550
1641
  * ```
1551
1642
  *
1552
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
1643
+ * @param {string | object} locator located by CSS|XPath|Strict locator.
1553
1644
  * @returns {void} automatically synchronized promise through #recorder
1554
1645
  *
1555
1646
  *
@@ -1567,7 +1658,7 @@ class Playwright extends Helper {
1567
1658
  * ```js
1568
1659
  * I.seeElementInDOM('#modal');
1569
1660
  * ```
1570
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
1661
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
1571
1662
  * @returns {void} automatically synchronized promise through #recorder
1572
1663
  *
1573
1664
  */
@@ -1583,7 +1674,7 @@ class Playwright extends Helper {
1583
1674
  * I.dontSeeElementInDOM('.nav'); // checks that element is not on page visible or not
1584
1675
  * ```
1585
1676
  *
1586
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|Strict locator.
1677
+ * @param {string | object} locator located by CSS|XPath|Strict locator.
1587
1678
  * @returns {void} automatically synchronized promise through #recorder
1588
1679
  *
1589
1680
  */
@@ -1648,14 +1739,14 @@ class Playwright extends Helper {
1648
1739
  * I.click({css: 'nav a.login'});
1649
1740
  * ```
1650
1741
  *
1651
- * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1652
- * @param {?CodeceptJS.LocatorOrString | null} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1742
+ * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1743
+ * @param {?string | object | null} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1653
1744
  * @returns {void} automatically synchronized promise through #recorder
1654
1745
  *
1655
1746
  *
1656
1747
  * @param {any} [options] [Additional options](https://playwright.dev/docs/api/class-page#page-click) for click available as 3rd argument.
1657
1748
  *
1658
- * Examples:
1749
+ * @example
1659
1750
  *
1660
1751
  * ```js
1661
1752
  * // click on element at position
@@ -1705,8 +1796,8 @@ class Playwright extends Helper {
1705
1796
  * I.forceClick({css: 'nav a.login'});
1706
1797
  * ```
1707
1798
  *
1708
- * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1709
- * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1799
+ * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1800
+ * @param {?string | object} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1710
1801
  * @returns {void} automatically synchronized promise through #recorder
1711
1802
  *
1712
1803
  */
@@ -1725,12 +1816,10 @@ class Playwright extends Helper {
1725
1816
  * I.doubleClick('.btn.edit');
1726
1817
  * ```
1727
1818
  *
1728
- * @param {CodeceptJS.LocatorOrString} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1729
- * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1819
+ * @param {string | object} locator clickable link or button located by text, or any element located by CSS|XPath|strict locator.
1820
+ * @param {?string | object} [context=null] (optional, `null` by default) element to search in CSS|XPath|Strict locator.
1730
1821
  * @returns {void} automatically synchronized promise through #recorder
1731
1822
  *
1732
- *
1733
- *
1734
1823
  */
1735
1824
  async doubleClick(locator, context = null) {
1736
1825
  return proceedClick.call(this, locator, context, { clickCount: 2 });
@@ -1748,18 +1837,27 @@ class Playwright extends Helper {
1748
1837
  * I.rightClick('Click me', '.context');
1749
1838
  * ```
1750
1839
  *
1751
- * @param {CodeceptJS.LocatorOrString} locator clickable element located by CSS|XPath|strict locator.
1752
- * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
1840
+ * @param {string | object} locator clickable element located by CSS|XPath|strict locator.
1841
+ * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
1753
1842
  * @returns {void} automatically synchronized promise through #recorder
1754
1843
  *
1755
- *
1756
- *
1757
1844
  */
1758
1845
  async rightClick(locator, context = null) {
1759
1846
  return proceedClick.call(this, locator, context, { button: 'right' });
1760
1847
  }
1761
1848
 
1762
1849
  /**
1850
+ *
1851
+ * [Additional options](https://playwright.dev/docs/api/class-elementhandle#element-handle-check) for check available as 3rd argument.
1852
+ *
1853
+ * Examples:
1854
+ *
1855
+ * ```js
1856
+ * // click on element at position
1857
+ * I.checkOption('Agree', '.signup', { position: { x: 5, y: 5 } })
1858
+ * ```
1859
+ * > ⚠️ To avoid flakiness, option `force: true` is set by default
1860
+ *
1763
1861
  * Selects a checkbox or radio button.
1764
1862
  * Element is located by label or name or CSS or XPath.
1765
1863
  *
@@ -1770,20 +1868,11 @@ class Playwright extends Helper {
1770
1868
  * I.checkOption('I Agree to Terms and Conditions');
1771
1869
  * I.checkOption('agree', '//form');
1772
1870
  * ```
1773
- * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1774
- * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1871
+ * @param {string | object} field checkbox located by label | name | CSS | XPath | strict locator.
1872
+ * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1775
1873
  * @returns {void} automatically synchronized promise through #recorder
1776
1874
  *
1777
1875
  *
1778
- * [Additional options](https://playwright.dev/docs/api/class-elementhandle#element-handle-check) for check available as 3rd argument.
1779
- *
1780
- * Examples:
1781
- *
1782
- * ```js
1783
- * // click on element at position
1784
- * I.checkOption('Agree', '.signup', { position: { x: 5, y: 5 } })
1785
- * ```
1786
- * > ⚠️ To avoid flakiness, option `force: true` is set by default
1787
1876
  */
1788
1877
  async checkOption(field, context = null, options = { force: true }) {
1789
1878
  const elm = await this._locateCheckable(field, context);
@@ -1792,6 +1881,17 @@ class Playwright extends Helper {
1792
1881
  }
1793
1882
 
1794
1883
  /**
1884
+ *
1885
+ * [Additional options](https://playwright.dev/docs/api/class-elementhandle#element-handle-uncheck) for uncheck available as 3rd argument.
1886
+ *
1887
+ * Examples:
1888
+ *
1889
+ * ```js
1890
+ * // click on element at position
1891
+ * I.uncheckOption('Agree', '.signup', { position: { x: 5, y: 5 } })
1892
+ * ```
1893
+ * > ⚠️ To avoid flakiness, option `force: true` is set by default
1894
+ *
1795
1895
  * Unselects a checkbox or radio button.
1796
1896
  * Element is located by label or name or CSS or XPath.
1797
1897
  *
@@ -1802,20 +1902,10 @@ class Playwright extends Helper {
1802
1902
  * I.uncheckOption('I Agree to Terms and Conditions');
1803
1903
  * I.uncheckOption('agree', '//form');
1804
1904
  * ```
1805
- * @param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
1806
- * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1905
+ * @param {string | object} field checkbox located by label | name | CSS | XPath | strict locator.
1906
+ * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
1807
1907
  * @returns {void} automatically synchronized promise through #recorder
1808
1908
  *
1809
- *
1810
- * [Additional options](https://playwright.dev/docs/api/class-elementhandle#element-handle-uncheck) for uncheck available as 3rd argument.
1811
- *
1812
- * Examples:
1813
- *
1814
- * ```js
1815
- * // click on element at position
1816
- * I.uncheckOption('Agree', '.signup', { position: { x: 5, y: 5 } })
1817
- * ```
1818
- * > ⚠️ To avoid flakiness, option `force: true` is set by default
1819
1909
  */
1820
1910
  async uncheckOption(field, context = null, options = { force: true }) {
1821
1911
  const elm = await this._locateCheckable(field, context);
@@ -1832,7 +1922,7 @@ class Playwright extends Helper {
1832
1922
  * I.seeCheckboxIsChecked({css: '#signup_form input[type=checkbox]'});
1833
1923
  * ```
1834
1924
  *
1835
- * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1925
+ * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1836
1926
  * @returns {void} automatically synchronized promise through #recorder
1837
1927
  *
1838
1928
  */
@@ -1849,7 +1939,7 @@ class Playwright extends Helper {
1849
1939
  * I.dontSeeCheckboxIsChecked('agree'); // located by name
1850
1940
  * ```
1851
1941
  *
1852
- * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
1942
+ * @param {string | object} field located by label|name|CSS|XPath|strict locator.
1853
1943
  * @returns {void} automatically synchronized promise through #recorder
1854
1944
  *
1855
1945
  */
@@ -1900,6 +1990,9 @@ class Playwright extends Helper {
1900
1990
  }
1901
1991
 
1902
1992
  /**
1993
+ *
1994
+ * _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/Puppeteer#1313](https://github.com/GoogleChrome/puppeteer/issues/1313)).
1995
+ *
1903
1996
  * Presses a key in the browser (on a focused element).
1904
1997
  *
1905
1998
  * _Hint:_ For populating text field or textarea, it is recommended to use [`fillField`](#fillfield).
@@ -1961,8 +2054,6 @@ class Playwright extends Helper {
1961
2054
  * @param {string|string[]} key key or array of keys to press.
1962
2055
  * @returns {void} automatically synchronized promise through #recorder
1963
2056
  *
1964
- *
1965
- * _Note:_ Shortcuts like `'Meta'` + `'A'` do not work on macOS ([GoogleChrome/Puppeteer#1313](https://github.com/GoogleChrome/puppeteer/issues/1313)).
1966
2057
  */
1967
2058
  async pressKey(key) {
1968
2059
  const modifiers = [];
@@ -2039,8 +2130,8 @@ class Playwright extends Helper {
2039
2130
  * // or by strict locator
2040
2131
  * I.fillField({css: 'form#login input[name=username]'}, 'John');
2041
2132
  * ```
2042
- * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
2043
- * @param {CodeceptJS.StringOrSecret} value text value to fill.
2133
+ * @param {string | object} field located by label|name|CSS|XPath|strict locator.
2134
+ * @param {string | object} value text value to fill.
2044
2135
  * @returns {void} automatically synchronized promise through #recorder
2045
2136
  *
2046
2137
  *
@@ -2073,7 +2164,7 @@ class Playwright extends Helper {
2073
2164
  * ```
2074
2165
  * Use `force` to bypass the [actionability](https://playwright.dev/docs/actionability) checks.
2075
2166
  *
2076
- * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2167
+ * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
2077
2168
  * @param {any} [options] [Additional options](https://playwright.dev/docs/api/class-locator#locator-clear) for available options object as 2nd argument.
2078
2169
  */
2079
2170
  async clearField(locator, options = {}) {
@@ -2098,12 +2189,10 @@ class Playwright extends Helper {
2098
2189
  * // typing secret
2099
2190
  * I.appendField('password', secret('123456'));
2100
2191
  * ```
2101
- * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator
2192
+ * @param {string | object} field located by label|name|CSS|XPath|strict locator
2102
2193
  * @param {string} value text value to append.
2103
2194
  * @returns {void} automatically synchronized promise through #recorder
2104
2195
  *
2105
- *
2106
- *
2107
2196
  */
2108
2197
  async appendField(field, value) {
2109
2198
  const els = await findFields.call(this, field);
@@ -2124,8 +2213,8 @@ class Playwright extends Helper {
2124
2213
  * I.seeInField('form input[type=hidden]','hidden_value');
2125
2214
  * I.seeInField('#searchform input','Search');
2126
2215
  * ```
2127
- * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
2128
- * @param {CodeceptJS.StringOrSecret} value value to check.
2216
+ * @param {string | object} field located by label|name|CSS|XPath|strict locator.
2217
+ * @param {string | object} value value to check.
2129
2218
  * @returns {void} automatically synchronized promise through #recorder
2130
2219
  *
2131
2220
  */
@@ -2143,8 +2232,8 @@ class Playwright extends Helper {
2143
2232
  * I.dontSeeInField({ css: 'form input.email' }, 'user@user.com'); // field by CSS
2144
2233
  * ```
2145
2234
  *
2146
- * @param {CodeceptJS.LocatorOrString} field located by label|name|CSS|XPath|strict locator.
2147
- * @param {CodeceptJS.StringOrSecret} value value to check.
2235
+ * @param {string | object} field located by label|name|CSS|XPath|strict locator.
2236
+ * @param {string | object} value value to check.
2148
2237
  * @returns {void} automatically synchronized promise through #recorder
2149
2238
  *
2150
2239
  */
@@ -2163,7 +2252,7 @@ class Playwright extends Helper {
2163
2252
  * I.attachFile('form input[name=avatar]', 'data/avatar.jpg');
2164
2253
  * ```
2165
2254
  *
2166
- * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2255
+ * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
2167
2256
  * @param {string} pathToFile local file path relative to codecept.conf.ts or codecept.conf.js config file.
2168
2257
  * @returns {void} automatically synchronized promise through #recorder
2169
2258
  *
@@ -2200,7 +2289,7 @@ class Playwright extends Helper {
2200
2289
  * ```js
2201
2290
  * I.selectOption('Which OS do you use?', ['Android', 'iOS']);
2202
2291
  * ```
2203
- * @param {LocatorOrString} select field located by label|name|CSS|XPath|strict locator.
2292
+ * @param {string | object} select field located by label|name|CSS|XPath|strict locator.
2204
2293
  * @param {string|Array<*>} option visible text or value of option.
2205
2294
  * @returns {void} automatically synchronized promise through #recorder
2206
2295
  *
@@ -2211,8 +2300,15 @@ class Playwright extends Helper {
2211
2300
  const el = els[0];
2212
2301
 
2213
2302
  await highlightActiveElement.call(this, el);
2303
+ let optionToSelect = '';
2214
2304
 
2215
- if (!Array.isArray(option)) option = [option];
2305
+ try {
2306
+ optionToSelect = await el.locator('option', { hasText: option }).textContent();
2307
+ } catch (e) {
2308
+ optionToSelect = option;
2309
+ }
2310
+
2311
+ if (!Array.isArray(option)) option = [optionToSelect];
2216
2312
 
2217
2313
  await el.selectOption(option);
2218
2314
  return this._waitForAction();
@@ -2226,7 +2322,7 @@ class Playwright extends Helper {
2226
2322
  * let numOfElements = await I.grabNumberOfVisibleElements('p');
2227
2323
  * ```
2228
2324
  *
2229
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2325
+ * @param {string | object} locator located by CSS|XPath|strict locator.
2230
2326
  * @returns {Promise<number>} number of visible elements
2231
2327
  *
2232
2328
  */
@@ -2307,7 +2403,7 @@ class Playwright extends Helper {
2307
2403
  * I.see('Register', {css: 'form.register'}); // use strict locator
2308
2404
  * ```
2309
2405
  * @param {string} text expected on page.
2310
- * @param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
2406
+ * @param {?string | object} [context=null] (optional, `null` by default) element located by CSS|Xpath|strict locator in which to search for text.
2311
2407
  * @returns {void} automatically synchronized promise through #recorder
2312
2408
  *
2313
2409
  *
@@ -2325,7 +2421,7 @@ class Playwright extends Helper {
2325
2421
  * ```
2326
2422
  *
2327
2423
  * @param {string} text element value to check.
2328
- * @param {CodeceptJS.LocatorOrString?} [context=null] element located by CSS|XPath|strict locator.
2424
+ * @param {(string | object)?} [context=null] element located by CSS|XPath|strict locator.
2329
2425
  * @returns {void} automatically synchronized promise through #recorder
2330
2426
  *
2331
2427
  */
@@ -2343,7 +2439,7 @@ class Playwright extends Helper {
2343
2439
  * ```
2344
2440
  *
2345
2441
  * @param {string} text which is not present.
2346
- * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
2442
+ * @param {string | object} [context] (optional) element located by CSS|XPath|strict locator in which to perfrom search.
2347
2443
  * @returns {void} automatically synchronized promise through #recorder
2348
2444
  *
2349
2445
  *
@@ -2439,7 +2535,7 @@ class Playwright extends Helper {
2439
2535
  * I.seeNumberOfElements('#submitBtn', 1);
2440
2536
  * ```
2441
2537
  *
2442
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2538
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2443
2539
  * @param {number} num number of elements.
2444
2540
  * @returns {void} automatically synchronized promise through #recorder
2445
2541
  *
@@ -2459,7 +2555,7 @@ class Playwright extends Helper {
2459
2555
  * I.seeNumberOfVisibleElements('.buttons', 3);
2460
2556
  * ```
2461
2557
  *
2462
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2558
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2463
2559
  * @param {number} num number of elements.
2464
2560
  * @returns {void} automatically synchronized promise through #recorder
2465
2561
  *
@@ -2531,6 +2627,8 @@ class Playwright extends Helper {
2531
2627
  }
2532
2628
 
2533
2629
  /**
2630
+ * Returns cookie in JSON format. If name not passed returns all cookies for this domain.
2631
+ *
2534
2632
  * Gets a cookie object by name.
2535
2633
  * If none provided gets all cookies.
2536
2634
  * Resumes test execution, so **should be used inside async function with `await`** operator.
@@ -2543,8 +2641,6 @@ class Playwright extends Helper {
2543
2641
  * @param {?string} [name=null] cookie name.
2544
2642
  * @returns {any} attribute value
2545
2643
  *
2546
- *
2547
- * Returns cookie in JSON format. If name not passed returns all cookies for this domain.
2548
2644
  */
2549
2645
  async grabCookie(name) {
2550
2646
  const cookies = await this.browserContext.cookies();
@@ -2584,8 +2680,8 @@ class Playwright extends Helper {
2584
2680
  * ```js
2585
2681
  * I.executeScript(({x, y}) => x + y, {x, y});
2586
2682
  * ```
2587
- * You can pass only one parameter into a function
2588
- * but you can pass in array or object.
2683
+ * You can pass only one parameter into a function,
2684
+ * or you can pass in array or object.
2589
2685
  *
2590
2686
  * ```js
2591
2687
  * I.executeScript(([x, y]) => x + y, [x, y]);
@@ -2629,7 +2725,7 @@ class Playwright extends Helper {
2629
2725
  * ```
2630
2726
  * If multiple elements found returns first element.
2631
2727
  *
2632
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2728
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2633
2729
  * @returns {Promise<string>} attribute value
2634
2730
  *
2635
2731
  *
@@ -2650,7 +2746,7 @@ class Playwright extends Helper {
2650
2746
  * let pins = await I.grabTextFromAll('#pin li');
2651
2747
  * ```
2652
2748
  *
2653
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2749
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2654
2750
  * @returns {Promise<string[]>} attribute value
2655
2751
  *
2656
2752
  *
@@ -2673,7 +2769,7 @@ class Playwright extends Helper {
2673
2769
  * ```js
2674
2770
  * let email = await I.grabValueFrom('input[name=email]');
2675
2771
  * ```
2676
- * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2772
+ * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
2677
2773
  * @returns {Promise<string>} attribute value
2678
2774
  *
2679
2775
  */
@@ -2691,7 +2787,7 @@ class Playwright extends Helper {
2691
2787
  * ```js
2692
2788
  * let inputs = await I.grabValueFromAll('//form/input');
2693
2789
  * ```
2694
- * @param {CodeceptJS.LocatorOrString} locator field located by label|name|CSS|XPath|strict locator.
2790
+ * @param {string | object} locator field located by label|name|CSS|XPath|strict locator.
2695
2791
  * @returns {Promise<string[]>} attribute value
2696
2792
  *
2697
2793
  */
@@ -2710,7 +2806,7 @@ class Playwright extends Helper {
2710
2806
  * let postHTML = await I.grabHTMLFrom('#post');
2711
2807
  * ```
2712
2808
  *
2713
- * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator.
2809
+ * @param {string | object} element located by CSS|XPath|strict locator.
2714
2810
  * @returns {Promise<string>} HTML code for an element
2715
2811
  *
2716
2812
  */
@@ -2729,7 +2825,7 @@ class Playwright extends Helper {
2729
2825
  * let postHTMLs = await I.grabHTMLFromAll('.post');
2730
2826
  * ```
2731
2827
  *
2732
- * @param {CodeceptJS.LocatorOrString} element located by CSS|XPath|strict locator.
2828
+ * @param {string | object} element located by CSS|XPath|strict locator.
2733
2829
  * @returns {Promise<string[]>} HTML code for an element
2734
2830
  *
2735
2831
  */
@@ -2748,7 +2844,7 @@ class Playwright extends Helper {
2748
2844
  * const value = await I.grabCssPropertyFrom('h3', 'font-weight');
2749
2845
  * ```
2750
2846
  *
2751
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2847
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2752
2848
  * @param {string} cssProperty CSS property name.
2753
2849
  * @returns {Promise<string>} CSS value
2754
2850
  *
@@ -2769,7 +2865,7 @@ class Playwright extends Helper {
2769
2865
  * const values = await I.grabCssPropertyFromAll('h3', 'font-weight');
2770
2866
  * ```
2771
2867
  *
2772
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
2868
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2773
2869
  * @param {string} cssProperty CSS property name.
2774
2870
  * @returns {Promise<string[]>} CSS value
2775
2871
  *
@@ -2790,7 +2886,7 @@ class Playwright extends Helper {
2790
2886
  * I.seeCssPropertiesOnElements('h3', { 'font-weight': "bold"});
2791
2887
  * ```
2792
2888
  *
2793
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2889
+ * @param {string | object} locator located by CSS|XPath|strict locator.
2794
2890
  * @param {object} cssProperties object with CSS properties and their values to check.
2795
2891
  * @returns {void} automatically synchronized promise through #recorder
2796
2892
  *
@@ -2802,19 +2898,17 @@ class Playwright extends Helper {
2802
2898
 
2803
2899
  const cssPropertiesCamelCase = convertCssPropertiesToCamelCase(cssProperties);
2804
2900
  const elemAmount = res.length;
2805
- const commands = [];
2806
2901
  let props = [];
2807
2902
 
2808
2903
  for (const element of res) {
2809
- const cssProperties = await element.evaluate((el) => getComputedStyle(el));
2810
-
2811
- Object.keys(cssPropertiesCamelCase).forEach(prop => {
2904
+ for (const prop of Object.keys(cssProperties)) {
2905
+ const cssProp = await this.grabCssPropertyFrom(locator, prop);
2812
2906
  if (isColorProperty(prop)) {
2813
- props.push(convertColorToRGBA(cssProperties[prop]));
2907
+ props.push(convertColorToRGBA(cssProp));
2814
2908
  } else {
2815
- props.push(cssProperties[prop]);
2909
+ props.push(cssProp);
2816
2910
  }
2817
- });
2911
+ }
2818
2912
  }
2819
2913
 
2820
2914
  const values = Object.keys(cssPropertiesCamelCase).map(key => cssPropertiesCamelCase[key]);
@@ -2822,7 +2916,8 @@ class Playwright extends Helper {
2822
2916
  let chunked = chunkArray(props, values.length);
2823
2917
  chunked = chunked.filter((val) => {
2824
2918
  for (let i = 0; i < val.length; ++i) {
2825
- if (val[i] !== values[i]) return false;
2919
+ // eslint-disable-next-line eqeqeq
2920
+ if (val[i] != values[i]) return false;
2826
2921
  }
2827
2922
  return true;
2828
2923
  });
@@ -2836,7 +2931,7 @@ class Playwright extends Helper {
2836
2931
  * I.seeAttributesOnElements('//form', { method: "post"});
2837
2932
  * ```
2838
2933
  *
2839
- * @param {CodeceptJS.LocatorOrString} locator located by CSS|XPath|strict locator.
2934
+ * @param {string | object} locator located by CSS|XPath|strict locator.
2840
2935
  * @param {object} attributes attributes and their values to check.
2841
2936
  * @returns {void} automatically synchronized promise through #recorder
2842
2937
  *
@@ -2860,7 +2955,8 @@ class Playwright extends Helper {
2860
2955
  let chunked = chunkArray(attrs, values.length);
2861
2956
  chunked = chunked.filter((val) => {
2862
2957
  for (let i = 0; i < val.length; ++i) {
2863
- if (val[i] !== values[i]) return false;
2958
+ // if the attribute doesn't exist, returns false as well
2959
+ if (!val[i] || !val[i].includes(values[i])) return false;
2864
2960
  }
2865
2961
  return true;
2866
2962
  });
@@ -2876,7 +2972,7 @@ class Playwright extends Helper {
2876
2972
  * I.dragSlider('#slider', -70);
2877
2973
  * ```
2878
2974
  *
2879
- * @param {CodeceptJS.LocatorOrString} locator located by label|name|CSS|XPath|strict locator.
2975
+ * @param {string | object} locator located by label|name|CSS|XPath|strict locator.
2880
2976
  * @param {number} offsetX position to drag.
2881
2977
  * @returns {void} automatically synchronized promise through #recorder
2882
2978
  *
@@ -2908,7 +3004,7 @@ class Playwright extends Helper {
2908
3004
  * ```js
2909
3005
  * let hint = await I.grabAttributeFrom('#tooltip', 'title');
2910
3006
  * ```
2911
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3007
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2912
3008
  * @param {string} attr attribute name.
2913
3009
  * @returns {Promise<string>} attribute value
2914
3010
  *
@@ -2928,7 +3024,7 @@ class Playwright extends Helper {
2928
3024
  * ```js
2929
3025
  * let hints = await I.grabAttributeFromAll('.tooltip', 'title');
2930
3026
  * ```
2931
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3027
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2932
3028
  * @param {string} attr attribute name.
2933
3029
  * @returns {Promise<string[]>} attribute value
2934
3030
  *
@@ -2954,7 +3050,7 @@ class Playwright extends Helper {
2954
3050
  * I.saveElementScreenshot(`#submit`,'debug.png');
2955
3051
  * ```
2956
3052
  *
2957
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3053
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
2958
3054
  * @param {string} fileName file name to save.
2959
3055
  * @returns {void} automatically synchronized promise through #recorder
2960
3056
  *
@@ -3083,6 +3179,10 @@ class Playwright extends Helper {
3083
3179
  test.artifacts[`trace_${sessionName}`] = await saveTraceForContext(this.sessionPages[sessionName].context, `${test.title}_${sessionName}.failed`);
3084
3180
  }
3085
3181
  }
3182
+
3183
+ if (this.options.recordHar) {
3184
+ test.artifacts.har = this.currentRunningTest.artifacts.har;
3185
+ }
3086
3186
  }
3087
3187
 
3088
3188
  async _passed(test) {
@@ -3110,6 +3210,10 @@ class Playwright extends Helper {
3110
3210
  await this.browserContext.tracing.stop();
3111
3211
  }
3112
3212
  }
3213
+
3214
+ if (this.options.recordHar) {
3215
+ test.artifacts.har = this.currentRunningTest.artifacts.har;
3216
+ }
3113
3217
  }
3114
3218
 
3115
3219
  /**
@@ -3133,7 +3237,7 @@ class Playwright extends Helper {
3133
3237
  * Waits for element to become enabled (by default waits for 1sec).
3134
3238
  * Element can be located by CSS or XPath.
3135
3239
  *
3136
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3240
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3137
3241
  * @param {number} [sec=1] (optional) time in seconds to wait, 1 by default.
3138
3242
  * @returns {void} automatically synchronized promise through #recorder
3139
3243
  *
@@ -3168,7 +3272,7 @@ class Playwright extends Helper {
3168
3272
  * I.waitForValue('//input', "GoodValue");
3169
3273
  * ```
3170
3274
  *
3171
- * @param {LocatorOrString} field input field.
3275
+ * @param {string | object} field input field.
3172
3276
  * @param {string }value expected value.
3173
3277
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3174
3278
  * @returns {void} automatically synchronized promise through #recorder
@@ -3205,7 +3309,7 @@ class Playwright extends Helper {
3205
3309
  * I.waitNumberOfVisibleElements('a', 3);
3206
3310
  * ```
3207
3311
  *
3208
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3312
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3209
3313
  * @param {number} num number of elements.
3210
3314
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3211
3315
  * @returns {void} automatically synchronized promise through #recorder
@@ -3248,7 +3352,7 @@ class Playwright extends Helper {
3248
3352
  * I.waitForClickable('.btn.continue', 5); // wait for 5 secs
3249
3353
  * ```
3250
3354
  *
3251
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3355
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3252
3356
  * @param {number} [sec] (optional, `1` by default) time in seconds to wait
3253
3357
  * @returns {void} automatically synchronized promise through #recorder
3254
3358
  *
@@ -3267,7 +3371,7 @@ class Playwright extends Helper {
3267
3371
  * I.waitForElement('.btn.continue', 5); // wait for 5 secs
3268
3372
  * ```
3269
3373
  *
3270
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3374
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3271
3375
  * @param {number} [sec] (optional, `1` by default) time in seconds to wait
3272
3376
  * @returns {void} automatically synchronized promise through #recorder
3273
3377
  *
@@ -3286,6 +3390,8 @@ class Playwright extends Helper {
3286
3390
  }
3287
3391
 
3288
3392
  /**
3393
+ * This method accepts [React selectors](https://codecept.io/react).
3394
+ *
3289
3395
  * Waits for an element to become visible on a page (by default waits for 1sec).
3290
3396
  * Element can be located by CSS or XPath.
3291
3397
  *
@@ -3293,12 +3399,10 @@ class Playwright extends Helper {
3293
3399
  * I.waitForVisible('#popup');
3294
3400
  * ```
3295
3401
  *
3296
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3402
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3297
3403
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3298
3404
  * @returns {void} automatically synchronized promise through #recorder
3299
3405
  *
3300
- *
3301
- * This method accepts [React selectors](https://codecept.io/react).
3302
3406
  */
3303
3407
  async waitForVisible(locator, sec) {
3304
3408
  const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
@@ -3334,7 +3438,7 @@ class Playwright extends Helper {
3334
3438
  * I.waitForInvisible('#popup');
3335
3439
  * ```
3336
3440
  *
3337
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3441
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3338
3442
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3339
3443
  * @returns {void} automatically synchronized promise through #recorder
3340
3444
  *
@@ -3374,7 +3478,7 @@ class Playwright extends Helper {
3374
3478
  * I.waitToHide('#popup');
3375
3479
  * ```
3376
3480
  *
3377
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3481
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3378
3482
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3379
3483
  * @returns {void} automatically synchronized promise through #recorder
3380
3484
  *
@@ -3485,7 +3589,7 @@ class Playwright extends Helper {
3485
3589
  *
3486
3590
  * @param {string }text to wait for.
3487
3591
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3488
- * @param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
3592
+ * @param {string | object} [context] (optional) element located by CSS|XPath|strict locator.
3489
3593
  * @returns {void} automatically synchronized promise through #recorder
3490
3594
  *
3491
3595
  */
@@ -3520,7 +3624,7 @@ class Playwright extends Helper {
3520
3624
  const _contextObject = this.frame ? this.frame : contextObject;
3521
3625
  let count = 0;
3522
3626
  do {
3523
- waiter = await _contextObject.locator(`:has-text('${text}')`).first().isVisible();
3627
+ waiter = await _contextObject.locator(`:has-text("${text}")`).first().isVisible();
3524
3628
  if (waiter) break;
3525
3629
  await this.wait(1);
3526
3630
  count += 1000;
@@ -3570,7 +3674,7 @@ class Playwright extends Helper {
3570
3674
  * I.switchTo(); // switch back to main page
3571
3675
  * ```
3572
3676
  *
3573
- * @param {?CodeceptJS.LocatorOrString} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
3677
+ * @param {?string | object} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
3574
3678
  * @returns {void} automatically synchronized promise through #recorder
3575
3679
  *
3576
3680
  */
@@ -3710,7 +3814,7 @@ class Playwright extends Helper {
3710
3814
  * I.waitForDetached('#popup');
3711
3815
  * ```
3712
3816
  *
3713
- * @param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
3817
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3714
3818
  * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3715
3819
  * @returns {void} automatically synchronized promise through #recorder
3716
3820
  *
@@ -3788,7 +3892,7 @@ class Playwright extends Helper {
3788
3892
  * const width = await I.grabElementBoundingRect('h3', 'width');
3789
3893
  * // width == 527
3790
3894
  * ```
3791
- * @param {LocatorOrString} locator element located by CSS|XPath|strict locator.
3895
+ * @param {string | object} locator element located by CSS|XPath|strict locator.
3792
3896
  * @param {string=} elementSize x, y, width or height of the given element.
3793
3897
  * @returns {Promise<DOMRect>|Promise<number>} Element bounding rectangle
3794
3898
  *
@@ -4191,7 +4295,7 @@ class Playwright extends Helper {
4191
4295
  /**
4192
4296
  * Returns all URLs of all network requests recorded so far during execution of test scenario.
4193
4297
  *
4194
- * @return {string} List of URLs recorded as a string, seperaeted by new lines after each URL
4298
+ * @return {string} List of URLs recorded as a string, separated by new lines after each URL
4195
4299
  * @private
4196
4300
  */
4197
4301
  _getTrafficDump() {
@@ -4373,6 +4477,7 @@ function buildLocatorString(locator) {
4373
4477
 
4374
4478
  async function findElements(matcher, locator) {
4375
4479
  if (locator.react) return findReact(matcher, locator);
4480
+ if (locator.vue) return findVue(matcher, locator);
4376
4481
  locator = new Locator(locator, 'css');
4377
4482
 
4378
4483
  return matcher.locator(buildLocatorString(locator)).all();
@@ -4434,6 +4539,7 @@ async function proceedClick(locator, context = null, options = {}) {
4434
4539
 
4435
4540
  async function findClickable(matcher, locator) {
4436
4541
  if (locator.react) return findReact(matcher, locator);
4542
+ if (locator.vue) return findVue(matcher, locator);
4437
4543
 
4438
4544
  locator = new Locator(locator);
4439
4545
  if (!locator.isFuzzy()) return findElements.call(this, matcher, locator);