codeceptjs 3.5.13-beta.1 → 3.5.13-beta.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.
- package/docs/webapi/amOnPage.mustache +11 -0
- package/docs/webapi/appendField.mustache +11 -0
- package/docs/webapi/attachFile.mustache +12 -0
- package/docs/webapi/blur.mustache +18 -0
- package/docs/webapi/checkOption.mustache +13 -0
- package/docs/webapi/clearCookie.mustache +9 -0
- package/docs/webapi/clearField.mustache +9 -0
- package/docs/webapi/click.mustache +25 -0
- package/docs/webapi/clickLink.mustache +8 -0
- package/docs/webapi/closeCurrentTab.mustache +7 -0
- package/docs/webapi/closeOtherTabs.mustache +8 -0
- package/docs/webapi/dontSee.mustache +11 -0
- package/docs/webapi/dontSeeCheckboxIsChecked.mustache +10 -0
- package/docs/webapi/dontSeeCookie.mustache +8 -0
- package/docs/webapi/dontSeeCurrentUrlEquals.mustache +10 -0
- package/docs/webapi/dontSeeElement.mustache +8 -0
- package/docs/webapi/dontSeeElementInDOM.mustache +8 -0
- package/docs/webapi/dontSeeInCurrentUrl.mustache +4 -0
- package/docs/webapi/dontSeeInField.mustache +11 -0
- package/docs/webapi/dontSeeInSource.mustache +8 -0
- package/docs/webapi/dontSeeInTitle.mustache +8 -0
- package/docs/webapi/dontSeeTraffic.mustache +13 -0
- package/docs/webapi/doubleClick.mustache +13 -0
- package/docs/webapi/downloadFile.mustache +12 -0
- package/docs/webapi/dragAndDrop.mustache +9 -0
- package/docs/webapi/dragSlider.mustache +11 -0
- package/docs/webapi/executeAsyncScript.mustache +24 -0
- package/docs/webapi/executeScript.mustache +26 -0
- package/docs/webapi/fillField.mustache +16 -0
- package/docs/webapi/flushNetworkTraffics.mustache +5 -0
- package/docs/webapi/focus.mustache +13 -0
- package/docs/webapi/forceClick.mustache +28 -0
- package/docs/webapi/forceRightClick.mustache +18 -0
- package/docs/webapi/grabAllWindowHandles.mustache +7 -0
- package/docs/webapi/grabAttributeFrom.mustache +10 -0
- package/docs/webapi/grabAttributeFromAll.mustache +9 -0
- package/docs/webapi/grabBrowserLogs.mustache +9 -0
- package/docs/webapi/grabCookie.mustache +11 -0
- package/docs/webapi/grabCssPropertyFrom.mustache +11 -0
- package/docs/webapi/grabCssPropertyFromAll.mustache +10 -0
- package/docs/webapi/grabCurrentUrl.mustache +9 -0
- package/docs/webapi/grabCurrentWindowHandle.mustache +6 -0
- package/docs/webapi/grabDataFromPerformanceTiming.mustache +20 -0
- package/docs/webapi/grabElementBoundingRect.mustache +20 -0
- package/docs/webapi/grabGeoLocation.mustache +8 -0
- package/docs/webapi/grabHTMLFrom.mustache +10 -0
- package/docs/webapi/grabHTMLFromAll.mustache +9 -0
- package/docs/webapi/grabNumberOfOpenTabs.mustache +8 -0
- package/docs/webapi/grabNumberOfVisibleElements.mustache +9 -0
- package/docs/webapi/grabPageScrollPosition.mustache +8 -0
- package/docs/webapi/grabPopupText.mustache +5 -0
- package/docs/webapi/grabRecordedNetworkTraffics.mustache +10 -0
- package/docs/webapi/grabSource.mustache +8 -0
- package/docs/webapi/grabTextFrom.mustache +10 -0
- package/docs/webapi/grabTextFromAll.mustache +9 -0
- package/docs/webapi/grabTitle.mustache +8 -0
- package/docs/webapi/grabValueFrom.mustache +9 -0
- package/docs/webapi/grabValueFromAll.mustache +8 -0
- package/docs/webapi/grabWebElement.mustache +9 -0
- package/docs/webapi/grabWebElements.mustache +9 -0
- package/docs/webapi/moveCursorTo.mustache +12 -0
- package/docs/webapi/openNewTab.mustache +7 -0
- package/docs/webapi/pressKey.mustache +12 -0
- package/docs/webapi/pressKeyDown.mustache +12 -0
- package/docs/webapi/pressKeyUp.mustache +12 -0
- package/docs/webapi/pressKeyWithKeyNormalization.mustache +60 -0
- package/docs/webapi/refreshPage.mustache +6 -0
- package/docs/webapi/resizeWindow.mustache +6 -0
- package/docs/webapi/rightClick.mustache +14 -0
- package/docs/webapi/saveElementScreenshot.mustache +10 -0
- package/docs/webapi/saveScreenshot.mustache +12 -0
- package/docs/webapi/say.mustache +10 -0
- package/docs/webapi/scrollIntoView.mustache +11 -0
- package/docs/webapi/scrollPageToBottom.mustache +6 -0
- package/docs/webapi/scrollPageToTop.mustache +6 -0
- package/docs/webapi/scrollTo.mustache +12 -0
- package/docs/webapi/see.mustache +11 -0
- package/docs/webapi/seeAttributesOnElements.mustache +9 -0
- package/docs/webapi/seeCheckboxIsChecked.mustache +10 -0
- package/docs/webapi/seeCookie.mustache +8 -0
- package/docs/webapi/seeCssPropertiesOnElements.mustache +9 -0
- package/docs/webapi/seeCurrentUrlEquals.mustache +11 -0
- package/docs/webapi/seeElement.mustache +8 -0
- package/docs/webapi/seeElementInDOM.mustache +8 -0
- package/docs/webapi/seeInCurrentUrl.mustache +8 -0
- package/docs/webapi/seeInField.mustache +12 -0
- package/docs/webapi/seeInPopup.mustache +8 -0
- package/docs/webapi/seeInSource.mustache +7 -0
- package/docs/webapi/seeInTitle.mustache +8 -0
- package/docs/webapi/seeNumberOfElements.mustache +11 -0
- package/docs/webapi/seeNumberOfVisibleElements.mustache +10 -0
- package/docs/webapi/seeTextEquals.mustache +9 -0
- package/docs/webapi/seeTitleEquals.mustache +8 -0
- package/docs/webapi/seeTraffic.mustache +36 -0
- package/docs/webapi/selectOption.mustache +21 -0
- package/docs/webapi/setCookie.mustache +16 -0
- package/docs/webapi/setGeoLocation.mustache +12 -0
- package/docs/webapi/startRecordingTraffic.mustache +8 -0
- package/docs/webapi/stopRecordingTraffic.mustache +5 -0
- package/docs/webapi/switchTo.mustache +9 -0
- package/docs/webapi/switchToNextTab.mustache +10 -0
- package/docs/webapi/switchToPreviousTab.mustache +10 -0
- package/docs/webapi/type.mustache +21 -0
- package/docs/webapi/uncheckOption.mustache +13 -0
- package/docs/webapi/wait.mustache +8 -0
- package/docs/webapi/waitForClickable.mustache +11 -0
- package/docs/webapi/waitForCookie.mustache +9 -0
- package/docs/webapi/waitForDetached.mustache +10 -0
- package/docs/webapi/waitForElement.mustache +11 -0
- package/docs/webapi/waitForEnabled.mustache +6 -0
- package/docs/webapi/waitForFunction.mustache +17 -0
- package/docs/webapi/waitForInvisible.mustache +10 -0
- package/docs/webapi/waitForNumberOfTabs.mustache +9 -0
- package/docs/webapi/waitForText.mustache +13 -0
- package/docs/webapi/waitForValue.mustache +10 -0
- package/docs/webapi/waitForVisible.mustache +10 -0
- package/docs/webapi/waitInUrl.mustache +9 -0
- package/docs/webapi/waitNumberOfVisibleElements.mustache +10 -0
- package/docs/webapi/waitToHide.mustache +10 -0
- package/docs/webapi/waitUrlEquals.mustache +10 -0
- package/lib/helper/Playwright.js +8 -204
- package/lib/helper/WebDriver.js +264 -3
- package/lib/helper/networkTraffics/utils.js +137 -0
- package/package.json +4 -3
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Switches frame or in case of null locator reverts to parent.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.switchTo('iframe'); // switch to first iframe
|
|
5
|
+
I.switchTo(); // switch back to main page
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {?CodeceptJS.LocatorOrString} [locator=null] (optional, `null` by default) element located by CSS|XPath|strict locator.
|
|
9
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Switch focus to a particular tab by its number. It waits tabs loading and then switch tab.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.switchToNextTab();
|
|
5
|
+
I.switchToNextTab(2);
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {number} [num] (optional) number of tabs to switch forward, default: 1.
|
|
9
|
+
@param {number | null} [sec] (optional) time in seconds to wait.
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Switch focus to a particular tab by its number. It waits tabs loading and then switch tab.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.switchToPreviousTab();
|
|
5
|
+
I.switchToPreviousTab(2);
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {number} [num] (optional) number of tabs to switch backward, default: 1.
|
|
9
|
+
@param {number?} [sec] (optional) time in seconds to wait.
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
Types out the given text into an active field.
|
|
2
|
+
To slow down typing use a second parameter, to set interval between key presses.
|
|
3
|
+
_Note:_ Should be used when [`fillField`](#fillfield) is not an option.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
// passing in a string
|
|
7
|
+
I.type('Type this out.');
|
|
8
|
+
|
|
9
|
+
// typing values with a 100ms interval
|
|
10
|
+
I.type('4141555311111111', 100);
|
|
11
|
+
|
|
12
|
+
// passing in an array
|
|
13
|
+
I.type(['T', 'E', 'X', 'T']);
|
|
14
|
+
|
|
15
|
+
// passing a secret
|
|
16
|
+
I.type(secret('123456'));
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
@param {string|string[]} key or array of keys to type.
|
|
20
|
+
@param {?number} [delay=null] (optional) delay in ms between key presses
|
|
21
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Unselects a checkbox or radio button.
|
|
2
|
+
Element is located by label or name or CSS or XPath.
|
|
3
|
+
|
|
4
|
+
The second parameter is a context (CSS or XPath locator) to narrow the search.
|
|
5
|
+
|
|
6
|
+
```js
|
|
7
|
+
I.uncheckOption('#agree');
|
|
8
|
+
I.uncheckOption('I Agree to Terms and Conditions');
|
|
9
|
+
I.uncheckOption('agree', '//form');
|
|
10
|
+
```
|
|
11
|
+
@param {CodeceptJS.LocatorOrString} field checkbox located by label | name | CSS | XPath | strict locator.
|
|
12
|
+
@param {?CodeceptJS.LocatorOrString} [context=null] (optional, `null` by default) element located by CSS | XPath | strict locator.
|
|
13
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Waits for element to be clickable (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitForClickable('.btn.continue');
|
|
6
|
+
I.waitForClickable('.btn.continue', 5); // wait for 5 secs
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
10
|
+
@param {number} [sec] (optional, `1` by default) time in seconds to wait
|
|
11
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Waits for the specified cookie in the cookies.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.waitForCookie("token");
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
@param {string} name expected cookie name.
|
|
8
|
+
@param {number} [sec=3] (optional, `3` by default) time in seconds to wait
|
|
9
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for an element to become not attached to the DOM on a page (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitForDetached('#popup');
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Waits for element to be present on page (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitForElement('.btn.continue');
|
|
6
|
+
I.waitForElement('.btn.continue', 5); // wait for 5 secs
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
10
|
+
@param {number} [sec] (optional, `1` by default) time in seconds to wait
|
|
11
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Waits for element to become enabled (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
5
|
+
@param {number} [sec=1] (optional) time in seconds to wait, 1 by default.
|
|
6
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Waits for a function to return true (waits for 1 sec by default).
|
|
2
|
+
Running in browser context.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitForFunction(fn[, [args[, timeout]])
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
```js
|
|
9
|
+
I.waitForFunction(() => window.requests == 0);
|
|
10
|
+
I.waitForFunction(() => window.requests == 0, 5); // waits for 5 sec
|
|
11
|
+
I.waitForFunction((count) => window.requests == count, [3], 5) // pass args and wait for 5 sec
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
@param {string|function} fn to be executed in browser context.
|
|
15
|
+
@param {any[]|number} [argsOrSec] (optional, `1` by default) arguments for function or seconds.
|
|
16
|
+
@param {number} [sec] (optional, `1` by default) time in seconds to wait
|
|
17
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for an element to be removed or become invisible on a page (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitForInvisible('#popup');
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Waits for a text to appear (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
Narrow down search results by providing context.
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
I.waitForText('Thank you, form has been submitted');
|
|
7
|
+
I.waitForText('Thank you, form has been submitted', 5, '#modal');
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
@param {string }text to wait for.
|
|
11
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
12
|
+
@param {CodeceptJS.LocatorOrString} [context] (optional) element located by CSS|XPath|strict locator.
|
|
13
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for the specified value to be in value attribute.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.waitForValue('//input', "GoodValue");
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
@param {LocatorOrString} field input field.
|
|
8
|
+
@param {string }value expected value.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for an element to become visible on a page (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitForVisible('#popup');
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Waiting for the part of the URL to match the expected. Useful for SPA to understand that page was changed.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.waitInUrl('/info', 2);
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
@param {string} urlPart value to check.
|
|
8
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
9
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for a specified number of elements on the page.
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.waitNumberOfVisibleElements('a', 3);
|
|
5
|
+
```
|
|
6
|
+
|
|
7
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
8
|
+
@param {number} num number of elements.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for an element to hide (by default waits for 1sec).
|
|
2
|
+
Element can be located by CSS or XPath.
|
|
3
|
+
|
|
4
|
+
```js
|
|
5
|
+
I.waitToHide('#popup');
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {CodeceptJS.LocatorOrString} locator element located by CSS|XPath|strict locator.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
Waits for the entire URL to match the expected
|
|
2
|
+
|
|
3
|
+
```js
|
|
4
|
+
I.waitUrlEquals('/info', 2);
|
|
5
|
+
I.waitUrlEquals('http://127.0.0.1:8000/info');
|
|
6
|
+
```
|
|
7
|
+
|
|
8
|
+
@param {string} urlPart value to check.
|
|
9
|
+
@param {number} [sec=1] (optional, `1` by default) time in seconds to wait
|
|
10
|
+
@returns {void} automatically synchronized promise through #recorder
|
package/lib/helper/Playwright.js
CHANGED
|
@@ -51,6 +51,7 @@ const { createValueEngine, createDisabledEngine } = require('./extras/Playwright
|
|
|
51
51
|
const {
|
|
52
52
|
seeElementError, dontSeeElementError, dontSeeElementInDOMError, seeElementInDOMError,
|
|
53
53
|
} = require('./errors/ElementAssertion');
|
|
54
|
+
const { createAdvancedTestResults, allParameterValuePairsMatchExtreme, extractQueryObjects } = require('./networkTraffics/utils');
|
|
54
55
|
const { log } = require('../output');
|
|
55
56
|
|
|
56
57
|
const pathSeparator = path.sep;
|
|
@@ -2976,14 +2977,8 @@ class Playwright extends Helper {
|
|
|
2976
2977
|
}
|
|
2977
2978
|
|
|
2978
2979
|
/**
|
|
2979
|
-
*
|
|
2980
|
-
* This also resets recorded network requests.
|
|
2980
|
+
* {{> flushNetworkTraffics }}
|
|
2981
2981
|
*
|
|
2982
|
-
* ```js
|
|
2983
|
-
* I.startRecordingTraffic();
|
|
2984
|
-
* ```
|
|
2985
|
-
*
|
|
2986
|
-
* @return {void}
|
|
2987
2982
|
*/
|
|
2988
2983
|
startRecordingTraffic() {
|
|
2989
2984
|
this.flushNetworkTraffics();
|
|
@@ -3010,18 +3005,8 @@ class Playwright extends Helper {
|
|
|
3010
3005
|
}
|
|
3011
3006
|
|
|
3012
3007
|
/**
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
* ```js
|
|
3016
|
-
* const traffics = await I.grabRecordedNetworkTraffics();
|
|
3017
|
-
* expect(traffics[0].url).to.equal('https://reqres.in/api/comments/1');
|
|
3018
|
-
* expect(traffics[0].response.status).to.equal(200);
|
|
3019
|
-
* expect(traffics[0].response.body).to.contain({ name: 'this was mocked' });
|
|
3020
|
-
* ```
|
|
3021
|
-
*
|
|
3022
|
-
* @return { Promise<Array<any>> }
|
|
3023
|
-
*
|
|
3024
|
-
*/
|
|
3008
|
+
* {{> grabRecordedNetworkTraffics }}
|
|
3009
|
+
*/
|
|
3025
3010
|
async grabRecordedNetworkTraffics() {
|
|
3026
3011
|
if (!this.recording || !this.recordedAtLeastOnce) {
|
|
3027
3012
|
throw new Error('Failure in test automation. You use "I.grabRecordedNetworkTraffics", but "I.startRecordingTraffic" was never called before.');
|
|
@@ -3129,18 +3114,14 @@ class Playwright extends Helper {
|
|
|
3129
3114
|
}
|
|
3130
3115
|
|
|
3131
3116
|
/**
|
|
3132
|
-
*
|
|
3117
|
+
* {{> flushNetworkTraffics }}
|
|
3133
3118
|
*/
|
|
3134
3119
|
flushNetworkTraffics() {
|
|
3135
3120
|
this.requests = [];
|
|
3136
3121
|
}
|
|
3137
3122
|
|
|
3138
3123
|
/**
|
|
3139
|
-
*
|
|
3140
|
-
*
|
|
3141
|
-
* ```js
|
|
3142
|
-
* I.stopRecordingTraffic();
|
|
3143
|
-
* ```
|
|
3124
|
+
* {{> stopRecordingTraffic }}
|
|
3144
3125
|
*/
|
|
3145
3126
|
stopRecordingTraffic() {
|
|
3146
3127
|
this.page.removeAllListeners('request');
|
|
@@ -3148,42 +3129,7 @@ class Playwright extends Helper {
|
|
|
3148
3129
|
}
|
|
3149
3130
|
|
|
3150
3131
|
/**
|
|
3151
|
-
*
|
|
3152
|
-
*
|
|
3153
|
-
* ```js
|
|
3154
|
-
* // checking the request url contains certain query strings
|
|
3155
|
-
* I.amOnPage('https://openai.com/blog/chatgpt');
|
|
3156
|
-
* I.startRecordingTraffic();
|
|
3157
|
-
* await I.seeTraffic({
|
|
3158
|
-
* name: 'sentry event',
|
|
3159
|
-
* url: 'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600',
|
|
3160
|
-
* parameters: {
|
|
3161
|
-
* width: '1919',
|
|
3162
|
-
* height: '1138',
|
|
3163
|
-
* },
|
|
3164
|
-
* });
|
|
3165
|
-
* ```
|
|
3166
|
-
*
|
|
3167
|
-
* ```js
|
|
3168
|
-
* // checking the request url contains certain post data
|
|
3169
|
-
* I.amOnPage('https://openai.com/blog/chatgpt');
|
|
3170
|
-
* I.startRecordingTraffic();
|
|
3171
|
-
* await I.seeTraffic({
|
|
3172
|
-
* name: 'event',
|
|
3173
|
-
* url: 'https://cloudflareinsights.com/cdn-cgi/rum',
|
|
3174
|
-
* requestPostData: {
|
|
3175
|
-
* st: 2,
|
|
3176
|
-
* },
|
|
3177
|
-
* });
|
|
3178
|
-
* ```
|
|
3179
|
-
*
|
|
3180
|
-
* @param {Object} opts - options when checking the traffic network.
|
|
3181
|
-
* @param {string} opts.name A name of that request. Can be any value. Only relevant to have a more meaningful error message in case of fail.
|
|
3182
|
-
* @param {string} opts.url Expected URL of request in network traffic
|
|
3183
|
-
* @param {Object} [opts.parameters] Expected parameters of that request in network traffic
|
|
3184
|
-
* @param {Object} [opts.requestPostData] Expected that request contains post data in network traffic
|
|
3185
|
-
* @param {number} [opts.timeout] Timeout to wait for request in seconds. Default is 10 seconds.
|
|
3186
|
-
* @return { Promise<*> }
|
|
3132
|
+
* {{> seeTraffic }}
|
|
3187
3133
|
*/
|
|
3188
3134
|
async seeTraffic({
|
|
3189
3135
|
name, url, parameters, requestPostData, timeout = 10,
|
|
@@ -3265,18 +3211,7 @@ class Playwright extends Helper {
|
|
|
3265
3211
|
}
|
|
3266
3212
|
|
|
3267
3213
|
/**
|
|
3268
|
-
*
|
|
3269
|
-
*
|
|
3270
|
-
* Examples:
|
|
3271
|
-
*
|
|
3272
|
-
* ```js
|
|
3273
|
-
* I.dontSeeTraffic({ name: 'Unexpected API Call', url: 'https://api.example.com' });
|
|
3274
|
-
* I.dontSeeTraffic({ name: 'Unexpected API Call of "user" endpoint', url: /api.example.com.*user/ });
|
|
3275
|
-
* ```
|
|
3276
|
-
*
|
|
3277
|
-
* @param {Object} opts - options when checking the traffic network.
|
|
3278
|
-
* @param {string} opts.name A name of that request. Can be any value. Only relevant to have a more meaningful error message in case of fail.
|
|
3279
|
-
* @param {string|RegExp} opts.url Expected URL of request in network traffic. Can be a string or a regular expression.
|
|
3214
|
+
* {{> dontSeeTraffic }}
|
|
3280
3215
|
*
|
|
3281
3216
|
*/
|
|
3282
3217
|
dontSeeTraffic({ name, url }) {
|
|
@@ -3988,134 +3923,3 @@ async function highlightActiveElement(element) {
|
|
|
3988
3923
|
});
|
|
3989
3924
|
}
|
|
3990
3925
|
}
|
|
3991
|
-
|
|
3992
|
-
const createAdvancedTestResults = (url, dataToCheck, requests) => {
|
|
3993
|
-
// Creates advanced test results for a network traffic check.
|
|
3994
|
-
// Advanced test results only applies when expected parameters are set
|
|
3995
|
-
if (!dataToCheck) return '';
|
|
3996
|
-
|
|
3997
|
-
let urlFound = false;
|
|
3998
|
-
let advancedResults;
|
|
3999
|
-
requests.forEach((request) => {
|
|
4000
|
-
// url not found in this request. continue with next request
|
|
4001
|
-
if (urlFound || !request.url.match(new RegExp(url))) return;
|
|
4002
|
-
urlFound = true;
|
|
4003
|
-
|
|
4004
|
-
// Url found. Now we create advanced test report for that URL and show which parameters failed
|
|
4005
|
-
if (!request.requestPostData) {
|
|
4006
|
-
advancedResults = allParameterValuePairsMatchExtreme(extractQueryObjects(request.url), dataToCheck);
|
|
4007
|
-
} else if (request.requestPostData) {
|
|
4008
|
-
advancedResults = allRequestPostDataValuePairsMatchExtreme(request.requestPostData, dataToCheck);
|
|
4009
|
-
}
|
|
4010
|
-
});
|
|
4011
|
-
return advancedResults;
|
|
4012
|
-
};
|
|
4013
|
-
|
|
4014
|
-
const extractQueryObjects = (queryString) => {
|
|
4015
|
-
// Converts a string of GET parameters into an array of parameter objects. Each parameter object contains the properties "name" and "value".
|
|
4016
|
-
if (queryString.indexOf('?') === -1) {
|
|
4017
|
-
return [];
|
|
4018
|
-
}
|
|
4019
|
-
const queryObjects = [];
|
|
4020
|
-
|
|
4021
|
-
const queryPart = queryString.split('?')[1];
|
|
4022
|
-
|
|
4023
|
-
const queryParameters = queryPart.split('&');
|
|
4024
|
-
|
|
4025
|
-
queryParameters.forEach((queryParameter) => {
|
|
4026
|
-
const keyValue = queryParameter.split('=');
|
|
4027
|
-
const queryObject = {};
|
|
4028
|
-
// eslint-disable-next-line prefer-destructuring
|
|
4029
|
-
queryObject.name = keyValue[0];
|
|
4030
|
-
queryObject.value = decodeURIComponent(keyValue[1]);
|
|
4031
|
-
queryObjects.push(queryObject);
|
|
4032
|
-
});
|
|
4033
|
-
|
|
4034
|
-
return queryObjects;
|
|
4035
|
-
};
|
|
4036
|
-
|
|
4037
|
-
const allParameterValuePairsMatchExtreme = (queryStringObject, advancedExpectedParameterValuePairs) => {
|
|
4038
|
-
// More advanced check if all request parameters match with the expectations
|
|
4039
|
-
let littleReport = '\nQuery parameters:\n';
|
|
4040
|
-
let success = true;
|
|
4041
|
-
|
|
4042
|
-
for (const expectedKey in advancedExpectedParameterValuePairs) {
|
|
4043
|
-
if (!Object.prototype.hasOwnProperty.call(advancedExpectedParameterValuePairs, expectedKey)) {
|
|
4044
|
-
continue;
|
|
4045
|
-
}
|
|
4046
|
-
let parameterFound = false;
|
|
4047
|
-
const expectedValue = advancedExpectedParameterValuePairs[expectedKey];
|
|
4048
|
-
|
|
4049
|
-
for (const queryParameter of queryStringObject) {
|
|
4050
|
-
if (queryParameter.name === expectedKey) {
|
|
4051
|
-
parameterFound = true;
|
|
4052
|
-
if (expectedValue === undefined) {
|
|
4053
|
-
littleReport += ` ${expectedKey.padStart(10, ' ')}\n`;
|
|
4054
|
-
} else if (typeof expectedValue === 'object' && expectedValue.base64) {
|
|
4055
|
-
const decodedActualValue = Buffer.from(queryParameter.value, 'base64').toString('utf8');
|
|
4056
|
-
if (decodedActualValue === expectedValue.base64) {
|
|
4057
|
-
littleReport += ` ${expectedKey.padStart(10, ' ')} = base64(${expectedValue.base64})\n`;
|
|
4058
|
-
} else {
|
|
4059
|
-
littleReport += ` ✖ ${expectedKey.padStart(10, ' ')} = base64(${expectedValue.base64}) -> actual value: "base64(${decodedActualValue})"\n`;
|
|
4060
|
-
success = false;
|
|
4061
|
-
}
|
|
4062
|
-
} else if (queryParameter.value === expectedValue) {
|
|
4063
|
-
littleReport += ` ${expectedKey.padStart(10, ' ')} = ${expectedValue}\n`;
|
|
4064
|
-
} else {
|
|
4065
|
-
littleReport += ` ✖ ${expectedKey.padStart(10, ' ')} = ${expectedValue} -> actual value: "${queryParameter.value}"\n`;
|
|
4066
|
-
success = false;
|
|
4067
|
-
}
|
|
4068
|
-
}
|
|
4069
|
-
}
|
|
4070
|
-
|
|
4071
|
-
if (parameterFound === false) {
|
|
4072
|
-
littleReport += ` ✖ ${expectedKey.padStart(10, ' ')}${expectedValue ? ` = ${JSON.stringify(expectedValue)}` : ''} -> parameter not found in request\n`;
|
|
4073
|
-
success = false;
|
|
4074
|
-
}
|
|
4075
|
-
}
|
|
4076
|
-
|
|
4077
|
-
return success ? true : littleReport;
|
|
4078
|
-
};
|
|
4079
|
-
|
|
4080
|
-
const allRequestPostDataValuePairsMatchExtreme = (RequestPostDataObject, advancedExpectedRequestPostValuePairs) => {
|
|
4081
|
-
// More advanced check if all request post data match with the expectations
|
|
4082
|
-
let littleReport = '\nRequest Post Data:\n';
|
|
4083
|
-
let success = true;
|
|
4084
|
-
|
|
4085
|
-
for (const expectedKey in advancedExpectedRequestPostValuePairs) {
|
|
4086
|
-
if (!Object.prototype.hasOwnProperty.call(advancedExpectedRequestPostValuePairs, expectedKey)) {
|
|
4087
|
-
continue;
|
|
4088
|
-
}
|
|
4089
|
-
let keyFound = false;
|
|
4090
|
-
const expectedValue = advancedExpectedRequestPostValuePairs[expectedKey];
|
|
4091
|
-
|
|
4092
|
-
for (const [key, value] of Object.entries(RequestPostDataObject)) {
|
|
4093
|
-
if (key === expectedKey) {
|
|
4094
|
-
keyFound = true;
|
|
4095
|
-
if (expectedValue === undefined) {
|
|
4096
|
-
littleReport += ` ${expectedKey.padStart(10, ' ')}\n`;
|
|
4097
|
-
} else if (typeof expectedValue === 'object' && expectedValue.base64) {
|
|
4098
|
-
const decodedActualValue = Buffer.from(value, 'base64').toString('utf8');
|
|
4099
|
-
if (decodedActualValue === expectedValue.base64) {
|
|
4100
|
-
littleReport += ` ${expectedKey.padStart(10, ' ')} = base64(${expectedValue.base64})\n`;
|
|
4101
|
-
} else {
|
|
4102
|
-
littleReport += ` ✖ ${expectedKey.padStart(10, ' ')} = base64(${expectedValue.base64}) -> actual value: "base64(${decodedActualValue})"\n`;
|
|
4103
|
-
success = false;
|
|
4104
|
-
}
|
|
4105
|
-
} else if (value === expectedValue) {
|
|
4106
|
-
littleReport += ` ${expectedKey.padStart(10, ' ')} = ${expectedValue}\n`;
|
|
4107
|
-
} else {
|
|
4108
|
-
littleReport += ` ✖ ${expectedKey.padStart(10, ' ')} = ${expectedValue} -> actual value: "${value}"\n`;
|
|
4109
|
-
success = false;
|
|
4110
|
-
}
|
|
4111
|
-
}
|
|
4112
|
-
}
|
|
4113
|
-
|
|
4114
|
-
if (keyFound === false) {
|
|
4115
|
-
littleReport += ` ✖ ${expectedKey.padStart(10, ' ')}${expectedValue ? ` = ${JSON.stringify(expectedValue)}` : ''} -> key not found in request\n`;
|
|
4116
|
-
success = false;
|
|
4117
|
-
}
|
|
4118
|
-
}
|
|
4119
|
-
|
|
4120
|
-
return success ? true : littleReport;
|
|
4121
|
-
};
|