diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 13ffd8a..0af5a08 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -9,9 +9,13 @@ on: pull_request: branches: [master] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: build: - runs-on: ubuntu-latest + runs-on: self-hosted-arc strategy: matrix: @@ -29,7 +33,7 @@ jobs: - run: npm test deploy-static: - runs-on: ubuntu-latest + runs-on: self-hosted-arc environment: CI strategy: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 5f2b63f..693393e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -16,7 +16,7 @@ permissions: jobs: # Build job build: - runs-on: ubuntu-latest + runs-on: self-hosted-arc steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 @@ -40,7 +40,7 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest + runs-on: self-hosted-arc needs: build steps: - name: Deploy to GitHub Pages diff --git a/docs/guides/how-to-check-accessibility.mdx b/docs/guides/how-to-check-accessibility.mdx index c00df4a..6aad5c0 100644 --- a/docs/guides/how-to-check-accessibility.mdx +++ b/docs/guides/how-to-check-accessibility.mdx @@ -20,7 +20,7 @@ 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 ({browser}) { +it("should get accessibility tree of yandex.ru", async function ({ browser }) { // Get puppeteer instance const puppeteer = await browser.getPuppeteer(); diff --git a/docs/guides/how-to-hide-scrollbars-by-cdp.mdx b/docs/guides/how-to-hide-scrollbars-by-cdp.mdx index 68d859f..b1fd997 100644 --- a/docs/guides/how-to-hide-scrollbars-by-cdp.mdx +++ b/docs/guides/how-to-hide-scrollbars-by-cdp.mdx @@ -20,7 +20,7 @@ CDP has a special method [Emulation.setScrollbarsHidden][set-scrollbars-hidden] Here's how it looks: ```javascript -it("should hide scrollbar", async function ({browser}) { +it("should hide scrollbar", async function ({ browser }) { // Get puppeteer instance const puppeteer = await browser.getPuppeteer(); diff --git a/docs/guides/how-to-intercept-requests-and-responses.mdx b/docs/guides/how-to-intercept-requests-and-responses.mdx index 5789c29..1ee405a 100644 --- a/docs/guides/how-to-intercept-requests-and-responses.mdx +++ b/docs/guides/how-to-intercept-requests-and-responses.mdx @@ -30,7 +30,7 @@ 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 ({browser}) { +it("should mock google.com", async function ({ browser }) { // Mocking the request to google.com const mock = await browser.mock("https://google.com"); @@ -46,7 +46,7 @@ it("should mock google.com", async function ({browser}) { 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 ({browser}) { +it("should mock google.com using puppeteer api", async function ({ browser }) { // Get puppeteer instance const puppeteer = await browser.getPuppeteer(); @@ -78,7 +78,7 @@ it("should mock google.com using puppeteer api", async function ({browser}) { 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 ({browser}) { +it("should mock google.com using cdp fetch domain", async function ({ browser }) { // Get puppeteer instance const puppeteer = await browser.getPuppeteer(); @@ -122,7 +122,7 @@ 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 ({browser}) { +it("should abort request to logo on google.com", async function ({ browser }) { // You can use a mask for the URL const mock = await browser.mock("https://www.google.com/images/**/*.png"); @@ -138,7 +138,7 @@ 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 ({browser}) { +it("should mock google.com and return answer from fixture", async function ({ browser }) { // Mocking the request to google.com const mock = await browser.mock("https://google.com"); @@ -155,7 +155,7 @@ 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 ({browser}) { +it("should redirect from google.com to yandex.ru", async function ({ browser }) { // Mocking the request to google.com const mock = await browser.mock("https://google.com"); @@ -173,7 +173,7 @@ 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 ({browser}) { +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 browser.mock("https://www.google.com"); @@ -190,7 +190,7 @@ it("should modify response from google.com", async function ({browser}) { 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 ({browser}) { +it("should modify response from google.com", async function ({ browser }) { // The first argument specifies that we will intercept all requests const mock = await browser.mock("**", { headers: headers => { @@ -217,7 +217,7 @@ it("should modify response from google.com", async function ({browser}) { 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 ({browser}) { +it("should mock yandex.ru and log all loaded urls", async function ({ browser }) { // Intercept absolutely all requests const mock = await browser.mock("**"); @@ -235,7 +235,7 @@ it("should mock yandex.ru and log all loaded urls", async function ({browser}) { 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 ({browser}) { +it("should mock yandex.ru and log all loaded urls (using puppeteer)", async function ({ browser }) { // Accumulative list of all URLs const urls = []; @@ -298,7 +298,7 @@ module.exports = { "testplane-global-hook": { enabled: true, - beforeEach: async function ({browser}) { + beforeEach: async function ({ browser }) { // Check that the browser name starts with "chrome" if (!/^chrome$/i.test(browser.capabilities.browserName)) { return; @@ -309,7 +309,7 @@ module.exports = { mock.respond("hello world", { fetchResponse: false }); }, - afterEach: function ({browser}) { + afterEach: function ({ browser }) { // Clear all mocks in the current session browser.mockRestoreAll(); }, @@ -327,7 +327,7 @@ 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 ({browser}) { +it("should mock google.com inside global before each", async function ({ browser }) { await browser.url("https://google.com"); }); ``` diff --git a/docs/guides/how-to-manage-cpu-performance.mdx b/docs/guides/how-to-manage-cpu-performance.mdx index 127a77e..f6db9d6 100644 --- a/docs/guides/how-to-manage-cpu-performance.mdx +++ b/docs/guides/how-to-manage-cpu-performance.mdx @@ -18,7 +18,7 @@ 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 ({browser}) { +it("should open yandex.ru with emulation 8x slower CPU", async function ({ browser }) { // Get puppeteer instance const puppeteer = await browser.getPuppeteer(); @@ -39,7 +39,7 @@ 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 ({browser}) { +it("should open yandex.ru with emulation 8x slower CPU", async function ({ browser }) { // Get puppeteer instance const puppeteer = await browser.getPuppeteer(); diff --git a/docs/guides/how-to-manage-network-bandwidth.mdx b/docs/guides/how-to-manage-network-bandwidth.mdx index 5e16f03..0e0ce69 100644 --- a/docs/guides/how-to-manage-network-bandwidth.mdx +++ b/docs/guides/how-to-manage-network-bandwidth.mdx @@ -28,7 +28,7 @@ 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 ({browser}) { +it("should open yandex.ru with emulation of 2G-connection", async function ({ browser }) { // Emulate a 2G connection await browser.throttle("Good2G"); @@ -41,7 +41,7 @@ it("should open yandex.ru with emulation of 2G-connection", async function ({bro We can also emulate a connection with specific characteristics: ```javascript -it("should open yandex.ru with emulation of custom connection", async function ({browser}) { +it("should open yandex.ru with emulation of custom connection", async function ({ browser }) { // Emulate a network connection with specified characteristics await browser.throttle({ offline: false, // emulate offline state diff --git a/docs/plugins/testplane-global-hook.mdx b/docs/plugins/testplane-global-hook.mdx index 12bb340..7e4094e 100644 --- a/docs/plugins/testplane-global-hook.mdx +++ b/docs/plugins/testplane-global-hook.mdx @@ -30,10 +30,10 @@ Add the plugin to the `plugins` section of the `testplane` config: module.exports = { plugins: { "testplane-global-hook": { - beforeEach: async function ({browser}) { + beforeEach: async function ({ browser }) { await browser.deleteCookie(); // Say, we want to always clear cookies before running a test }, - afterEach: async function ({browser}) { + afterEach: async function ({ browser }) { await browser.execute(function () { try { localStorage.clear(); // And always clean up the localStorage after the test is completed diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-check-accessibility.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-check-accessibility.mdx index f618532..bd7b655 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-check-accessibility.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-check-accessibility.mdx @@ -20,7 +20,7 @@ import Admonition from "@theme/Admonition"; Вот пример, как его можно использовать: ```javascript -it("should get accessibility tree of yandex.ru", async function ({browser}) { +it("should get accessibility tree of yandex.ru", async function ({ browser }) { // Получаем инстанс puppeteer'а const puppeteer = await browser.getPuppeteer(); diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-hide-scrollbars-by-cdp.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-hide-scrollbars-by-cdp.mdx index 36b5bc3..125dc1d 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-hide-scrollbars-by-cdp.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-hide-scrollbars-by-cdp.mdx @@ -20,7 +20,7 @@ import Admonition from "@theme/Admonition"; Вот как это будет выглядеть: ```javascript -it("should hide scrollbar", async function ({browser}) { +it("should hide scrollbar", async function ({ browser }) { // Получаем инстанс puppeteer'а const puppeteer = await browser.getPuppeteer(); diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-intercept-requests-and-responses.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-intercept-requests-and-responses.mdx index 27db321..017b2f6 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-intercept-requests-and-responses.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-intercept-requests-and-responses.mdx @@ -30,7 +30,7 @@ import Admonition from "@theme/Admonition"; ## Пример 1: мокаем запрос к google.com и возвращаем свой ответ {#example_1} ```javascript -it("should mock google.com", async function ({browser}) { +it("should mock google.com", async function ({ browser }) { // Мокаем поход на google.com const mock = await browser.mock("https://google.com"); @@ -46,7 +46,7 @@ it("should mock google.com", async function ({browser}) { По графическому изображению видно, что мы вернули свой текст, при этом в строке браузера отображается как будто мы выполнили переход на _google.com._ Также видно, что мы не замокали фавиконку и она приехала снаружи. Этот же самый пример мы можем написать с использованием API puppeteer'а, для этого в _webdriverio_ реализована команда [getPuppeteer()][get-puppeteer]: ```javascript -it("should mock google.com using puppeteer api", async function ({browser}) { +it("should mock google.com using puppeteer api", async function ({ browser }) { // Получаем инстанс puppeteer'а const puppeteer = await browser.getPuppeteer(); @@ -78,7 +78,7 @@ it("should mock google.com using puppeteer api", async function ({browser}) { А теперь представим, что в _puppeteer_ еще нет API для мока запросов, но это уже реализовано в домене [Fetch][fetch] CDP. В этом случае воспользуемся методом этого домена через общение с CDP-сессией напрямую. Для этого в _puppeteer_ есть метод [CDPSession.send()][cdp-session-send]: ```javascript -it("should mock google.com using cdp fetch domain", async function ({browser}) { +it("should mock google.com using cdp fetch domain", async function ({ browser }) { // Получаем инстанс puppeteer'а const puppeteer = await browser.getPuppeteer(); @@ -122,7 +122,7 @@ it("should mock google.com using cdp fetch domain", async function ({browser}) { ## Пример 2: отменяем запрос за логотипом гугла {#example_2} ```javascript -it("should abort request to logo on google.com", async function ({browser}) { +it("should abort request to logo on google.com", async function ({ browser }) { // В качестве урла можно использовать маску const mock = await browser.mock("https://www.google.com/images/**/*.png"); @@ -138,7 +138,7 @@ it("should abort request to logo on google.com", async function ({browser}) { ## Пример 3: при загрузке google.com берем ответ из фикстуры {#example_3} ```javascript -it("should mock google.com and return answer from fixture", async function ({browser}) { +it("should mock google.com and return answer from fixture", async function ({ browser }) { // Мокаем поход на google.com const mock = await browser.mock("https://google.com"); @@ -155,7 +155,7 @@ it("should mock google.com and return answer from fixture", async function ({bro ## Пример 4: перенаправляем запрос с google.com на yandex.ru {#example_4} ```javascript -it("should redirect from google.com to yandex.ru", async function ({browser}) { +it("should redirect from google.com to yandex.ru", async function ({ browser }) { // Мокаем поход на google.com const mock = await browser.mock("https://google.com"); @@ -173,7 +173,7 @@ it("should redirect from google.com to yandex.ru", async function ({browser}) { Заменим в ответе от _google.com_ все строки содержащие `Google` на `Yandex`: ```javascript -it("should modify response from google.com", async function ({browser}) { +it("should modify response from google.com", async function ({ browser }) { // Тут нужно мокать именно с www, так как переход на google.com // возвращает ответ 301 без body и перенаправляет нас на www const mock = await browser.mock("https://www.google.com"); @@ -190,7 +190,7 @@ it("should modify response from google.com", async function ({browser}) { Кроме этого, мы можем видоизменять ответы от заранее неизвестных источников. Например, давайте модифицируем все скрипты, загружаемые на _google.com:_ ```javascript -it("should modify response from google.com", async function ({browser}) { +it("should modify response from google.com", async function ({ browser }) { // Первым аргументом указываем, что будем перехватывать абсолютно все запросы const mock = await browser.mock("**", { headers: headers => { @@ -217,7 +217,7 @@ it("should modify response from google.com", async function ({browser}) { Предположим, что нам необходимо собрать список всех урлов, которые загружаются на странице. Используя эту информацию мы могли бы определить, есть ли у нас походы за внешними ресурсами или в соседние сервисы, которые мы никак не контролируем. Это означает, что они в любой момент могут не ответить и сломать нам тесты. Как мог бы выглядеть наш код: ```javascript -it("should mock yandex.ru and log all loaded urls", async function ({browser}) { +it("should mock yandex.ru and log all loaded urls", async function ({ browser }) { // Перехватываем абсолютно все запросы const mock = await browser.mock("**"); @@ -235,7 +235,7 @@ it("should mock yandex.ru and log all loaded urls", async function ({browser}) { Скорее всего, ваши тесты сложнее этих примеров и у вас будут различные клики в элементы, которые открываются в новых табах. В таких случаях предыдущий код ничего не узнает об открытии новых вкладок, а также о том, что в них тоже нужно собрать список урлов. Поэтому для такого случая нужно использовать API puppeteer'а: ```javascript -it("should mock yandex.ru and log all loaded urls (using puppeteer)", async function ({browser}) { +it("should mock yandex.ru and log all loaded urls (using puppeteer)", async function ({ browser }) { // В этой переменной будем накапливать список всех урлов const urls = []; @@ -298,7 +298,7 @@ module.exports = { "testplane-global-hook": { enabled: true, - beforeEach: async function ({browser}) { + beforeEach: async function ({ browser }) { // Проверяем, что имя браузера не начинается на "chrome" if (!/^chrome$/i.test(browser.capabilities.browserName)) { return; @@ -309,7 +309,7 @@ module.exports = { mock.respond("hello world", { fetchResponse: false }); }, - afterEach: function ({browser}) { + afterEach: function ({ browser }) { // Очищаем все моки в текущей сессии browser.mockRestoreAll(); }, @@ -327,7 +327,7 @@ module.exports = { ```javascript // Явно укажем, чтобы тест выполнялся только в браузерах, название которых начинается с chrome testplane.only.in(/^chrome/); -it("should mock google.com inside global before each", async function ({browser}) { +it("should mock google.com inside global before each", async function ({ browser }) { await browser.url("https://google.com"); }); ``` diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-cpu-performance.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-cpu-performance.mdx index 2300905..339e2fb 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-cpu-performance.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-cpu-performance.mdx @@ -18,7 +18,7 @@ import Admonition from "@theme/Admonition"; Воспользуемся этим методом, чтобы замедлить скорость процессора в 8 раз: ```javascript -it("should open yandex.ru with emulation 8x slower CPU", async function ({browser}) { +it("should open yandex.ru with emulation 8x slower CPU", async function ({ browser }) { // Получаем инстанс puppeteer'а const puppeteer = await browser.getPuppeteer(); @@ -39,7 +39,7 @@ it("should open yandex.ru with emulation 8x slower CPU", async function ({browse Однако это ограничение можно было обойти с помощью метода _puppeteer_ [CDPSession.send()][cdp-session-send], отправив браузеру команду [Emulation.setCPUThrottlingRate][emulation-set-cpu-throttling-rate] по CDP: ```javascript -it("should open yandex.ru with emulation 8x slower CPU", async function ({browser}) { +it("should open yandex.ru with emulation 8x slower CPU", async function ({ browser }) { // Получаем инстанс puppeteer'а const puppeteer = await browser.getPuppeteer(); diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-network-bandwidth.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-network-bandwidth.mdx index 1964949..4fdbabe 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-network-bandwidth.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/guides/how-to-manage-network-bandwidth.mdx @@ -28,7 +28,7 @@ import Admonition from "@theme/Admonition"; Сэмулируем 2G-соединение и откроем yandex.ru в Хроме с эмуляцией телефона: ```javascript -it("should open yandex.ru with emulation of 2G-connection", async function ({browser}) { +it("should open yandex.ru with emulation of 2G-connection", async function ({ browser }) { // Имитируем 2G-соединение await browser.throttle("Good2G"); @@ -41,7 +41,7 @@ it("should open yandex.ru with emulation of 2G-connection", async function ({bro Также мы можем сэмулировать соединение с конкретными характеристиками: ```javascript -it("should open yandex.ru with emulation of custom connection", async function ({browser}) { +it("should open yandex.ru with emulation of custom connection", async function ({ browser }) { // Имитируем соединение в сети с заданными характеристиками await browser.throttle({ offline: false, // имитация отключения от интернета diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/plugins/testplane-global-hook.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/plugins/testplane-global-hook.mdx index b4e9782..e77526b 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/plugins/testplane-global-hook.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/plugins/testplane-global-hook.mdx @@ -30,10 +30,10 @@ npm install -D testplane-global-hook module.exports = { plugins: { "testplane-global-hook": { - beforeEach: async function ({browser}) { + beforeEach: async function ({ browser }) { await browser.deleteCookie(); // Например, мы хотим всегда очищать cookies перед запуском теста }, - afterEach: async function ({browser}) { + afterEach: async function ({ browser }) { await browser.execute(function () { try { localStorage.clear(); // И всегда очищать за собой localStorage после завершения теста @@ -81,6 +81,7 @@ module.exports = { + ## Полезные ссылки {#useful_links}