codeceptjs 3.1.3 → 3.2.0

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 (54) hide show
  1. package/CHANGELOG.md +49 -1
  2. package/README.md +2 -3
  3. package/bin/codecept.js +1 -0
  4. package/docs/advanced.md +94 -60
  5. package/docs/basics.md +1 -1
  6. package/docs/build/FileSystem.js +1 -0
  7. package/docs/build/Playwright.js +19 -26
  8. package/docs/build/Protractor.js +9 -24
  9. package/docs/build/Puppeteer.js +9 -27
  10. package/docs/build/REST.js +1 -0
  11. package/docs/build/WebDriver.js +1 -23
  12. package/docs/changelog.md +49 -1
  13. package/docs/custom-helpers.md +1 -36
  14. package/docs/helpers/Appium.md +1 -1
  15. package/docs/helpers/FileSystem.md +1 -1
  16. package/docs/helpers/Playwright.md +16 -18
  17. package/docs/helpers/Puppeteer.md +1 -17
  18. package/docs/helpers/REST.md +3 -1
  19. package/docs/helpers/WebDriver.md +1 -17
  20. package/docs/mobile-react-native-locators.md +3 -0
  21. package/docs/plugins.md +125 -0
  22. package/docs/reports.md +2 -2
  23. package/lib/actor.js +19 -1
  24. package/lib/codecept.js +2 -0
  25. package/lib/command/info.js +1 -1
  26. package/lib/config.js +12 -0
  27. package/lib/container.js +3 -1
  28. package/lib/helper/FileSystem.js +1 -0
  29. package/lib/helper/Playwright.js +19 -16
  30. package/lib/helper/Protractor.js +2 -14
  31. package/lib/helper/Puppeteer.js +2 -17
  32. package/lib/helper/REST.js +1 -0
  33. package/lib/helper/WebDriver.js +1 -13
  34. package/lib/interfaces/featureConfig.js +3 -0
  35. package/lib/interfaces/scenarioConfig.js +4 -0
  36. package/lib/listener/steps.js +21 -3
  37. package/lib/listener/timeout.js +71 -0
  38. package/lib/locator.js +3 -0
  39. package/lib/plugin/allure.js +6 -1
  40. package/lib/plugin/retryTo.js +130 -0
  41. package/lib/plugin/screenshotOnFail.js +1 -0
  42. package/lib/plugin/stepByStepReport.js +7 -0
  43. package/lib/plugin/stepTimeout.js +90 -0
  44. package/lib/recorder.js +16 -5
  45. package/lib/step.js +3 -0
  46. package/lib/store.js +2 -0
  47. package/lib/ui.js +2 -2
  48. package/package.json +4 -6
  49. package/typings/index.d.ts +6 -1
  50. package/typings/types.d.ts +40 -64
  51. package/docs/angular.md +0 -325
  52. package/docs/helpers/Protractor.md +0 -1658
  53. package/docs/webapi/waitUntil.mustache +0 -11
  54. package/typings/Protractor.d.ts +0 -16
@@ -108,7 +108,7 @@ If you need to get access to web elements, it is recommended to implement operat
108
108
 
109
109
  To get access for elements, connect to a corresponding helper and use `_locate` function to match web elements by CSS or XPath, like you usually do:
110
110
 
111
- ### Acessing Elements in WebDriver
111
+ ### Accessing Elements in WebDriver
112
112
 
113
113
  ```js
114
114
  // inside a custom helper
@@ -304,38 +304,3 @@ class MyHelper extends Helper {
304
304
 
305
305
  module.exports = MyHelper;
306
306
  ```
