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.
- package/CHANGELOG.md +49 -1
- package/README.md +2 -3
- package/bin/codecept.js +1 -0
- package/docs/advanced.md +94 -60
- package/docs/basics.md +1 -1
- package/docs/build/FileSystem.js +1 -0
- package/docs/build/Playwright.js +19 -26
- package/docs/build/Protractor.js +9 -24
- package/docs/build/Puppeteer.js +9 -27
- package/docs/build/REST.js +1 -0
- package/docs/build/WebDriver.js +1 -23
- package/docs/changelog.md +49 -1
- package/docs/custom-helpers.md +1 -36
- package/docs/helpers/Appium.md +1 -1
- package/docs/helpers/FileSystem.md +1 -1
- package/docs/helpers/Playwright.md +16 -18
- package/docs/helpers/Puppeteer.md +1 -17
- package/docs/helpers/REST.md +3 -1
- package/docs/helpers/WebDriver.md +1 -17
- package/docs/mobile-react-native-locators.md +3 -0
- package/docs/plugins.md +125 -0
- package/docs/reports.md +2 -2
- package/lib/actor.js +19 -1
- package/lib/codecept.js +2 -0
- package/lib/command/info.js +1 -1
- package/lib/config.js +12 -0
- package/lib/container.js +3 -1
- package/lib/helper/FileSystem.js +1 -0
- package/lib/helper/Playwright.js +19 -16
- package/lib/helper/Protractor.js +2 -14
- package/lib/helper/Puppeteer.js +2 -17
- package/lib/helper/REST.js +1 -0
- package/lib/helper/WebDriver.js +1 -13
- package/lib/interfaces/featureConfig.js +3 -0
- package/lib/interfaces/scenarioConfig.js +4 -0
- package/lib/listener/steps.js +21 -3
- package/lib/listener/timeout.js +71 -0
- package/lib/locator.js +3 -0
- package/lib/plugin/allure.js +6 -1
- package/lib/plugin/retryTo.js +130 -0
- package/lib/plugin/screenshotOnFail.js +1 -0
- package/lib/plugin/stepByStepReport.js +7 -0
- package/lib/plugin/stepTimeout.js +90 -0
- package/lib/recorder.js +16 -5
- package/lib/step.js +3 -0
- package/lib/store.js +2 -0
- package/lib/ui.js +2 -2
- package/package.json +4 -6
- package/typings/index.d.ts +6 -1
- package/typings/types.d.ts +40 -64
- package/docs/angular.md +0 -325
- package/docs/helpers/Protractor.md +0 -1658
- package/docs/webapi/waitUntil.mustache +0 -11
- package/typings/Protractor.d.ts +0 -16
package/docs/custom-helpers.md
CHANGED
|
@@ -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
|
-
###
|
|
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
|
-
```
|
package/docs/helpers/Appium.md
CHANGED
|
@@ -1315,7 +1315,7 @@ I.defineTimeout({ implicit: 10000, pageLoad: 10000, script: 5000 });
|
|
|
1315
1315
|
|
|
1316
1316
|
#### Parameters
|
|
1317
1317
|
|
|
1318
|
-
- `timeouts` **
|
|
1318
|
+
- `timeouts` **any** WebDriver timeouts object.
|
|
1319
1319
|
|
|
1320
1320
|
### amOnPage
|
|
1321
1321
|
|
|
@@ -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
|
|
1838
|
+
Waits for a network response.
|
|
1825
1839
|
|
|
1826
1840
|
```js
|
|
1827
1841
|
I.waitForResponse('http://example.com/resource');
|
|
1828
|
-
I.waitForResponse(
|
|
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
|
package/docs/helpers/REST.md
CHANGED
|
@@ -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` **
|
|
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
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
|
package/lib/command/info.js
CHANGED
|
@@ -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:
|
|
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
|
});
|
package/lib/helper/FileSystem.js
CHANGED
package/lib/helper/Playwright.js
CHANGED
|
@@ -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
|
|
2165
|
+
* Waits for a network response.
|
|
2150
2166
|
*
|
|
2151
2167
|
* ```js
|
|
2152
2168
|
* I.waitForResponse('http://example.com/resource');
|
|
2153
|
-
* I.waitForResponse(
|
|
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
|
}
|
package/lib/helper/Protractor.js
CHANGED
|
@@ -838,11 +838,7 @@ class Protractor extends Helper {
|
|
|
838
838
|
}
|
|
839
839
|
|
|
840
840
|
/**
|
|
841
|
-
*
|
|
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
|
-
|
|
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
|
*/
|
package/lib/helper/Puppeteer.js
CHANGED
|
@@ -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
|
-
*
|
|
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
|
package/lib/helper/REST.js
CHANGED