Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
.env.development.local
.env.test.local
.env.production.local
.vscode/

npm-debug.log*

Expand Down
2 changes: 1 addition & 1 deletion docs/commands/browser/assertView.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Required parameter. Specifies the name of the test state. The name must be uniqu

### selector

Required parameter. Specifies the selector of the DOM element to capture. If not specified or skipped, will be set to `body` and the following options will be automatically added to `options`:
Optional parameter. Specifies the selector of the DOM element to capture. If not specified or skipped, will be set to `body` and the following options will be automatically added to `options`:

```
{
Expand Down
3 changes: 2 additions & 1 deletion docs/commands/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ However, the command descriptions on the [WebDriverIO][webdriverio-api] website

```javascript
it("should test something", async function () {
const browser = this.browser;
await this.browser.url("https://testplane.io");
// test code...
});
```
Expand All @@ -31,6 +31,7 @@ or get the `browser` object from the function argument (note that the `browser`

```javascript
it("should test something", async ({ browser }) => {
await browser.url("https://testplane.io");
// test code...
});
```
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/how-to-check-accessibility.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ To obtain such a tree, _puppeteer_ has a special [Accessibility class][puppeteer
Here's an example of how to use it:

```javascript
it("should get accessibility tree of yandex.ru", async function () {
it("should get accessibility tree of yandex.ru", async function ({browser}) {
// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get the first open page (considering it to be currently active)
const [page] = await puppeteer.pages();

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");

// Get the current state of the accessibility tree
const snapshot = await page.accessibility.snapshot();
Expand Down
6 changes: 3 additions & 3 deletions docs/guides/how-to-hide-scrollbars-by-cdp.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ CDP has a special method [Emulation.setScrollbarsHidden][set-scrollbars-hidden]
Here's how it looks:

```javascript
it("should hide scrollbar", async function () {
it("should hide scrollbar", async function ({browser}) {
// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get the first open page (considering it to be currently active)
const [page] = await puppeteer.pages();
Expand All @@ -33,7 +33,7 @@ it("should hide scrollbar", async function () {
// Hide the scrollbar
await client.send("Emulation.setScrollbarsHidden", { hidden: true });

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");
});
```

Expand Down
76 changes: 38 additions & 38 deletions docs/guides/how-to-intercept-requests-and-responses.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -30,25 +30,25 @@ Let's try writing tests using this API and cover different cases. To clarify, al
## Example 1: Mocking a Request to google.com and Returning Our Own Response {#example_1}

```javascript
it("should mock google.com", async function () {
it("should mock google.com", async function ({browser}) {
// Mocking the request to google.com
const mock = await this.browser.mock("https://google.com");
const mock = await browser.mock("https://google.com");

// Returning the string "Hello, world!" instead of the response from the site.
// The "fetchResponse" option dictates whether the request should be made
// to the mocked resource; default is true.
mock.respond("Hello, world!", { fetchResponse: false });

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

From the graphical representation, you can see that we returned our text, although the browser's address bar shows we navigated to _google.com._ Also, it's clear that we didn't mock the favicon, which was fetched from an external source. We can write this same example using the puppeteer API. For this, _webdriverio_ has the [getPuppeteer()][get-puppeteer] command:

```javascript
it("should mock google.com using puppeteer api", async function () {
it("should mock google.com using puppeteer api", async function ({browser}) {
// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get the first open page (considering it to be currently active)
const [page] = await puppeteer.pages();
Expand All @@ -69,7 +69,7 @@ it("should mock google.com using puppeteer api", async function () {
// Here, we could call "page.goto('https://google.com')", but it's better to call "url",
// because most plugins have wrappers for the "url" command adding additional logic.
// For example, in testplane, the URL is added to the meta.
await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Expand All @@ -78,9 +78,9 @@ it("should mock google.com using puppeteer api", async function () {
Now, let's imagine that puppeteer doesn't yet have an API for mocking requests, but this is already implemented in the [Fetch][fetch] domain of CDP. In this case, we will use this domain's method by interacting with the CDP session directly. For this, puppeteer has the [CDPSession.send()][cdp-session-send] method:

```javascript
it("should mock google.com using cdp fetch domain", async function () {
it("should mock google.com using cdp fetch domain", async function ({browser}) {
// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get the first open page (considering it to be currently active)
const [page] = await puppeteer.pages();
Expand Down Expand Up @@ -113,7 +113,7 @@ it("should mock google.com using cdp fetch domain", async function () {
});
});

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Expand All @@ -122,14 +122,14 @@ Obviously, when using the _webdriverio_ API for mocking requests, the code is mu
## Example 2: Canceling the Request for Google's Logo {#example_2}

```javascript
it("should abort request to logo on google.com", async function () {
it("should abort request to logo on google.com", async function ({browser}) {
// You can use a mask for the URL
const mock = await this.browser.mock("https://www.google.com/images/**/*.png");
const mock = await browser.mock("https://www.google.com/images/**/*.png");

// Throw an error "ERR_FAILED" when loading a resource that matches the mask
mock.abort("Failed");

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Expand All @@ -138,15 +138,15 @@ From the graphical representation, it is clear that the logo is not displayed, a
## Example 3: Loading google.com Using a Fixture for the Response {#example_3}

```javascript
it("should mock google.com and return answer from fixture", async function () {
it("should mock google.com and return answer from fixture", async function ({browser}) {
// Mocking the request to google.com
const mock = await this.browser.mock("https://google.com");
const mock = await browser.mock("https://google.com");

// Specify the path from which to take the fixture, and with
// "fetchResponse: false", indicate that the real request should not be made
mock.respond("./fixtures/my-google.com.html", { fetchResponse: false });

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Expand All @@ -155,14 +155,14 @@ From the graphical representation, it is clear that instead of google.com's cont
## Example 4: Redirecting the Request from google.com to yandex.ru {#example_4}

```javascript
it("should redirect from google.com to yandex.ru", async function () {
it("should redirect from google.com to yandex.ru", async function ({browser}) {
// Mocking the request to google.com
const mock = await this.browser.mock("https://google.com");
const mock = await browser.mock("https://google.com");

// For redirection, simply specify the URL
mock.respond("https://yandex.ru");

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Expand All @@ -173,26 +173,26 @@ Puppeteer still does not have an API for conveniently modifying responses. There
Replace all occurrences of the string `Google` with `Yandex` in google.com's response:

```javascript
it("should modify response from google.com", async function () {
it("should modify response from google.com", async function ({browser}) {
// Here, you need to mock with www because navigating to google.com
// returns a 301 response without a body and redirects to www
const mock = await this.browser.mock("https://www.google.com");
const mock = await browser.mock("https://www.google.com");

mock.respond(req => {
// Replace "Google" with "Yandex" using a regular expression
return req.body.replace(/Google/g, "Yandex");
});

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Additionally, we can modify responses from unknown sources in advance. For example, let's modify all scripts loaded on _google.com:_

```javascript
it("should modify response from google.com", async function () {
it("should modify response from google.com", async function ({browser}) {
// The first argument specifies that we will intercept all requests
const mock = await this.browser.mock("**", {
const mock = await browser.mock("**", {
headers: headers => {
// Filter only the requests where the "content-type"
// header contains values "text/javascript" or "application/javascript"
Expand All @@ -208,7 +208,7 @@ it("should modify response from google.com", async function () {
return (req.body += `\nconsole.log("This script was modified in real time.");`);
});

await this.browser.url("https://google.com");
await browser.url("https://google.com");
});
```

Expand All @@ -217,11 +217,11 @@ it("should modify response from google.com", async function () {
Let's say we need to collect a list of all URLs loaded on the page. Using this information, we could determine if we have requests for external resources or neighboring services that we do not control. This means they could fail at any time and break our tests. Here's what our code might look like:

```javascript
it("should mock yandex.ru and log all loaded urls", async function () {
it("should mock yandex.ru and log all loaded urls", async function ({browser}) {
// Intercept absolutely all requests
const mock = await this.browser.mock("**");
const mock = await browser.mock("**");

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");

// mock.calls contains not only the visited URL information
// but also the response from the source, the request headers, response headers, etc.
Expand All @@ -235,7 +235,7 @@ it("should mock yandex.ru and log all loaded urls", async function () {
Most likely, your tests are more complex than these examples and involve various clicks on elements that open in new tabs. In such cases, the previous code will not capture the opening of new tabs or that URLs need to be collected there as well. Therefore, in such cases, you need to use puppeteer's API:

```javascript
it("should mock yandex.ru and log all loaded urls (using puppeteer)", async function () {
it("should mock yandex.ru and log all loaded urls (using puppeteer)", async function ({browser}) {
// Accumulative list of all URLs
const urls = [];

Expand All @@ -249,7 +249,7 @@ it("should mock yandex.ru and log all loaded urls (using puppeteer)", async func
}

// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get all open pages at the current moment
const pages = await puppeteer.pages();
Expand All @@ -274,10 +274,10 @@ it("should mock yandex.ru and log all loaded urls (using puppeteer)", async func
urlsHandler(page);
});

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");

// Find the first element in the list of services (at that time it was a football page)
const elem = await this.browser.$(".services-new__list-item > a");
const elem = await browser.$(".services-new__list-item > a");

// Click the service that opens in a new tab
await elem.click();
Expand All @@ -298,20 +298,20 @@ module.exports = {
"testplane-global-hook": {
enabled: true,

beforeEach: async function () {
beforeEach: async function ({browser}) {
// Check that the browser name starts with "chrome"
if (!/^chrome$/i.test(this.browser.capabilities.browserName)) {
if (!/^chrome$/i.test(browser.capabilities.browserName)) {
return;
}

// Mocking the request to google.com
const mock = await this.browser.mock("https://google.com");
const mock = await browser.mock("https://google.com");
mock.respond("hello world", { fetchResponse: false });
},

afterEach: function () {
afterEach: function ({browser}) {
// Clear all mocks in the current session
this.browser.mockRestoreAll();
browser.mockRestoreAll();
},
},

Expand All @@ -327,8 +327,8 @@ The test code will now only contain the URL transition:
```javascript
// Explicitly indicate that the test is only executed in browsers whose name starts with chrome
testplane.only.in(/^chrome/);
it("should mock google.com inside global before each", async function () {
await this.browser.url("https://google.com");
it("should mock google.com inside global before each", async function ({browser}) {
await browser.url("https://google.com");
});
```

Expand Down
12 changes: 6 additions & 6 deletions docs/guides/how-to-manage-cpu-performance.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ The CPU speed on mobile devices is significantly slower than on computers. There
Let's use this method to slow down CPU speed by 8 times:

```javascript
it("should open yandex.ru with emulation 8x slower CPU", async function () {
it("should open yandex.ru with emulation 8x slower CPU", async function ({browser}) {
// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get the first open page (considering it to be currently active)
const [page] = await puppeteer.pages();

// Slow down the CPU speed by 8 times
await page.emulateCPUThrottling(8);

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");
});
```

Expand All @@ -39,9 +39,9 @@ Initially, _webdriverio_ did not support the `page.emulateCPUThrottling` method
However, this limitation could be bypassed using puppeteer's [CDPSession.send()][cdp-session-send] method by sending the browser the [Emulation.setCPUThrottlingRate][emulation-set-cpu-throttling-rate] command via CDP:

```javascript
it("should open yandex.ru with emulation 8x slower CPU", async function () {
it("should open yandex.ru with emulation 8x slower CPU", async function ({browser}) {
// Get puppeteer instance
const puppeteer = await this.browser.getPuppeteer();
const puppeteer = await browser.getPuppeteer();

// Get the first open page (considering it to be currently active)
const [page] = await puppeteer.pages();
Expand All @@ -52,7 +52,7 @@ it("should open yandex.ru with emulation 8x slower CPU", async function () {
// Slow down the CPU speed by 8 times
await client.send("Emulation.setCPUThrottlingRate", { rate: 8 });

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");
});
```

Expand Down
12 changes: 6 additions & 6 deletions docs/guides/how-to-manage-network-bandwidth.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,11 @@ Besides custom settings, the [throttle][throttle] method supports the following
Let's emulate a 2G connection and open yandex.ru in Chrome with phone emulation:

```javascript
it("should open yandex.ru with emulation of 2G-connection", async function () {
it("should open yandex.ru with emulation of 2G-connection", async function ({browser}) {
// Emulate a 2G connection
await this.browser.throttle("Good2G");
await browser.throttle("Good2G");

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");
});
```

Expand All @@ -41,16 +41,16 @@ it("should open yandex.ru with emulation of 2G-connection", async function () {
We can also emulate a connection with specific characteristics:

```javascript
it("should open yandex.ru with emulation of custom connection", async function () {
it("should open yandex.ru with emulation of custom connection", async function ({browser}) {
// Emulate a network connection with specified characteristics
await this.browser.throttle({
await browser.throttle({
offline: false, // emulate offline state
downloadThroughput: (10 * 1024) / 8, // max download bandwidth (byte/sec)
uploadThroughput: (10 * 1024) / 8, // max upload bandwidth (byte/sec)
latency: 10, // min latency from sending the request to receiving the response headers
});

await this.browser.url("https://yandex.ru");
await browser.url("https://yandex.ru");
});
```

Expand Down
Loading
Loading