307
-
308
- ### Protractor Example
309
-
310
- Protractor example demonstrates usage of global `element` and `by` objects.
311
- However `browser` should be accessed from a helper instance via `this.helpers['Protractor']`;
312
- We also use `chai-as-promised` library to have nice assertions with promises.
313
-
314
- ```js
315
- const Helper = require('@codeceptjs/helper');
316
-
317
- // use any assertion library you like
318
- const chai = require('chai');
319
- const chaiAsPromised = require('chai-as-promised');
320
- chai.use(chaiAsPromised);
321
- const expect = chai.expect;
322
-
323
- class MyHelper extends Helper {
324
- /**
325
- * checks that authentication cookie is set
326
- */
327
- seeInHistory(historyPosition, value) {
328
- // access browser instance from Protractor helper
329
- this.helpers['Protractor'].browser.refresh();
330
-
331
- // you can use `element` as well as in protractor
332
- const history = element.all(by.repeater('result in memory'));
333
-
334
- // use chai as promised for better assertions
335
- // end your method with `return` to handle promises
336
- return expect(history.get(historyPosition).getText()).to.eventually.equal(value);
337
- }
338
- }
339
-
340
- module.exports = MyHelper;
341
- ```
@@ -1315,7 +1315,7 @@ I.defineTimeout({ implicit: 10000, pageLoad: 10000, script: 5000 });
1315
1315
 
1316
1316
  #### Parameters
1317
1317
 
1318
- - `timeouts` **WebdriverIO.Timeouts** WebDriver timeouts object.
1318
+ - `timeouts` **any** WebDriver timeouts object.
1319
1319
 
1320
1320
  ### amOnPage
1321
1321
 
@@ -101,7 +101,7 @@ I.seeFileNameMatching('.pdf');
101
101
 
102
102
  #### Parameters
103
103
 
104
- - `text`
104
+ - `text` **[string][1]**
105
105
 
106
106
  ### seeInThisFile
107
107
 
@@ -47,6 +47,7 @@ This helper should be configured in codecept.json or codecept.conf.js
47
47
  - `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
48
48
  - `windowSize`: (optional) default window size. Set a dimension like `640x480`.
49
49
  - `userAgent`: (optional) user-agent string.
50
+ - `locale`: (optional) locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
50
51
  - `manualStart`: - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
51
52
  - `chromium`: (optional) pass additional chromium options
52
53
  - `electron`: (optional) pass additional electron options
@@ -162,6 +163,19 @@ const { devices } = require('playwright');
162
163
  }
163
164
  ```
164
165
 
166
+ #### Example #7: Launch test with a specifc user locale
167
+
168
+ ```js
169
+ {
170
+ helpers: {
171
+ Playwright : {
172
+ url: "http://localhost",
173
+ locale: "fr-FR",
174
+ }
175
+ }
176
+ }
177
+ ```
178
+
165
179
  Note: When connecting to remote browser `show` and specific `chrome` options (e.g. `headless` or `devtools`) are ignored.
166
180
 
167
181
  ## Access From Helpers
