codeceptjs 3.1.3 → 3.2.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 (75) hide show
  1. package/CHANGELOG.md +75 -1
  2. package/README.md +2 -3
  3. package/bin/codecept.js +1 -0
  4. package/docs/advanced.md +99 -61
  5. package/docs/basics.md +27 -2
  6. package/docs/bdd.md +2 -2
  7. package/docs/build/Appium.js +62 -0
  8. package/docs/build/FileSystem.js +12 -1
  9. package/docs/build/Playwright.js +37 -33
  10. package/docs/build/Protractor.js +9 -24
  11. package/docs/build/Puppeteer.js +10 -28
  12. package/docs/build/REST.js +1 -0
  13. package/docs/build/WebDriver.js +2 -24
  14. package/docs/changelog.md +75 -1
  15. package/docs/configuration.md +8 -8
  16. package/docs/custom-helpers.md +2 -37
  17. package/docs/data.md +9 -9
  18. package/docs/helpers/Appium.md +240 -198
  19. package/docs/helpers/FileSystem.md +12 -2
  20. package/docs/helpers/Playwright.md +226 -225
  21. package/docs/helpers/Puppeteer.md +1 -17
  22. package/docs/helpers/REST.md +3 -1
  23. package/docs/helpers/WebDriver.md +1 -17
  24. package/docs/installation.md +1 -1
  25. package/docs/mobile-react-native-locators.md +3 -0
  26. package/docs/mobile.md +11 -11
  27. package/docs/nightmare.md +3 -3
  28. package/docs/pageobjects.md +2 -0
  29. package/docs/playwright.md +4 -4
  30. package/docs/plugins.md +138 -9
  31. package/docs/puppeteer.md +5 -5
  32. package/docs/reports.md +3 -3
  33. package/docs/testcafe.md +1 -1
  34. package/docs/translation.md +1 -1
  35. package/docs/visual.md +2 -2
  36. package/docs/vue.md +1 -1
  37. package/docs/webdriver.md +2 -2
  38. package/lib/actor.js +19 -1
  39. package/lib/cli.js +25 -20
  40. package/lib/codecept.js +2 -0
  41. package/lib/command/info.js +1 -1
  42. package/lib/command/workers/runTests.js +25 -7
  43. package/lib/config.js +12 -0
  44. package/lib/container.js +3 -1
  45. package/lib/helper/Appium.js +62 -0
  46. package/lib/helper/FileSystem.js +12 -1
  47. package/lib/helper/Playwright.js +37 -23
  48. package/lib/helper/Protractor.js +2 -14
  49. package/lib/helper/Puppeteer.js +3 -18
  50. package/lib/helper/REST.js +1 -0
  51. package/lib/helper/WebDriver.js +2 -14
  52. package/lib/interfaces/featureConfig.js +3 -0
  53. package/lib/interfaces/scenarioConfig.js +4 -0
  54. package/lib/listener/steps.js +21 -3
  55. package/lib/listener/timeout.js +72 -0
  56. package/lib/locator.js +3 -0
  57. package/lib/plugin/allure.js +6 -1
  58. package/lib/plugin/autoLogin.js +1 -1
  59. package/lib/plugin/retryFailedStep.js +4 -3
  60. package/lib/plugin/retryTo.js +130 -0
  61. package/lib/plugin/screenshotOnFail.js +1 -0
  62. package/lib/plugin/stepByStepReport.js +7 -0
  63. package/lib/plugin/stepTimeout.js +91 -0
  64. package/lib/plugin/tryTo.js +6 -0
  65. package/lib/recorder.js +18 -6
  66. package/lib/step.js +58 -0
  67. package/lib/store.js +2 -0
  68. package/lib/ui.js +2 -2
  69. package/package.json +4 -6
  70. package/typings/index.d.ts +8 -1
  71. package/typings/types.d.ts +149 -164
  72. package/docs/angular.md +0 -325
  73. package/docs/helpers/Protractor.md +0 -1658
  74. package/docs/webapi/waitUntil.mustache +0 -11
  75. package/typings/Protractor.d.ts +0 -16