@@ -1821,11 +1835,11 @@ I.waitForRequest(request => request.url() === 'http://example.com' && request.me
1821
1835
 
1822
1836
  ### waitForResponse
1823
1837
 
1824
- Waits for a network request.
1838
+ Waits for a network response.
1825
1839
 
1826
1840
  ```js
1827
1841
  I.waitForResponse('http://example.com/resource');
1828
- I.waitForResponse(request => request.url() === 'http://example.com' && request.method() === 'GET');
1842
+ I.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
1829
1843
  ```
1830
1844
 
1831
1845
  #### Parameters
@@ -1919,22 +1933,6 @@ I.waitToHide('#popup');
1919
1933
  - `locator` **([string][9] | [object][7])** element located by CSS|XPath|strict locator.
1920
1934
  - `sec` **[number][10]** (optional, `1` by default) time in seconds to wait
1921
1935
 
1922
- ### waitUntil
1923
-
1924
- Waits for a function to return true (waits for 1sec by default).
1925
-
1926
- ```js
1927
- I.waitUntil(() => window.requests == 0);
1928
- I.waitUntil(() => window.requests == 0, 5);
1929
- ```
1930
-
1931
- #### Parameters
1932
-
1933
- - `fn` **([function][11] | [string][9])** function which is executed in browser context.
1934
- - `sec` **[number][10]** (optional, `1` by default) time in seconds to wait
1935
- - `timeoutMsg` **[string][9]** message to show in case of timeout fail.
1936
- - `interval` **[number][10]?**
1937
-
1938
1936
  ### waitUrlEquals
1939
1937
 
1940
1938
  Waits for the entire URL to match the expected
@@ -1614,7 +1614,7 @@ I.seeTitleEquals('Test title.');
1614
1614
 
1615
1615
  #### Parameters
1616
1616
 
1617
- - `text`
1617
+ - `text` **[string][8]** value to check.
1618
1618
 
1619
1619
  ### selectOption
1620
1620
 
@@ -1998,22 +1998,6 @@ I.waitToHide('#popup');
1998
1998
  - `locator` **([string][8] | [object][6])** element located by CSS|XPath|strict locator.
1999
1999
  - `sec` **[number][10]** (optional, `1` by default) time in seconds to wait
2000
2000
 
2001
- ### waitUntil
2002
-
2003
- Waits for a function to return true (waits for 1sec by default).
2004
-
2005
- ```js
2006
- I.waitUntil(() => window.requests == 0);
2007
- I.waitUntil(() => window.requests == 0, 5);
2008
- ```
2009
-
2010
- #### Parameters
2011
-
2012
- - `fn` **([function][12] | [string][8])** function which is executed in browser context.
2013
- - `sec` **[number][10]** (optional, `1` by default) time in seconds to wait
2014
- - `timeoutMsg` **[string][8]** message to show in case of timeout fail.
2015
- - `interval` **[number][10]?**
2016
-
2017
2001
  ### waitUrlEquals
2018
2002
 
2019
2003
  Waits for the entire URL to match the expected
@@ -168,7 +168,7 @@ I.setRequestTimeout(10000); // In milliseconds
168
168
 
169
169
  #### Parameters
170
170
 
171
- - `newTimeout`
171
+ - `newTimeout` **[number][5]** timeout in milliseconds
172
172
 
173
173
  [1]: https://github.com/axios/axios
174
174
 
@@ -177,3 +177,5 @@ I.setRequestTimeout(10000); // In milliseconds
177
177
  [3]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object
178
178
 
179
179
  [4]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String
180
+
181
+ [5]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number
@@ -599,7 +599,7 @@ I.defineTimeout({ implicit: 10000, pageLoad: 10000, script: 5000 });
599
599
 
600
600
  #### Parameters
601
601
 
602
- - `timeouts` **WebdriverIO.Timeouts** WebDriver timeouts object.
602
+ - `timeouts` **any** WebDriver timeouts object.
603
603
 
604
604
  ### dontSee
605
605
 
@@ -2155,22 +2155,6 @@ I.waitToHide('#popup');
2155
2155
  - `locator` **([string][19] | [object][18])** element located by CSS|XPath|strict locator.
2156
2156
  - `sec` **[number][22]** (optional, `1` by default) time in seconds to wait
2157
2157
 
2158
- ### waitUntil
2159
-
2160
- Waits for a function to return true (waits for 1sec by default).
2161
-
2162
- ```js
2163
- I.waitUntil(() => window.requests == 0);
2164
- I.waitUntil(() => window.requests == 0, 5);
2165
- ```
2166
-
2167
- #### Parameters
2168
-
2169
- - `fn` **([function][24] | [string][19])** function which is executed in browser context.
2170
- - `sec` **[number][22]** (optional, `1` by default) time in seconds to wait
2171
- - `timeoutMsg` **[string][19]** message to show in case of timeout fail.
2172
- - `interval` **[number][22]?**
2173
-
2174
2158
  ### waitUrlEquals
2175
2159
 
2176
2160
  Waits for the entire URL to match the expected
@@ -1,6 +1,9 @@
1
1
  ## Automating React Native apps
2
2
 
3
3
  ### Problem
4
+
5
+ > ⚠️ **NOTE**: This problem is not actual starting from `react-native@0.65.x` [CHANGELOG](https://github.com/react-native-community/releases/blob/master/CHANGELOG.md#android-specific-9), [#381fb3](https://github.com/facebook/react-native/commit/381fb395ad9d2d48717a5d082aaedbecdd804554)
6
+
4
7
  Let's say we have a React Native app with component defined like this
5
8
  ```html
6
9
  <Button testID='someButton'>My button</Button>
package/docs/plugins.md CHANGED
@@ -626,6 +626,75 @@ Scenario('scenario tite', () => {
626
626
 
627
627
  - `config`
628
628
 
629
+ ## retryTo
630
+
631
+ Adds global `retryTo` which retries steps a few times before failing.
632
+
633
+ Enable this plugin in `codecept.conf.js` (enabled by default for new setups):
634
+
635
+ ```js
636
+ plugins: {
637
+ retryTo: {
638
+ enabled: true
639
+ }
640
+ }
641
+ ```
642
+
643
+ Use it in your tests:
644
+
645
+ ```js
646
+ // retry these steps 5 times before failing
647
+ await retryTo((tryNum) => {
648
+ I.switchTo('#editor frame');
649
+ I.click('Open');
650
+ I.see('Opened')
651
+ }, 5);
652
+ ```
653
+
654
+ Set polling interval as 3rd argument (200ms by default):
655
+
656
+ ```js
657
+ // retry these steps 5 times before failing
658
+ await retryTo((tryNum) => {
659
+ I.switchTo('#editor frame');
660
+ I.click('Open');
661
+ I.see('Opened')
662
+ }, 5, 100);
663
+ ```
664
+
665
+ Default polling interval can be changed in a config:
666
+
667
+ ```js
668
+ plugins: {
669
+ retryTo: {
670
+ enabled: true,
671
+ pollInterval: 500,
672
+ }
673
+ }
674
+ ```
675
+
676
+ Disables retryFailedStep plugin for steps inside a block;
677
+
678
+ Use this plugin if:
679
+
680
+ - you need repeat a set of actions in flaky tests
681
+ - iframe was not rendered and you need to retry switching to it
682
+
683
+ #### Configuration
684
+
685
+ - `pollInterval` - default interval between retries in ms. 200 by default.
686
+ - `registerGlobal` - to register `retryTo` function globally, true by default
687
+
688
+ If `registerGlobal` is false you can use retryTo from the plugin:
689
+
690
+ ```js
691
+ const retryTo = codeceptjs.container.plugins('retryTo');
692
+ ```
693
+
694
+ ### Parameters
695
+
696
+ - `config`
697
+
629
698
  ## screenshotOnFail
630
699
 
631
700
  Creates screenshot on failure. Screenshot is saved into `output` directory.
@@ -802,11 +871,67 @@ Possible config options:
802
871
  - `fullPageScreenshots`: should full page screenshots be used. Default: false.
803
872
  - `output`: a directory where reports should be stored. Default: `output`.
804
873
  - `screenshotsForAllureReport`: If Allure plugin is enabled this plugin attaches each saved screenshot to allure report. Default: false.
874
+ - \`disableScreenshotOnFail : Disables the capturing of screeshots after the failed step. Default: true.
805
875
 
806
876
  ### Parameters
807
877
 
808
878
  - `config` **any**
809
879
 
880
+ ## stepTimeout
881
+
882
+ Set timeout for test steps globally.
883
+
884
+ Add this plugin to config file:
885
+
886
+ ```js
887
+ plugins: {
888
+ stepTimeout: {
889
+ enabled: true
890
+ }
891
+ }
892
+ ```
893
+
894
+ Run tests with plugin enabled:
895
+
896
+ npx codeceptjs run --plugins stepTimeout
897
+
898
+ #### Configuration:
899
+
900
+ - `timeout` - global step timeout, default 150 seconds
901
+ - `force` - whether to use timeouts set in plugin config to override step timeouts set in code with I.limitTime(x).action(...), default false
902
+ - `noTimeoutSteps` - an array of steps with no timeout. Default:
903
+
904
+ - `amOnPage`
905
+ - `wait*`
906
+
907
+ you could set your own noTimeoutSteps which would replace the default one.
908
+
909
+ - `customTimeoutSteps` - an array of step actions with custom timeout. Use it to override or extend noTimeoutSteps.
910
+ You can use step names or step prefixes ending with `*`. As such, `wait*` will match all steps starting with `wait`.
911
+
912
+ #### Example
913
+
914
+ ```js
915
+ plugins: {
916
+ stepTimeout: {
917
+ enabled: true,
918
+ force: true,
919
+ noTimeoutSteps: [
920
+ 'scroll*', // ignore all scroll steps
921
+ /Cookie/, // ignore all steps with a Cookie in it (by regexp)
922
+ ],
923
+ customTimeoutSteps: [
924
+ ['myFlakyStep*', 1],
925
+ ['scrollWhichRequiresTimeout', 5],
926
+ ]
927
+ }
928
+ }
929
+ ```
930
+
931
+ ### Parameters
932
+
933
+ - `config`
934
+
810
935
  ## subtitles
811
936
 
812
937
  Automatically captures steps as subtitle, and saves it as an artifact when a video is found for a failed test
package/docs/reports.md CHANGED
@@ -33,8 +33,8 @@ GitHub --
33
33
  Run with --verbose flag to see NodeJS stacktrace
34
34
 
35
35
  ```
36
- npx codeceptjs run --stepsutput add `--steps` option to `run` command:
37
- ```
36
+
37
+ output steps use `--steps` option:
38
38
  ```
39
39
  npx codeceptjs run --steps
40
40
  ```
package/lib/actor.js CHANGED
@@ -26,6 +26,24 @@ class Actor {
26
26
  });
27
27
  }
28
28
 
29
+ /**
30
+ * set the maximum execution time for the next step
31
+ * @function
32
+ * @param {number} timeout - step timeout in seconds
33
+ * @return {this}
34
+ * @inner
35
+ */
36
+ limitTime(timeout) {
37
+ if (!store.timeouts) return this;
38
+
39
+ event.dispatcher.prependOnceListener(event.step.before, (step) => {
40
+ output.log(`Timeout to ${step}: ${timeout}s`);
41
+ step.totalTimeout = timeout * 1000;
42
+ });
43
+
44
+ return this;
45
+ }
46
+
29
47
  /**
30
48
  * @function
31
49
  * @param {*} [opts]
@@ -114,7 +132,7 @@ function recordStep(step, args) {
114
132
  step.startTime = Date.now();
115
133
  }
116
134
  return val = step.run(...args);
117
- });
135
+ }, false, undefined, step.totalTimeout);
118
136
 
119
137
  event.emit(event.step.after, step);
120
138
 
package/lib/codecept.js CHANGED
@@ -77,6 +77,7 @@ class Codecept {
77
77
  global.inject = container.support;
78
78
  global.share = container.share;
79
79
  global.secret = require('./secret').secret;
80
+ global.codecept_debug = output.debug;
80
81
  global.codeceptjs = require('./index'); // load all objects
81
82
 
82
83
  // BDD
@@ -95,6 +96,7 @@ class Codecept {
95
96
  runHook(require('./listener/steps'));
96
97
  runHook(require('./listener/config'));
97
98
  runHook(require('./listener/helpers'));
99
+ runHook(require('./listener/timeout'));
98
100
  runHook(require('./listener/exit'));
99
101
 
100
102
  // custom hooks
@@ -32,7 +32,7 @@ module.exports = async function (path) {
32
32
  }
33
33
  }
34
34
  output.print('***************************************');
35
- output.print('If you have questions ask them in our Slack: shorturl.at/cuKU8');
35
+ output.print('If you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs');
36
36
  output.print('Or ask them on our discussion board: https://codecept.discourse.group/');
37
37
  output.print('Please copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues');
38
38
  output.print('***************************************');
package/lib/config.js CHANGED
@@ -13,6 +13,7 @@ const defaultConfig = {
13
13
  include: {},
14
14
  mocha: {},
15
15
  bootstrap: null,
16
+ timeout: null,
16
17
  teardown: null,
17
18
  hooks: [],
18
19
  gherkin: {},
@@ -21,6 +22,17 @@ const defaultConfig = {
21
22
  enabled: true, // will be disabled by default in 2.0
22
23
  },
23
24
  },
25
+ stepTimeout: 0,
26
+ stepTimeoutOverride: [
27
+ {
28
+ pattern: 'wait.*',
29
+ timeout: 0,
30
+ },
31
+ {
32
+ pattern: 'amOnPage',
33
+ timeout: 0,
34
+ },
35
+ ],
24
36
  };
25
37
 
26
38
  let hooks = [];
package/lib/container.js CHANGED
@@ -7,6 +7,7 @@ const MochaFactory = require('./mochaFactory');
7
7
  const recorder = require('./recorder');
8
8
  const event = require('./event');
9
9
  const WorkerStorage = require('./workerStorage');
10
+ const store = require('./store');
10
11
 
11
12
  let container = {
12
13
  helpers: {},
@@ -45,6 +46,7 @@ class Container {
45
46
  container.support = createSupportObjects(config.include || {});
46
47
  container.plugins = createPlugins(config.plugins || {}, opts);
47
48
  if (config.gherkin) loadGherkinSteps(config.gherkin.steps || []);
49
+ if (opts && typeof opts.timeouts === 'boolean') store.timeouts = opts.timeouts;
48
50
  }
49
51
 
50
52
  /**
@@ -233,7 +235,7 @@ function createSupportObjects(config) {
233
235
  const currentObject = objects[object];
234
236
  Object.keys(currentObject).forEach((method) => {
235
237
  const currentMethod = currentObject[method];
236
- if (currentMethod[Symbol.toStringTag] === 'AsyncFunction') {
238
+ if (currentMethod && currentMethod[Symbol.toStringTag] === 'AsyncFunction') {
237
239
  objects[object][method] = asyncWrapper(currentMethod);
238
240
  }
239
241
  });
@@ -91,6 +91,7 @@ class FileSystem extends Helper {
91
91
  * I.amInPath('output/downloads');
92
92
  * I.seeFileNameMatching('.pdf');
93
93
  * ```
94
+ * @param {string} text
94
95
  */
95
96
  seeFileNameMatching(text) {
96
97
  assert.ok(
@@ -80,6 +80,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
80
80
  * * `basicAuth`: (optional) the basic authentication to pass to base url. Example: {username: 'username', password: 'password'}
81
81
  * * `windowSize`: (optional) default window size. Set a dimension like `640x480`.
82
82
  * * `userAgent`: (optional) user-agent string.
83
+ * * `locale`: (optional) locale string. Example: 'en-GB', 'de-DE', 'fr-FR', ...
83
84
  * * `manualStart`: (optional, default: false) - do not start browser before a test, start it manually inside a helper with `this.helpers["Playwright"]._startBrowser()`.
84
85
  * * `chromium`: (optional) pass additional chromium options
85
86
  * * `electron`: (optional) pass additional electron options
@@ -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
@@ -371,6 +385,8 @@ class Playwright extends Helper {
371
385
  }
372
386
  if (this.options.recordVideo) contextOptions.recordVideo = this.options.recordVideo;
373
387
  if (this.storageState) contextOptions.storageState = this.storageState;
388
+ if (this.options.userAgent) contextOptions.userAgent = this.options.userAgent;
389
+ if (this.options.locale) contextOptions.locale = this.options.locale;
374
390
  this.browserContext = await this.browser.newContext(contextOptions); // Adding the HTTPSError ignore in the context so that we can ignore those errors
375
391
  }
376
392
 
@@ -2146,11 +2162,11 @@ class Playwright extends Helper {
2146
2162
  }
2147
2163
 
2148
2164
  /**
2149
- * Waits for a network request.
2165
+ * Waits for a network response.
2150
2166
  *
2151
2167
  * ```js
2152
2168
  * I.waitForResponse('http://example.com/resource');
2153
- * I.waitForResponse(request => request.url() === 'http://example.com' && request.method() === 'GET');
2169
+ * I.waitForResponse(response => response.url() === 'https://example.com' && response.status() === 200);
2154
2170
  * ```
2155
2171
  *
2156
2172
  * @param {string|function} urlOrPredicate
@@ -2236,16 +2252,6 @@ class Playwright extends Helper {
2236
2252
  return this.page.waitForNavigation(opts);
2237
2253
  }
2238
2254
 
2239
- /**
2240
- * {{> waitUntil }}
2241
- */
2242
- async waitUntil(fn, sec = null) {
2243
- console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
2244
- const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
2245
- const context = await this._getContext();
2246
- return context.waitForFunction(fn, { timeout: waitTimeout });
2247
- }
2248
-
2249
2255
  async waitUntilExists(locator, sec) {
2250
2256
  console.log(`waitUntilExists deprecated:
2251
2257
  * use 'waitForElement' to wait for element to be attached
@@ -2662,13 +2668,10 @@ async function targetCreatedHandler(page) {
2662
2668
  });
2663
2669
  });
2664
2670
  page.on('console', (msg) => {
2665
- this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg._text || '') + msg.args().join(' '));
2671
+ this.debugSection(`Browser:${ucfirst(msg.type())}`, (msg.text && msg.text() || msg._text || '') + msg.args().join(' '));
2666
2672
  consoleLogStore.add(msg);
2667
2673
  });
2668
2674
 
2669
- if (this.options.userAgent) {
2670
- await page.setUserAgent(this.options.userAgent);
2671
- }
2672
2675
  if (this.options.windowSize && this.options.windowSize.indexOf('x') > 0 && this._getType() === 'Browser') {
2673
2676
  await page.setViewportSize(parseWindowSize(this.options.windowSize));
2674
2677
  }
@@ -838,11 +838,7 @@ class Protractor extends Helper {
838
838
  }
839
839
 
840
840
  /**
841
- * Checks that title is equal to provided one.
842
- *
843
- * ```js
844
- * I.seeTitleEquals('Test title.');
845
- * ```
841
+ * {{> seeTitleEquals }}
846
842
  */
847
843
  async seeTitleEquals(text) {
848
844
  const title = await this.browser.getTitle();
@@ -1018,7 +1014,7 @@ class Protractor extends Helper {
1018
1014
  }
1019
1015
 
1020
1016
  /**
1021
- * {{> seeInCurrentUrl }}
1017
+ * {{> seeInCurrentUrl }}
1022
1018
  */
1023
1019
  async seeInCurrentUrl(url) {
1024
1020
  return this.browser.getCurrentUrl().then(currentUrl => stringIncludes('url').assert(url, currentUrl));
@@ -1498,14 +1494,6 @@ class Protractor extends Helper {
1498
1494
  return this.browser.wait(() => this.browser.executeScript.call(this.browser, fn, ...args), aSec * 1000);
1499
1495
  }
1500
1496
 
1501
- /**
1502
- * {{> waitUntil }}
1503
- */
1504
- async waitUntil(fn, sec = null, timeoutMsg = null) {
1505
- const aSec = sec || this.options.waitForTimeout;
1506
- return this.browser.wait(fn, aSec * 1000, timeoutMsg);
1507
- }
1508
-
1509
1497
  /**
1510
1498
  * {{> waitInUrl }}
1511
1499
  */
@@ -554,10 +554,9 @@ class Puppeteer extends Helper {
554
554
  this.context = null;
555
555
  popupStore.clear();
556
556
  this.isAuthenticated = false;
557
+ await this.browser.close();
557
558
  if (this.isRemoteBrowser) {
558
559
  await this.browser.disconnect();
559
- } else {
560
- await this.browser.close();
561
560
  }
562
561
  }
563
562
 
@@ -774,11 +773,7 @@ class Puppeteer extends Helper {
774
773
  }
775
774
 
776
775
  /**
777
- * Checks that title is equal to provided one.
778
- *
779
- * ```js
780
- * I.seeTitleEquals('Test title.');
781
- * ```
776
+ * {{> seeTitleEquals }}
782
777
  */
783
778
  async seeTitleEquals(text) {
784
779
  const title = await this.page.title();
@@ -2220,16 +2215,6 @@ class Puppeteer extends Helper {
2220
2215
  return this.page.waitForNavigation(opts);
2221
2216
  }
2222
2217
 
2223
- /**
2224
- * {{> waitUntil }}
2225
- */
2226
- async waitUntil(fn, sec = null) {
2227
- console.log('This method will remove in CodeceptJS 1.4; use `waitForFunction` instead!');
2228
- const waitTimeout = sec ? sec * 1000 : this.options.waitForTimeout;
2229
- const context = await this._getContext();
2230
- return context.waitForFunction(fn, { timeout: waitTimeout });
2231
- }
2232
-
2233
2218
  async waitUntilExists(locator, sec) {
2234
2219
  console.log(`waitUntilExists deprecated:
2235
2220
  * 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;