@@ -331,6 +331,7 @@ class Appium extends Webdriver {
331
331
  *
332
332
  * @param {*} caps
333
333
  * @param {*} fn
334
+ * @return {Promise<any>}
334
335
  */
335
336
  async runOnIOS(caps, fn) {
336
337
  if (this.platform !== 'ios') return;
@@ -373,6 +374,7 @@ class Appium extends Webdriver {
373
374
  *
374
375
  * @param {*} caps
375
376
  * @param {*} fn
377
+ * @return {Promise<any>}
376
378
  */
377
379
  async runOnAndroid(caps, fn) {
378
380
  if (this.platform !== 'android') return;
@@ -393,6 +395,7 @@ class Appium extends Webdriver {
393
395
  * ```
394
396
  *
395
397
  * @param {*} fn
398
+ * @return {Promise<any>}
396
399
  */
397
400
  /* eslint-disable */
398
401
  async runInWeb(fn) {
@@ -434,6 +437,7 @@ class Appium extends Webdriver {
434
437
  * ```
435
438
  *
436
439
  * @param {string} bundleId String ID of bundled app
440
+ * @return {Promise<void>}
437
441
  *
438
442
  * Appium: support only Android
439
443
  */
@@ -451,6 +455,7 @@ class Appium extends Webdriver {
451
455
  * ```
452
456
  *
453
457
  * @param {string} bundleId String ID of bundled app
458
+ * @return {Promise<void>}
454
459
  *
455
460
  * Appium: support only Android
456
461
  */
@@ -467,6 +472,7 @@ class Appium extends Webdriver {
467
472
  * I.installApp('/path/to/file.apk');
468
473
  * ```
469
474
  * @param {string} path path to apk file
475
+ * @return {Promise<void>}
470
476
  *
471
477
  * Appium: support only Android
472
478
  */
@@ -508,6 +514,7 @@ class Appium extends Webdriver {
508
514
  * I.seeCurrentActivityIs(".HomeScreenActivity")
509
515
  * ```
510
516
  * @param {string} currentActivity
517
+ * @return {Promise<void>}
511
518
  *
512
519
  * Appium: support only Android
513
520
  */
@@ -524,6 +531,8 @@ class Appium extends Webdriver {
524
531
  * I.seeDeviceIsLocked();
525
532
  * ```
526
533
  *
534
+ * @return {Promise<void>}
535
+ *
527
536
  * Appium: support only Android
528
537
  */
529
538
  async seeDeviceIsLocked() {
@@ -539,6 +548,8 @@ class Appium extends Webdriver {
539
548
  * I.seeDeviceIsUnlocked();
540
549
  * ```
541
550
  *
551
+ * @return {Promise<void>}
552
+ *
542
553
  * Appium: support only Android
543
554
  */
544
555
  async seeDeviceIsUnlocked() {
@@ -555,6 +566,8 @@ class Appium extends Webdriver {
555
566
  * I.seeOrientationIs('LANDSCAPE')
556
567
  * ```
557
568
  *
569
+ * @return {Promise<void>}
570
+ *
558
571
  * @param {'LANDSCAPE'|'PORTRAIT'} orientation LANDSCAPE or PORTRAIT
559
572
  *
560
573
  * Appium: support Android and iOS
@@ -586,6 +599,7 @@ class Appium extends Webdriver {
586
599
  * ```
587
600
  *
588
601
  * @param {'LANDSCAPE'|'PORTRAIT'} orientation LANDSCAPE or PORTRAIT
602
+ * @return {Promise<any>}
589
603
  *
590
604
  * Appium: support Android and iOS
591
605
  */
@@ -609,6 +623,8 @@ class Appium extends Webdriver {
609
623
  * let contexts = await I.grabAllContexts();
610
624
  * ```
611
625
  *
626
+ * @return {Promise<string[]>}
627
+ *
612
628
  * Appium: support Android and iOS
613
629
  */
614
630
  async grabAllContexts() {
@@ -623,6 +639,8 @@ class Appium extends Webdriver {
623
639
  * let context = await I.grabContext();
624
640
  * ```
625
641
  *
642
+ * @return {Promise<string|null>}
643
+ *
626
644
  * Appium: support Android and iOS
627
645
  */
628
646
  async grabContext() {
@@ -637,6 +655,8 @@ class Appium extends Webdriver {
637
655
  * let activity = await I.grabCurrentActivity();
638
656
  * ```
639
657
  *
658
+ * @return {Promise<string>}
659
+ *
640
660
  * Appium: support only Android
641
661
  */
642
662
  async grabCurrentActivity() {
@@ -653,6 +673,8 @@ class Appium extends Webdriver {
653
673
  * let con = await I.grabNetworkConnection();
654
674
  * ```
655
675
  *
676
+ * @return {Promise<{}>}
677
+ *
656
678
  * Appium: support only Android
657
679
  */
658
680
  async grabNetworkConnection() {
@@ -673,6 +695,8 @@ class Appium extends Webdriver {
673
695
  * let orientation = await I.grabOrientation();
674
696
  * ```
675
697
  *
698
+ * @return {Promise<string>}
699
+ *
676
700
  * Appium: support Android and iOS
677
701
  */
678
702
  async grabOrientation() {
@@ -689,6 +713,8 @@ class Appium extends Webdriver {
689
713
  * let settings = await I.grabSettings();
690
714
  * ```
691
715
  *
716
+ * @return {Promise<string>}
717
+ *
692
718
  * Appium: support Android and iOS
693
719
  */
694
720
  async grabSettings() {
@@ -720,6 +746,8 @@ class Appium extends Webdriver {
720
746
  * I.switchToWeb('WEBVIEW_io.selendroid.testapp');
721
747
  * ```
722
748
  *
749
+ * @return {Promise<void>}
750
+ *
723
751
  * @param {string} [context]
724
752
  */
725
753
  async switchToWeb(context) {
@@ -747,6 +775,7 @@ class Appium extends Webdriver {
747
775
  * I.switchToNative('SOME_OTHER_CONTEXT');
748
776
  * ```
749
777
  * @param {*} context
778
+ * @return {Promise<void>}
750
779
  */
751
780
  async switchToNative(context = null) {
752
781
  this.isWeb = false;
@@ -763,6 +792,8 @@ class Appium extends Webdriver {
763
792
  * I.startActivity('io.selendroid.testapp', '.RegisterUserActivity');
764
793
  * ```
765
794
  *
795
+ * @return {Promise<void>}
796
+ *
766
797
  * Appium: support only Android
767
798
  */
768
799
  async startActivity(appPackage, appActivity) {
@@ -786,6 +817,8 @@ class Appium extends Webdriver {
786
817
  * ```
787
818
  * See corresponding [webdriverio reference](http://webdriver.io/api/mobile/setNetworkConnection.html).
788
819
  *
820
+ * @return {Promise<{}>}
821
+ *
789
822
  * Appium: support only Android
790
823
  */
791
824
  async setNetworkConnection(value) {
@@ -801,6 +834,7 @@ class Appium extends Webdriver {
801
834
  * ```
802
835
  *
803
836
  * @param {object} settings object
837
+ * @return {Promise<any>}
804
838
  *
805
839
  * Appium: support Android and iOS
806
840
  */
@@ -841,6 +875,7 @@ class Appium extends Webdriver {
841
875
  * ```
842
876
  *
843
877
  * @param {number} keyValue Device specific key value
878
+ * @return {Promise<void>}
844
879
  *
845
880
  * Appium: support only Android
846
881
  */
@@ -859,6 +894,8 @@ class Appium extends Webdriver {
859
894
  * I.openNotifications();
860
895
  * ```
861
896
  *
897
+ * @return {Promise<void>}
898
+ *
862
899
  * Appium: support only Android
863
900
  */
864
901
  async openNotifications() {
@@ -877,6 +914,8 @@ class Appium extends Webdriver {
877
914
  * I.makeTouchAction("~buttonStartWebviewCD", 'tap');
878
915
  * ```
879
916
  *
917
+ * @return {Promise<void>}
918
+ *
880
919
  * Appium: support Android and iOS
881
920
  */
882
921
  async makeTouchAction(locator, action) {
@@ -898,6 +937,8 @@ class Appium extends Webdriver {
898
937
  *
899
938
  * Shortcut for `makeTouchAction`
900
939
  *
940
+ * @return {Promise<void>}
941
+ *
901
942
  * @param {*} locator
902
943
  */
903
944
  async tap(locator) {
@@ -918,6 +959,7 @@ class Appium extends Webdriver {
918
959
  * @param {number} xoffset
919
960
  * @param {number} yoffset
920
961
  * @param {number} [speed=1000] (optional), 1000 by default
962
+ * @return {Promise<void>}
921
963
  *
922
964
  * Appium: support Android and iOS
923
965
  */
@@ -971,6 +1013,7 @@ class Appium extends Webdriver {
971
1013
  * @param {CodeceptJS.LocatorOrString} locator
972
1014
  * @param {number} [yoffset] (optional)
973
1015
  * @param {number} [speed=1000] (optional), 1000 by default
1016
+ * @return {Promise<void>}
974
1017
  *
975
1018
  * Appium: support Android and iOS
976
1019
  */
@@ -999,6 +1042,7 @@ class Appium extends Webdriver {
999
1042
  * @param {CodeceptJS.LocatorOrString} locator
1000
1043
  * @param {number} [xoffset] (optional)
1001
1044
  * @param {number} [speed=1000] (optional), 1000 by default
1045
+ * @return {Promise<void>}
1002
1046
  *
1003
1047
  * Appium: support Android and iOS
1004
1048
  */
@@ -1025,6 +1069,7 @@ class Appium extends Webdriver {
1025
1069
  * @param {CodeceptJS.LocatorOrString} locator
1026
1070
  * @param {number} [xoffset] (optional)
1027
1071
  * @param {number} [speed=1000] (optional), 1000 by default
1072
+ * @return {Promise<void>}
1028
1073
  *
1029
1074
  * Appium: support Android and iOS
1030
1075
  */
@@ -1051,6 +1096,7 @@ class Appium extends Webdriver {
1051
1096
  * @param {CodeceptJS.LocatorOrString} locator
1052
1097
  * @param {number} [yoffset] (optional)
1053
1098
  * @param {number} [speed=1000] (optional), 1000 by default
1099
+ * @return {Promise<void>}
1054
1100
  *
1055
1101
  * Appium: support Android and iOS
1056
1102
  */
@@ -1084,6 +1130,7 @@ class Appium extends Webdriver {
1084
1130
  * @param {number} timeout
1085
1131
  * @param {number} offset
1086
1132
  * @param {number} speed
1133
+ * @return {Promise<void>}
1087
1134
  *
1088
1135
  * Appium: support Android and iOS
1089
1136
  */
@@ -1181,6 +1228,10 @@ class Appium extends Webdriver {
1181
1228
  * I.pullFile('/storage/emulated/0/DCIM/logo.png', output_dir);
1182
1229
  * ```
1183
1230
  *
1231
+ * @param {string} path
1232
+ * @param {string} dest
1233
+ * @return {Promise<string>}
1234
+ *
1184
1235
  * Appium: support Android and iOS
1185
1236
  */
1186
1237
  async pullFile(path, dest) {
@@ -1200,6 +1251,8 @@ class Appium extends Webdriver {
1200
1251
  * I.shakeDevice();
1201
1252
  * ```
1202
1253
  *
1254
+ * @return {Promise<void>}
1255
+ *
1203
1256
  * Appium: support only iOS
1204
1257
  */
1205
1258
  async shakeDevice() {
@@ -1216,6 +1269,8 @@ class Appium extends Webdriver {
1216
1269
  *
1217
1270
  * See corresponding [webdriverio reference](http://webdriver.io/api/mobile/rotate.html).
1218
1271
  *
1272
+ * @return {Promise<void>}
1273
+ *
1219
1274
  * Appium: support only iOS
1220
1275
  */
1221
1276
  async rotate(x, y, duration, radius, rotation, touchCount) {
@@ -1228,6 +1283,8 @@ class Appium extends Webdriver {
1228
1283
  *
1229
1284
  * See corresponding [webdriverio reference](http://webdriver.io/api/mobile/setImmediateValue.html).
1230
1285
  *
1286
+ * @return {Promise<void>}
1287
+ *
1231
1288
  * Appium: support only iOS
1232
1289
  */
1233
1290
  async setImmediateValue(id, value) {
@@ -1244,6 +1301,8 @@ class Appium extends Webdriver {
1244
1301
  * I.touchId(false); // simulates invalid fingerprint
1245
1302
  * ```
1246
1303
  *
1304
+ * @return {Promise<void>}
1305
+ *
1247
1306
  * Appium: support only iOS
1248
1307
  * TODO: not tested
1249
1308
  */
@@ -1260,6 +1319,8 @@ class Appium extends Webdriver {
1260
1319
  * I.closeApp();
1261
1320
  * ```
1262
1321
  *
1322
+ * @return {Promise<void>}
1323
+ *
1263
1324
  * Appium: support only iOS
1264
1325
  */
1265
1326
  async closeApp() {
@@ -1564,6 +1625,7 @@ class Appium extends Webdriver {
1564
1625
  * ```
1565
1626
  *
1566
1627
  * @param {string} fileName file name to save.
1628
+ * @return {Promise<void>}
1567
1629
  */
1568
1630
  async saveScreenshot(fileName) {
1569
1631
  return super.saveScreenshot(fileName, false);
@@ -15,7 +15,17 @@ const { fileEquals } = require('../assert/equal');
15
15
  * I.amInPath('test');
16
16
  * I.seeFile('codecept.json');
17
17
  * I.seeInThisFile('FileSystem');
18
- * I.dontSeeInThisFile("WebDriverIO");
18
+ * I.dontSeeInThisFile("WebDriver");
19
+ * ```
20
+ *
21
+ * ## Configuration
22
+ *
23
+ * Enable helper in config file:
24
+ *
25
+ * ```js
26
+ * helpers: {
27
+ * FileSystem: {},
28
+ * }
19
29
  * ```
20
30
  *
21
31
  * ## Methods
@@ -91,6 +101,7 @@ class FileSystem extends Helper {
91
101
  * I.amInPath('output/downloads');
92
102
  * I.seeFileNameMatching('.pdf');
93
103
  * ```
104
+ * @param {string} text
94
105
  */
95
106
  seeFileNameMatching(text) {
96
107
  assert.ok(
@@ -14,7 +14,6 @@ const {
14
14
  ucfirst,
15
15
  fileExists,
16
16
  chunkArray,
17
- toCamelCase,
18
17
  convertCssPropertiesToCamelCase,
19
18
  screenshotOutputFolder,
20
19
  getNormalizedKeyAttributeValue,
@@ -73,16 +72,18 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
73
72
  * * `keepBrowserState`: (optional, default: false) - keep browser state between tests when `restart` is set to false.
74
73
  * * `keepCookies`: (optional, default: false) - keep cookies between tests when `restart` is set to false.
75
74
  * * `waitForAction`: (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 100.
76
- * * `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/master/docs/api.md#pagewaitfornavigationoptions).
75
+ * * `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).
77
76
  * * `pressKeyDelay`: (optional, default: '10'). Delay between key presses in ms. Used when calling Playwrights page.type(...) in fillField/appendField
78
77
  * * `getPageTimeout` (optional, default: '0') config option to set maximum navigation time in milliseconds.
79
78
  * * `waitForTimeout`: (optional) default wait* timeout in ms. Default: 1000.
80
79
  * * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
81
80
  * * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
82
81
  * * `userAgent`: (optional) user-agent string.
82
+ * * `locale`: (optional) locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
83
83
  * * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
84
84
  * * `chromium`: (optional) pass additional chromium options
85
85
  * * `electron`: (optional) pass additional electron options
86
+ * * `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).
86
87
  *
87
88
  * #### Video Recording Customization
88
89
  *
@@ -197,6 +198,19 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
197
198
  * }
198
199
  * ```
199
200
  *
201
+ * #### Example #7: Launch test with a specifc user locale
202
+ *
203
+ * ```js
204
+ * {
205
+ * helpers: {
206
+ * Playwright : {
207
+ * url: "http://localhost",
208
+ * locale: "fr-FR",
209
+ * }
210
+ * }
211
+ * }
212
+ * ```
213
+ *
200
214
  * Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
201
215
  *
202
216
  * ## Access From Helpers
@@ -287,6 +301,11 @@ class Playwright extends Helper {
287
301
  headless: !this.options.show,
288
302
  ...this._getOptionsForBrowser(config),
289
303
  };
304
+
305
+ if (this.options.channel && this.options.browser === 'chromium') {
306
+ this.playwrightOptions.channel = this.options.channel;
307
+ }
308
+
290
309
  if (this.options.video) {
291
310
  this.options.recordVideo = { size: parseWindowSize(this.options.windowSize) };
292
311
  }
@@ -351,6 +370,7 @@ class Playwright extends Helper {
351
370
  return err.message.includes('context');
352
371
  },
353
372
  });
373
+
354
374
  if (this.options.restart && !this.options.manualStart) await this._startBrowser();
355
375
  if (!this.isRunning && !this.options.manualStart) await this._startBrowser();
356
376
 
@@ -371,6 +391,8 @@ class Playwright extends Helper {
371
391
  }
372
392
  if (this.options.recordVideo) contextOptions.recordVideo = this.options.recordVideo;
373
393
  if (this.storageState) contextOptions.storageState = this.storageState;
394
+ if (this.options.userAgent) contextOptions.userAgent = this.options.userAgent;
395
+ if (this.options.locale) contextOptions.locale = this.options.locale;
374
396
  this.browserContext = await this.browser.newContext(contextOptions); // Adding the HTTPSError ignore in the context so that we can ignore those errors
375
397
  }
376
398
 
@@ -484,10 +506,10 @@ class Playwright extends Helper {
484
506
  * First argument is a description of an action.
485
507
  * Second argument is async function that gets this helper as parameter.
486
508
  *
487
- * { [`page`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-page), [`context`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-context) [`browser`](https://github.com/microsoft/playwright/blob/master/docs/api.md#class-browser) } objects from Playwright API are available.
509
+ * { [`page`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-page.md), [`context`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browsercontext.md) [`browser`](https://github.com/microsoft/playwright/blob/main/docs/src/api/class-browser.md) } objects from Playwright API are available.
488
510
  *
489
511
  * ```js
490
- * I.usePlaywrightTo('emulate offline mode', async ({ context }) {
512
+ * I.usePlaywrightTo('emulate offline mode', async ({ context }) => {
491
513
  * await context.setOffline(true);
492
514
  * });
493
515
  * ```
@@ -569,6 +591,11 @@ class Playwright extends Helper {
569
591
  this.page = page;
570
592
  if (!page) return;
571
593
  page.setDefaultNavigationTimeout(this.options.getPageTimeout);
594
+
595
+ page.on('crash', async () => {
596
+ console.log('ERROR: Page has crashed, closing page!');
597
+ await page.close();
598
+ });
572
599
  this.context = await this.page;
573
600
  this.contextLocator = null;
574
601
  if (this.options.browser === 'chrome') {
@@ -1147,7 +1174,7 @@ class Playwright extends Helper {
1147
1174
  * I.openNewTab();
1148
1175
  * ```
1149
1176
  *
1150
- * You can pass in [page options](https://github.com/microsoft/playwright/blob/master/docs/api.md#browsernewpageoptions) to emulate device on this page
1177
+ * You can pass in [page options](https://github.com/microsoft/playwright/blob/main/docs/api.md#browsernewpageoptions) to emulate device on this page
1151
1178
  *
1152
1179
  * ```js
1153
1180
  * // enable mobile
@@ -2135,7 +2162,7 @@ class Playwright extends Helper {
2135
2162
  */
2136
2163
  async clearCookie() {
2137
2164
  // Playwright currently doesn't support to delete a certain cookie
2138
- // https://github.com/microsoft/playwright/blob/master/docs/api.md#class-browsercontext
2165
+ // https://github.com/microsoft/playwright/blob/main/docs/api.md#class-browsercontext
2139
2166
  if (!this.browserContext) return;
2140
2167
  return this.browserContext.clearCookies();
2141
2168
  }
@@ -2580,7 +2607,7 @@ class Playwright extends Helper {
2580
2607
  }
2581
2608
 
2582
2609
  if (this.options.trace) {
2583
- const path = `${global.output_dir}/trace/${clearString(test.title).slice(0, 255)}.zip`;
2610
+ const path = `${`${global.output_dir}/trace/${clearString(test.title)}`.slice(0, 251)}.zip`;
2584
2611
  await this.browserContext.tracing.stop({ path });
2585
2612
  test.artifacts.trace = path;
2586
2613
  }
@@ -2956,11 +2983,11 @@ class Playwright extends Helper {
2956
2983
  }
2957
2984
 
2958
2985
  /**
2959
- * Waits for a network request.
2986
+ * Waits for a network response.
2960
2987
  *
2961
2988
  * ```js
2962
2989
  * I.waitForResponse('http://example.com/resource');
2963
- * I.waitForResponse(request => request.url() === 'http://example.com' && request.method() === 'GET');
2990
+ * I.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
2964
2991
  * ```
2965
2992
  *
2966
2993
  * @param {string|function} urlOrPredicate
@@ -3069,26 +3096,6 @@ class Playwright extends Helper {
3069
3096
  return this.page.waitForNavigation(opts);
3070
3097
  }
3071
3098
 
3072
- /**
3073
- * Waits for a function to return true (waits for 1sec by default).
3074
- *
3075
- * ```js
3076
- * I.waitUntil(() => window.requests == 0);
3077
- * I.waitUntil(() => window.requests == 0, 5);
3078
- * ```
3079
- *
3080
- * @param {function|string} fn function which is executed in browser context.
3081
- * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3082
- * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
3083
- * @param {?number} [interval=null]
3084
- */
3085
- async waitUntil(fn, sec = null) {
3086
- console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
3087
- const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
3088
- const context = await this._getContext();
3089
- return context.waitForFunction(fn, { timeout: waitTimeout });
3090
- }
3091
-
3092
3099
  async waitUntilExists(locator, sec) {
3093
3100
  console.log(`waitUntilExists deprecated:
3094
3101
  * use 'waitForElement' to wait for element to be attached
@@ -3551,13 +3558,10 @@ async function targetCreatedHandler(page) {
3551
3558
  });
3552
3559
  });
3553
3560
  page.on('console', (msg) => {
3554
- this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg._text || '') + msg.args().join(' '));
3561
+ this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg.text && msg.text() || msg._text || '') + msg.args().join(' '));
3555
3562
  consoleLogStore.add(msg);
3556
3563
  });
3557
3564
 
3558
- if (this.options.userAgent) {
3559
- await page.setUserAgent(this.options.userAgent);
3560
- }
3561
3565
  if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && this._getType() === 'Browser') {
3562
3566
  await page.setViewportSize(parseWindowSize(this.options.windowSize));
3563
3567
  }
@@ -1181,11 +1181,14 @@ class Protractor extends Helper {
1181
1181
  }
1182
1182
 
1183
1183
  /**
1184
- * Checks that title is equal to provided one.
1185
- *
1186
- * ```js
1187
- * I.seeTitleEquals('Test title.');
1188
- * ```
1184
+ * Checks that title is equal to provided one.
1185
+ *
1186
+ * ```js
1187
+ * I.seeTitleEquals('Test title.');
1188
+ * ```
1189
+ *
1190
+ * @param {string} text value to check.
1191
+ *
1189
1192
  */
1190
1193
  async seeTitleEquals(text) {
1191
1194
  const title = await this.browser.getTitle();
@@ -1509,7 +1512,7 @@ class Protractor extends Helper {
1509
1512
  }
1510
1513
 
1511
1514
  /**
1512
- * Checks that current url contains a provided fragment.
1515
+ * Checks that current url contains a provided fragment.
1513
1516
  *
1514
1517
  * ```js
1515
1518
  * I.seeInCurrentUrl('/register'); // we are on registration page
@@ -2184,24 +2187,6 @@ class Protractor extends Helper {
2184
2187
  return this.browser.wait(() => this.browser.executeScript.call(this.browser, fn, ...args), aSec * 1000);
2185
2188
  }
2186
2189
 
2187
- /**
2188
- * Waits for a function to return true (waits for 1sec by default).
2189
- *
2190
- * ```js
2191
- * I.waitUntil(() => window.requests == 0);
2192
- * I.waitUntil(() => window.requests == 0, 5);
2193
- * ```
2194
- *
2195
- * @param {function|string} fn function which is executed in browser context.
2196
- * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
2197
- * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
2198
- * @param {?number} [interval=null]
2199
- */
2200
- async waitUntil(fn, sec = null, timeoutMsg = null) {
2201
- const aSec = sec || this.options.waitForTimeout;
2202
- return this.browser.wait(fn, aSec * 1000, timeoutMsg);
2203
- }
2204
-
2205
2190
  /**
2206
2191
  * Waiting for the part of the URL to match the expected. Useful for SPA to understand that page was changed.
2207
2192
  *
@@ -264,7 +264,7 @@ class Puppeteer extends Helper {
264
264
  async _before() {
265
265
  this.sessionPages = {};
266
266
  recorder.retry({
267
- retries: 5,
267
+ retries: 3,
268
268
  when: err => {
269
269
  if (!err || typeof (err.message) !== 'string') {
270
270
  return false;
@@ -561,10 +561,9 @@ class Puppeteer extends Helper {
561
561
  this.context = null;
562
562
  popupStore.clear();
563
563
  this.isAuthenticated = false;
564
+ await this.browser.close();
564
565
  if (this.isRemoteBrowser) {
565
566
  await this.browser.disconnect();
566
- } else {
567
- await this.browser.close();
568
567
  }
569
568
  }
570
569
 
@@ -852,11 +851,14 @@ class Puppeteer extends Helper {
852
851
  }
853
852
 
854
853
  /**
855
- * Checks that title is equal to provided one.
856
- *
857
- * ```js
858
- * I.seeTitleEquals('Test title.');
859
- * ```
854
+ * Checks that title is equal to provided one.
855
+ *
856
+ * ```js
857
+ * I.seeTitleEquals('Test title.');
858
+ * ```
859
+ *
860
+ * @param {string} text value to check.
861
+ *
860
862
  */
861
863
  async seeTitleEquals(text) {
862
864
  const title = await this.page.title();
@@ -3102,26 +3104,6 @@ class Puppeteer extends Helper {
3102
3104
  return this.page.waitForNavigation(opts);
3103
3105
  }
3104
3106
 
3105
- /**
3106
- * Waits for a function to return true (waits for 1sec by default).
3107
- *
3108
- * ```js
3109
- * I.waitUntil(() => window.requests == 0);
3110
- * I.waitUntil(() => window.requests == 0, 5);
3111
- * ```
3112
- *
3113
- * @param {function|string} fn function which is executed in browser context.
3114
- * @param {number} [sec=1] (optional, `1` by default) time in seconds to wait
3115
- * @param {string} [timeoutMsg=''] message to show in case of timeout fail.
3116
- * @param {?number} [interval=null]
3117
- */
3118
- async waitUntil(fn, sec = null) {
3119
- console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
3120
- const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
3121
- const context = await this._getContext();
3122
- return context.waitForFunction(fn, { timeout: waitTimeout });
3123
- }
3124
-
3125
3107
  async waitUntilExists(locator, sec) {
3126
3108
  console.log(`waitUntilExists deprecated:
3127
3109
  * use 'waitForElement' to wait for element to be attached
@@ -131,6 +131,7 @@ class REST extends Helper {
131
131
  * I.setRequestTimeout(10000); // In milliseconds
132
132
  * ```
133
133
  *
134
+ * @param {number} newTimeout - timeout in milliseconds
134
135
  */
135
136
  setRequestTimeout(newTimeout) {
136
137
  this.options.timeout = newTimeout;