From 78be5b48e2763aef73afba49dbe926c4608d0883 Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Mon, 23 Mar 2026 08:16:13 +0300 Subject: [PATCH 01/12] docs: first priority changes draft --- docs/quickstart/running-tests.mdx | 4 +- .../current/quickstart/index.mdx | 31 +++++- .../current/quickstart/running-tests.mdx | 105 +++++++++++++++++- .../current/quickstart/writing-tests.mdx | 24 +++- 4 files changed, 147 insertions(+), 17 deletions(-) diff --git a/docs/quickstart/running-tests.mdx b/docs/quickstart/running-tests.mdx index 81a4364..c0372d6 100644 --- a/docs/quickstart/running-tests.mdx +++ b/docs/quickstart/running-tests.mdx @@ -18,7 +18,7 @@ You can also run tests in `gui` mode. To do this, execute the command: npx testplane gui ``` -### Running a specific test +### Running a specific test {#the_grep_option} Consider the following set of tests: @@ -96,7 +96,7 @@ describe("Browser specific tests", () => { }); ``` -### Running a test from a specific file +### Running a test from a specific file {#running_a_specific_file} To run tests from a specific file, execute the command: diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx index 4611679..2bd951e 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx @@ -20,7 +20,7 @@ import Admonition from "@theme/Admonition"; npm init testplane@latest YOUR_PROJECT_PATH ``` -Чтобы настроить проект, а не использовать дефолты при его инициализации, укажите опцию `-v`. +Чтобы настроить проект, а не использовать дефолты при его инициализации, укажите опцию `-v`. После выполнения команды установки в директории проекта появится следующий набор файлов и папок: @@ -40,15 +40,25 @@ testplane.config.ts ```typescript export default { + // gridUrl: "local" — запуск браузеров локально на вашей машине + // Для удалённого запуска укажите URL Selenium Grid или облачного сервиса (например, BrowserStack) gridUrl: "local", + baseUrl: "http://localhost", + + // pageLoadTimeout — максимальное время ожидания загрузки страницы (0 = без ограничений) pageLoadTimeout: 0, + httpTimeout: 60000, + + // testTimeout — максимальное время выполнения одного теста (в миллисекундах) testTimeout: 90000, + resetCursor: false, - // В параметре sets содержится информация о директории, в которой находятся тесты - // и перечень браузеров, в которых они будут запускаться: + // sets — группы тестов, привязанные к определённым браузерам + // Позволяет запускать разные наборы тестов в разных браузерах + // Например: десктопные тесты в Chrome/Firefox, мобильные в Safari sets: { desktop: { files: ["testplane-tests/**/*.testplane.(t|j)s"], @@ -56,7 +66,7 @@ export default { }, }, - // В поле `browsers` описана конфигурация используемых браузеров: + // browsers — конфигурация для каждого браузера browsers: { chrome: { headless: true, @@ -72,6 +82,9 @@ export default { }, }, + // html-reporter — инструмент для просмотра результатов тестов в браузере + // Предоставляет интерактивные отчёты со скриншотами, логами и возможностями отладки + // Подробнее: https://testplane.io/ru/docs/html-reporter/overview plugins: { "html-reporter/testplane": { enabled: true, @@ -83,10 +96,18 @@ export default { }; ``` +**Ключевые концепции:** + +- **gridUrl: "local"** — браузеры запускаются на вашей локальной машине. Для запуска тестов на удалённой инфраструктуре (Selenium Grid, BrowserStack, Sauce Labs) укажите URL грида. +- **sets** — позволяют группировать тесты и запускать их в определённых браузерах. Например, можно создать отдельные наборы для десктопных и мобильных тестов. Подробнее в [справочнике по sets](../reference/config/sets.mdx). +- **testTimeout** — если тест выполняется дольше этого значения, он будет прерван. Настраивайте в зависимости от сложности вашего приложения. + +Полный список параметров конфигурации см. в [справочнике по конфигурации](../reference/config/main.mdx). + Чтобы загрузить браузеры, описанные в конфиге, отдельно от запуска самого Testplane, выполните команду: ```bash npx testplane install-deps ``` -Без предварительного запуска команды, недостающие браузеры будут автоматически загружены с первым запуском Testplane. +Без предварительного запуска команды недостающие браузеры будут автоматически загружены с первым запуском Testplane. diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index 094fa00..b8ff3d0 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -18,7 +18,7 @@ npx testplane npx testplane gui ``` -### Запуск конкретного теста +### Запуск конкретного теста {#the_grep_option} У вас имеется набор тестов, и вам нужно запустить только один из них. @@ -77,26 +77,26 @@ testplane --browser chrome // tests/browser-specific.test.js describe("Browser specific tests", () => { it("should work in all browsers", async ({ browser }) => { - await browser.url("https://example.com"); + await browser.url("https://testplane.io/ru/"); }); // Пропустить тест в Safari testplane.skip.in("safari", "Feature not supported in Safari"); it("should work only in Chrome and Firefox", async ({ browser }) => { - await browser.url("https://example.com"); + await browser.url("https://testplane.io/ru/"); // ... тело теста }); // Запустить только в Chrome testplane.only.in("chrome"); it("should work only in Chrome", async ({ browser }) => { - await browser.url("https://example.com"); + await browser.url("https://testplane.io/ru/"); // ... тело теста }); }); ``` -### Запуск теста из конкретного файла +### Запуск теста из конкретного файла {#running_a_specific_file} Чтобы запустить тесты из конкретного файла, выполните команду: @@ -159,3 +159,98 @@ it("отладка с паузой", async ({ browser }) => { И находить нестабильные, медленные тесты или другие проблемы с помощью опций «сортировка» и «группировка». ![](/gif/docs/ui/analytics.gif) + +## Диагностика ошибок + +Когда тест падает, важно быстро найти причину. Вот базовый чеклист для диагностики: + +### Где найти информацию об ошибке + +**В консоли:** +- Сообщение об ошибке выводится в терминал при запуске `npx testplane` +- Показывает стек вызовов и строку, где произошла ошибка + +**В HTML-репорте:** +- Запустите `npx testplane gui` для интерактивного просмотра +- Упавшие тесты отмечены красным цветом +- Кликните на тест, чтобы увидеть детали: скриншоты, логи, сообщение об ошибке + +### Как найти упавший тест + +1. **По имени теста** — используйте `--grep`: + ```bash + testplane --grep "название теста" + ``` + +2. **В UI-режиме** — используйте фильтры и поиск: + - Фильтр "failed" покажет только упавшие тесты + - Поиск по имени теста или файлу + +### Что проверять в первую очередь + +#### 1. Селекторы +Самая частая причина падения тестов — изменился селектор элемента. + +```javascript +// Плохо: селектор может измениться +await browser.$(".btn-primary").click(); + +// Хорошо: используйте data-атрибуты +await browser.$("[data-testid='submit-button']").click(); +``` + +**Как проверить:** +- Откройте страницу в браузере +- Используйте DevTools для проверки, существует ли элемент с таким селектором +- Проверьте, не изменилась ли вёрстка + +#### 2. Ожидания (таймауты) +Элемент может появляться с задержкой, и тест не успевает дождаться. + +```javascript +// Может упасть, если элемент загружается медленно +const button = await browser.$(".button"); +await button.click(); + +// Явно ждём появления элемента +const button = await browser.$(".button"); +await button.waitForDisplayed({ timeout: 5000 }); +await button.click(); +``` + +**Как проверить:** +- Увеличьте таймаут в конфиге (`testTimeout`, `pageLoadTimeout`) +- Добавьте явные ожидания `waitForDisplayed()`, `waitForClickable()` + +#### 3. Данные и окружение +Тест может падать из-за отсутствия тестовых данных или проблем с окружением. + +**Как проверить:** +- Убедитесь, что тестовое окружение доступно +- Проверьте, что тестовые данные существуют (пользователи, товары и т.д.) +- Проверьте переменные окружения и конфигурацию + +#### 4. Состояние браузера +Иногда тесты падают из-за состояния, оставшегося от предыдущих тестов. + +**Как проверить:** +- Очищайте cookies и localStorage в хуках `beforeEach` +- Используйте изолированные тестовые данные +- Проверьте, не влияют ли тесты друг на друга + +### Полезные команды для диагностики + +```bash +# Запустить только упавший тест +testplane --grep "название упавшего теста" + +# Запустить в одном браузере для ускорения +testplane --browser chrome --grep "название теста" + +# Запустить в GUI для визуальной отладки +testplane gui +``` + +Если тест падает нестабильно (флакает), используйте `browser.pause()` или `browser.debug()` для пошаговой отладки. В GUI-режиме можно замедлить выполнение теста и наблюдать за каждым шагом. + +Подробнее об отладке читайте в разделе [Отладка тестов](../basic-guides/debugging-tests.mdx). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx index f3ebb1f..4bdf177 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx @@ -32,21 +32,21 @@ describe("test examples", () => { it("docs search test", async ({ browser }) => { await browser.openAndWait("https://testplane.io/"); - // Find by tag name + // Поиск по имени тега const navBar = await browser.$("nav"); - // Find by aria-label + // Поиск по aria-label await navBar.$("aria/Search").click(); - // Find by placeholder + // Поиск по placeholder const fileSearchInput = await browser.findByPlaceholderText("Search docs"); await fileSearchInput.waitForDisplayed(); await fileSearchInput.setValue("config"); - // Find by id + // Поиск по id const fileSearchResults = await browser.$("#docsearch-list"); - // Find by role + // Поиск по role const fileSearchResultsItems = await fileSearchResults.findAllByRole("option"); await expect(fileSearchResultsItems.length).toBeGreaterThan(1); @@ -337,6 +337,20 @@ describe("tests", () => { }); ``` +Когда использовать WebdriverIO expect vs Jest expect + +**WebdriverIO expect** — используйте для проверки элементов и браузера: +- Автоматические ожидания (retry механизм) +- Проверка состояния элементов: `toBeDisplayed()`, `toExist()`, `toHaveText()` +- Проверка браузера: `toHaveUrl()`, `toHaveTitle()` + +**Jest expect** — используйте для проверки значений, чисел, строк: +- Синхронные проверки данных +- Проверка чисел: `toBeGreaterThan()`, `toBeLessThan()` +- Проверка строк и массивов: `toContain()`, `toBe()`, `toMatch()` + +**Рекомендация:** для проверок элементов и браузера всегда используйте WebdriverIO expect, так как он автоматически ожидает выполнения условия. + ### Хуки Хуки — это специальные функции, которые автоматически выполняются в определенные моменты жизненного цикла тестов. Они позволяют подготовить окружение перед тестами и очистить его после выполнения. По умолчанию доступны два вида хуков — `beforeEach` и `afterEach`, первый выполняется перед каждым тестом, а второй — после. From 1fa9300104093fd31647ea39e46b8f41342e19fe Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Thu, 26 Mar 2026 09:32:34 +0300 Subject: [PATCH 02/12] docs: add medium priority improvements to quickstart - Add links to reference sections for methods (browser.url, browser.openAndWait, $) - Add examples of different selector types (CSS, text, XPath) with recommendations - Expand --grep section with regex examples and .only() alternative - Add tips on selector priority and best practices --- .../current/quickstart/running-tests.mdx | 48 +++++++++++++- .../current/quickstart/writing-tests.mdx | 63 +++++++++++++++++-- 2 files changed, 105 insertions(+), 6 deletions(-) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index b8ff3d0..88347ab 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -41,13 +41,57 @@ describe("tests", () => { }); ``` -В таком случае выполните команду: +Опция `--grep` позволяет запускать тесты по совпадению с именем. Вот несколько способов использования: + +**Запуск одного теста по точному имени:** ```bash testplane --grep "Проверка наличия поля поиска" ``` -В кавычках вам необходимо передать содержимое скобок ключевого слова `it`. +**Запуск нескольких тестов по части имени:** + +```bash +# Запустит все тесты, в названии которых есть слово "Проверка" +testplane --grep "Проверка" +``` + +**Использование регулярных выражений:** + +```bash +# Запустит тесты, содержащие "поиск" ИЛИ "навигация" +testplane --grep "поиск|навигация" + +# Запустит тесты, начинающиеся с "Проверка" +testplane --grep "^Проверка" +``` + +**Инверсия (запуск всех тестов, КРОМЕ указанных):** + +```bash +# Запустит все тесты, кроме тех, что содержат "медленный" +testplane --grep "медленный" --invert +``` + +:::tip Альтернатива: использование .only() +Для быстрого запуска конкретного теста во время разработки можно использовать `.only()`: + +```javascript +describe("tests", () => { + // Запустится только этот тест + it.only("Проверка наличия поля поиска", async ({ browser }) => { + // ... + }); + + // Этот тест будет пропущен + it("Проверка отображения главной страницы", async ({ browser }) => { + // ... + }); +}); +``` + +⚠️ **Важно:** Не забудьте убрать `.only()` перед коммитом! Подробнее о [testplane helper](../reference/testplane-helper.mdx). +::: ### Запуск тестов в конкретных браузерах diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx index 4bdf177..8bc65f4 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx @@ -58,7 +58,7 @@ describe("test examples", () => { ### Навигация -Для перемещения по страницам используйте метод: +Для перемещения по страницам используйте метод [`browser.url()`](../commands/browser/url.mdx): ```javascript await browser.url("https://testplane.io/ru/"); @@ -72,17 +72,17 @@ await browser.$("h1").waitForExist({ timeout: 5000 }); const title = await browser.$("h1").getText(); ``` -Либо используйте команду: +Либо используйте команду [`browser.openAndWait()`](../commands/browser/openAndWait.mdx): ```javascript await browser.openAndWait("https://testplane.io/ru/"); ``` -Команда `await browser.openAndWait()` по умолчанию дожидается загрузки всех необходимых элементов на странице. +Команда [`browser.openAndWait()`](../commands/browser/openAndWait.mdx) по умолчанию дожидается загрузки всех необходимых элементов на странице. ### Селекторы -Testplane поддерживает различные стратегии поиска элементов: `CSS`-селекторы (самые распространенные), текстовые селекторы (по содержимому), `XPath` для сложных запросов. Метод `$()` возвращает первый найденный элемент, а `$$()` — массив всех подходящих элементов: +Testplane поддерживает различные стратегии поиска элементов: `CSS`-селекторы (самые распространенные), текстовые селекторы (по содержимому), `XPath` для сложных запросов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а `$$()` — массив всех подходящих элементов: ```javascript const assert = require("assert"); @@ -116,6 +116,61 @@ describe("tests", () => { }); ``` +#### Типы селекторов + +Testplane поддерживает несколько типов селекторов. Вот примеры, когда использовать каждый из них: + +```javascript +describe("Примеры типов селекторов", () => { + it("CSS-селекторы — основной способ поиска элементов", async ({ browser }) => { + await browser.url("https://testplane.io/ru/"); + + // ✅ Рекомендуется: data-атрибуты (стабильны, не зависят от вёрстки) + const button = await browser.$('[data-testid="submit-button"]'); + + // ✅ Хорошо: CSS-классы и теги + const logo = await browser.$("a.navbar__brand"); + const heading = await browser.$("h1"); + }); + + it("Текстовые селекторы — когда нет стабильных атрибутов", async ({ browser }) => { + await browser.url("https://testplane.io/ru/"); + + // Поиск ссылки по точному тексту + const link = await browser.$("a=Документация"); + + // Поиск кнопки по частичному совпадению текста + const button = await browser.$("button*=Начать"); + }); + + it("XPath — для сложных запросов в DOM", async ({ browser }) => { + await browser.url("https://testplane.io/ru/"); + + // Поиск элемента по тексту внутри + const element = await browser.$("//button[contains(text(), 'Поиск')]"); + + // Поиск родительского элемента + const parent = await browser.$("//a[@class='navbar__brand']/parent::div"); + + // ⚠️ Используйте XPath только когда CSS-селекторы не подходят + }); +}); +``` + +:::tip Рекомендации по выбору селекторов + +**Приоритет использования:** +1. **Data-атрибуты** (`[data-testid="..."]`) — самый надёжный способ +2. **CSS-селекторы** (классы, ID, теги) — для стабильных элементов +3. **Текстовые селекторы** — когда нет других вариантов +4. **XPath** — только для сложных случаев + +**Избегайте:** +- Сложных CSS-селекторов, зависящих от структуры DOM +- Селекторов по порядковому номеру (`:nth-child`) +- XPath без необходимости (медленнее CSS) +::: + ### Взаимодействия с элементами После знакомства с селекторами и поиска элемента можно выполнить различные действия: клик, ввод текста, двойной клик. From 3a051d19ab2fb3172cfab1a0d14edf4b185eb802 Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Thu, 26 Mar 2026 10:42:12 +0300 Subject: [PATCH 03/12] docs: fix --grep examples --- .../current/quickstart/running-tests.mdx | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index 88347ab..bcabf50 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -58,21 +58,26 @@ testplane --grep "Проверка" **Использование регулярных выражений:** +Testplane поддерживает стандартные JavaScript регулярные выражения: + ```bash # Запустит тесты, содержащие "поиск" ИЛИ "навигация" testplane --grep "поиск|навигация" # Запустит тесты, начинающиеся с "Проверка" testplane --grep "^Проверка" -``` -**Инверсия (запуск всех тестов, КРОМЕ указанных):** +# Запустит тесты, заканчивающиеся на "тест" +testplane --grep "тест$" -```bash -# Запустит все тесты, кроме тех, что содержат "медленный" -testplane --grep "медленный" --invert +# Исключить тесты (отрицание через regex) +testplane --grep "^(?!.*медленный).*$" ``` +:::info Как работает --grep +Опция `--grep` использует стандартный JavaScript `RegExp.test()` для фильтрации тестов по полному имени (включая все уровни `describe` и `it`). Переданная строка автоматически интерпретируется либо как регулярное выражение, либо как обычный текст для поиска. +::: + :::tip Альтернатива: использование .only() Для быстрого запуска конкретного теста во время разработки можно использовать `.only()`: From e120d7f5101921eb06c49a47644840c7760cc48d Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Fri, 27 Mar 2026 20:47:57 +0300 Subject: [PATCH 04/12] docs: add improvements --- docs/quickstart/usage-in-ci.mdx | 83 ++++++++- .../current/quickstart/index.mdx | 94 +++++++--- .../current/quickstart/running-tests.mdx | 94 +++++++--- .../current/quickstart/usage-in-ci.mdx | 83 ++++++++- .../current/quickstart/writing-tests.mdx | 161 ++++++++---------- 5 files changed, 374 insertions(+), 141 deletions(-) diff --git a/docs/quickstart/usage-in-ci.mdx b/docs/quickstart/usage-in-ci.mdx index 0c89c4b..01ee0c8 100644 --- a/docs/quickstart/usage-in-ci.mdx +++ b/docs/quickstart/usage-in-ci.mdx @@ -1,6 +1,87 @@ --- sidebar_position: 4 -draft: true --- # Usage in CI + +Testplane can be easily integrated into any CI system (GitHub Actions, GitLab CI, Jenkins, etc.). Below is an example setup for GitHub Actions. + +## GitHub Actions + +Create a `.github/workflows/testplane.yml` file in your repository root: + +```yaml +name: Testplane Tests + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Install browser dependencies + run: npx testplane install-deps + + - name: Run tests + run: npx testplane + + - name: Upload HTML report + if: always() + uses: actions/upload-artifact@v4 + with: + name: testplane-report + path: testplane-report/ +``` + +### Configuration notes + +- **`testplane install-deps`** — downloads required browsers (Chrome, Firefox) before running tests. +- **`npx testplane`** — runs all tests in headless mode (by default). +- **Report upload** — after test execution, the HTML report is saved as an artifact that can be downloaded from the GitHub Actions interface. + +## GitLab CI + +Example `.gitlab-ci.yml`: + +```yaml +image: node:20-alpine + +stages: + - test + +testplane: + stage: test + script: + - npm ci + - npx testplane install-deps + - npx testplane + artifacts: + when: always + paths: + - testplane-report/ +``` + +## General recommendations + +- **Caching dependencies** — configure caching of `node_modules` and browsers to speed up execution. +- **Parallel execution** — use CI capabilities to run tests in different browsers in parallel (e.g., via `testplane --browser chrome` and `testplane --browser firefox` in separate jobs). +- **Environment variables** — set `gridUrl` for remote Selenium Grid if tests run on cloud infrastructure. + +For more details on configuring Testplane for CI, refer to the [configuration documentation](../reference/config/main.mdx). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx index 2bd951e..11f6d1b 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx @@ -38,27 +38,15 @@ testplane.config.ts В файле `testplane.config.ts` содержится базовый набор настроек для запуска тестов: -```typescript +```typescript title="testplane.config.ts" export default { - // gridUrl: "local" — запуск браузеров локально на вашей машине - // Для удалённого запуска укажите URL Selenium Grid или облачного сервиса (например, BrowserStack) gridUrl: "local", - baseUrl: "http://localhost", - - // pageLoadTimeout — максимальное время ожидания загрузки страницы (0 = без ограничений) pageLoadTimeout: 0, - httpTimeout: 60000, - - // testTimeout — максимальное время выполнения одного теста (в миллисекундах) testTimeout: 90000, - resetCursor: false, - // sets — группы тестов, привязанные к определённым браузерам - // Позволяет запускать разные наборы тестов в разных браузерах - // Например: десктопные тесты в Chrome/Firefox, мобильные в Safari sets: { desktop: { files: ["testplane-tests/**/*.testplane.(t|j)s"], @@ -66,7 +54,6 @@ export default { }, }, - // browsers — конфигурация для каждого браузера browsers: { chrome: { headless: true, @@ -82,9 +69,6 @@ export default { }, }, - // html-reporter — инструмент для просмотра результатов тестов в браузере - // Предоставляет интерактивные отчёты со скриншотами, логами и возможностями отладки - // Подробнее: https://testplane.io/ru/docs/html-reporter/overview plugins: { "html-reporter/testplane": { enabled: true, @@ -96,11 +80,19 @@ export default { }; ``` -**Ключевые концепции:** +### Основные параметры конфигурации -- **gridUrl: "local"** — браузеры запускаются на вашей локальной машине. Для запуска тестов на удалённой инфраструктуре (Selenium Grid, BrowserStack, Sauce Labs) укажите URL грида. -- **sets** — позволяют группировать тесты и запускать их в определённых браузерах. Например, можно создать отдельные наборы для десктопных и мобильных тестов. Подробнее в [справочнике по sets](../reference/config/sets.mdx). -- **testTimeout** — если тест выполняется дольше этого значения, он будет прерван. Настраивайте в зависимости от сложности вашего приложения. +`gridUrl` определяет, где запускать браузеры. Значение `"local"` означает запуск на вашей локальной машине. Для удалённого запуска укажите URL Selenium Grid или облачного сервиса (например, BrowserStack или Sauce Labs). + +`sets` — группы тестов, привязанные к определённым браузерам. Позволяет запускать разные наборы тестов в разных браузерах. Например, можно создать отдельные наборы для десктопных тестов в Chrome/Firefox и мобильных в Safari. Подробнее в [справочнике по sets](../reference/config/sets.mdx). + +`testTimeout` — максимальное время выполнения одного теста в миллисекундах. Если тест выполняется дольше этого значения, он будет прерван. Настраивайте в зависимости от сложности вашего приложения. + +`pageLoadTimeout` — максимальное время ожидания загрузки страницы. Значение `0` означает отсутствие ограничений. + +`browsers` — конфигурация для каждого браузера. Параметр `headless: true` запускает браузер в фоновом режиме без графического интерфейса. Подробнее в разделе [Браузеры](../basic-guides/managing-browsers.mdx). + +`plugins` — подключаемые модули. `html-reporter` — инструмент для просмотра результатов тестов в браузере. Предоставляет интерактивные отчёты со скриншотами, логами и возможностями отладки. Подробнее в разделе [HTML Reporter](../html-reporter/overview.mdx). Полный список параметров конфигурации см. в [справочнике по конфигурации](../reference/config/main.mdx). @@ -111,3 +103,63 @@ npx testplane install-deps ``` Без предварительного запуска команды недостающие браузеры будут автоматически загружены с первым запуском Testplane. + +## Первый запуск {#first-run} + +После установки и настройки запустите тестовый пример, который был создан автоматически: + +```bash +npx testplane +``` + +### Что происходит при первом запуске + +Testplane автоматически выполнит следующие действия: + +1. Загрузит браузеры: если вы не запускали `install-deps`, Testplane скачает Chrome и Firefox +2. Запустит тест: выполнит пример из `testplane-tests/example.testplane.ts` +3. Создаст отчёт: сгенерирует HTML-репорт в папке `testplane-report/` + +### Просмотр результатов + +После завершения тестов откройте интерактивный отчёт: + +```bash +npx testplane gui +``` + +Команда запустит локальный сервер и откроет отчёт в браузере. В интерфейсе вы увидите: + +- Список пройденных тестов +- Статистику выполнения +- Скриншоты (если тест использует `assertView`) +- Логи выполнения + +### Ожидаемый результат + +Если всё настроено корректно, вы увидите: + +``` +✔ test examples › docs search test [chrome] - 3.2s +✔ test examples › docs search test [firefox] - 3.5s + +Total: 2 Passed: 2 Failed: 0 Skipped: 0 Retries: 0 +``` + +### Что делать, если тест упал + +Если тест не прошёл, проверьте: + +1. Интернет-соединение: тест обращается к https://testplane.io/ +2. Браузеры установлены: запустите `npx testplane install-deps` +3. Порты свободны: убедитесь, что порты не заняты другими процессами + +Подробнее об отладке читайте в разделе [Запуск и отладка](./running-tests.mdx). + +## Что дальше? + +Теперь, когда Testplane настроен и работает, вы можете: + +- [Запустить тесты разными способами](./running-tests.mdx) — фильтрация, отладка, GUI-режим +- [Настроить CI/CD](./usage-in-ci.mdx) — автоматизируйте запуск тестов в GitHub Actions или GitLab CI +- Изучить [справочник по API](../reference/testplane-api.mdx) — полный список методов и возможностей diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index bcabf50..a88980d 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -162,7 +162,7 @@ testplane ../testplane-tests/example.testplane.ts ![](/img/docs/html-reporter/html-reporter-demo.png) -О процессах установки и настройки Testplane UI вы можете прочитать в разделе [UI.](..//html-reporter//overview.mdx) +О процессах установки и настройки Testplane UI вы можете прочитать в разделе [HTML Reporter](../html-reporter/overview.mdx). ## Отладка @@ -188,17 +188,20 @@ it("отладка с паузой", async ({ browser }) => { // После вызова debug() тест приостанавливается // В консоли можно вводить команды WebdriverIO в реальном времени: - // Примеры команд, которые можно вводить в REPL: - // > await browser.$('.button').click() - кликнуть по кнопке - // > await browser.getTitle() - получить заголовок страницы - // > await browser.$$('.items') - найти все элементы - // > .exit - выйти из режима отладки + // В консоли можно вводить команды WebdriverIO (см. примеры ниже) // Этот код выполнится только после выхода из debug() await browser.$(".button").click(); }); ``` +**Примеры команд REPL:** + +- `await browser.$('.button').click()` — кликнуть по кнопке +- `await browser.getTitle()` — получить заголовок страницы +- `await browser.$$('.items')` — найти все элементы +- `.exit` — выйти из режима отладки + ### Отладка через Testplane UI Наиболее удобным способом для работы с отладкой тестов является UI-режим, в нем вы можете в реальном времени наблюдать выполнение тестов. @@ -216,28 +219,32 @@ it("отладка с паузой", async ({ browser }) => { ### Где найти информацию об ошибке **В консоли:** -- Сообщение об ошибке выводится в терминал при запуске `npx testplane` -- Показывает стек вызовов и строку, где произошла ошибка + +- Сообщение об ошибке выводится в терминал при запуске `npx testplane` +- Показывает стек вызовов и строку, где произошла ошибка **В HTML-репорте:** -- Запустите `npx testplane gui` для интерактивного просмотра -- Упавшие тесты отмечены красным цветом -- Кликните на тест, чтобы увидеть детали: скриншоты, логи, сообщение об ошибке + +- Запустите `npx testplane gui` для интерактивного просмотра +- Упавшие тесты отмечены красным цветом +- Кликните на тест, чтобы увидеть детали: скриншоты, логи, сообщение об ошибке ### Как найти упавший тест 1. **По имени теста** — используйте `--grep`: - ```bash - testplane --grep "название теста" - ``` + + ```bash + testplane --grep "название теста" + ``` 2. **В UI-режиме** — используйте фильтры и поиск: - - Фильтр "failed" покажет только упавшие тесты - - Поиск по имени теста или файлу + - Фильтр "failed" покажет только упавшие тесты + - Поиск по имени теста или файлу ### Что проверять в первую очередь #### 1. Селекторы + Самая частая причина падения тестов — изменился селектор элемента. ```javascript @@ -249,11 +256,13 @@ await browser.$("[data-testid='submit-button']").click(); ``` **Как проверить:** -- Откройте страницу в браузере -- Используйте DevTools для проверки, существует ли элемент с таким селектором -- Проверьте, не изменилась ли вёрстка + +- Откройте страницу в браузере +- Используйте DevTools для проверки, существует ли элемент с таким селектором +- Проверьте, не изменилась ли вёрстка #### 2. Ожидания (таймауты) + Элемент может появляться с задержкой, и тест не успевает дождаться. ```javascript @@ -268,24 +277,55 @@ await button.click(); ``` **Как проверить:** -- Увеличьте таймаут в конфиге (`testTimeout`, `pageLoadTimeout`) -- Добавьте явные ожидания `waitForDisplayed()`, `waitForClickable()` + +- Увеличьте таймаут в конфиге (`testTimeout`, `pageLoadTimeout`) +- Добавьте явные ожидания `waitForDisplayed()`, `waitForClickable()` #### 3. Данные и окружение + Тест может падать из-за отсутствия тестовых данных или проблем с окружением. **Как проверить:** -- Убедитесь, что тестовое окружение доступно -- Проверьте, что тестовые данные существуют (пользователи, товары и т.д.) -- Проверьте переменные окружения и конфигурацию + +- Убедитесь, что тестовое окружение доступно +- Проверьте, что тестовые данные существуют (пользователи, товары и т.д.) +- Проверьте переменные окружения и конфигурацию #### 4. Состояние браузера + Иногда тесты падают из-за состояния, оставшегося от предыдущих тестов. **Как проверить:** -- Очищайте cookies и localStorage в хуках `beforeEach` -- Используйте изолированные тестовые данные -- Проверьте, не влияют ли тесты друг на друга + +- Очищайте cookies и localStorage в хуках `beforeEach` +- Используйте изолированные тестовые данные +- Проверьте, не влияют ли тесты друг на друга + +#### 5. Скриншоты + +Testplane автоматически делает скриншоты при падении тестов. Они сохраняются в HTML-репорте и помогают визуально оценить состояние страницы в момент ошибки. + +**Как использовать скриншоты для отладки:** + +- **Автоматические скриншоты:** При падении теста Testplane сохраняет скриншот страницы. Посмотреть его можно в HTML-репорте (кликните на упавший тест). +- **Ручные скриншоты:** Вы можете сделать скриншот в любой момент теста с помощью `browser.saveScreenshot()`: + +```javascript +// Сохранить скриншот в файл +await browser.saveScreenshot("./screenshots/my-page.png"); +``` + +- **Скриншоты элементов:** Чтобы сделать скриншот конкретного элемента, используйте `element.saveScreenshot()`: + +```javascript +const logo = await browser.$(".navbar__brand"); +await logo.saveScreenshot("./screenshots/logo.png"); +``` + +**Рекомендации:** + +- Сохраняйте скриншоты в отдельную папку (например, `./screenshots/`). +- Используйте ручные скриншоты для проверки промежуточных состояний интерфейса. ### Полезные команды для диагностики diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx index 8e8caa3..36c6464 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx @@ -1,6 +1,87 @@ --- sidebar_position: 4 -draft: true --- # Использование в CI + +Testplane можно легко интегрировать в любую CI-систему (GitHub Actions, GitLab CI, Jenkins и др.). Ниже приведён пример настройки для GitHub Actions. + +## GitHub Actions + +Создайте файл `.github/workflows/testplane.yml` в корне вашего репозитория: + +```yaml +name: Testplane Tests + +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: "npm" + + - name: Install dependencies + run: npm ci + + - name: Install browser dependencies + run: npx testplane install-deps + + - name: Run tests + run: npx testplane + + - name: Upload HTML report + if: always() + uses: actions/upload-artifact@v4 + with: + name: testplane-report + path: testplane-report/ +``` + +### Пояснения к конфигурации + +- **`testplane install-deps`** — загружает необходимые браузеры (Chrome, Firefox) перед запуском тестов. +- **`npx testplane`** — запускает все тесты в headless-режиме (по умолчанию). +- **Загрузка отчёта** — после выполнения тестов HTML-репорт сохраняется как артефакт, который можно скачать из интерфейса GitHub Actions. + +## GitLab CI + +Пример `.gitlab-ci.yml`: + +```yaml +image: node:20-alpine + +stages: + - test + +testplane: + stage: test + script: + - npm ci + - npx testplane install-deps + - npx testplane + artifacts: + when: always + paths: + - testplane-report/ +``` + +## Общие рекомендации + +- **Кэширование зависимостей** — настройте кэширование `node_modules` и браузеров, чтобы ускорить выполнение. +- **Параллельный запуск** — используйте возможности CI для параллельного запуска тестов в разных браузерах (например, через `testplane --browser chrome` и `testplane --browser firefox` в отдельных job'ах). +- **Переменные окружения** — задайте `gridUrl` для удалённого Selenium Grid, если тесты запускаются на облачной инфраструктуре. + +Подробнее о настройке Testplane для CI читайте в [документации по конфигурации](../reference/config/main.mdx). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx index 8bc65f4..3fb14c4 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx @@ -7,27 +7,9 @@ draft: true ## Структура теста -Блок `describe` предназначен для группировки связанных тестов. - -```javascript -describe("Название группы тестов", () => { - it("описание того, что должно произойти", async ({ browser }) => { - // Тело теста - }); -}); -``` - -В блоке `it` описываются тестовые сценарии. - -```javascript -it("описание того, что должно произойти", async ({ browser }) => { - // Тело теста -}); -``` - -После установки testplane вы можете ознакомиться с примером теста, для этого перейдите в папку `testplane-tests` и откройте файл `example.testplane.ts`. +После установки testplane можно ознакомиться с примером теста, для этого перейдите в папку `testplane-tests` и откройте файл `example.testplane.ts`. -```javascript +```typescript title="example.testplane.ts" describe("test examples", () => { it("docs search test", async ({ browser }) => { await browser.openAndWait("https://testplane.io/"); @@ -54,19 +36,31 @@ describe("test examples", () => { }); ``` +Блок `describe` предназначен для группировки связанных тестов. + +В блоке `it` описываются тестовые сценарии. + +```typescript +describe("Название группы тестов", () => { + it("Описание того, что должно произойти", async ({ browser }) => { + // Тело теста + }); +}); +``` + ## Базовый синтаксис ### Навигация Для перемещения по страницам используйте метод [`browser.url()`](../commands/browser/url.mdx): -```javascript +```typescript await browser.url("https://testplane.io/ru/"); ``` Если на странице имеются элементы, которые отображаются с задержкой, для корректного выполнения тестов укажите явное ожидание: -```javascript +```typescript await browser.url("https://testplane.io/ru/"); await browser.$("h1").waitForExist({ timeout: 5000 }); const title = await browser.$("h1").getText(); @@ -74,7 +68,7 @@ const title = await browser.$("h1").getText(); Либо используйте команду [`browser.openAndWait()`](../commands/browser/openAndWait.mdx): -```javascript +```typescript await browser.openAndWait("https://testplane.io/ru/"); ``` @@ -82,9 +76,9 @@ await browser.openAndWait("https://testplane.io/ru/"); ### Селекторы -Testplane поддерживает различные стратегии поиска элементов: `CSS`-селекторы (самые распространенные), текстовые селекторы (по содержимому), `XPath` для сложных запросов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а `$$()` — массив всех подходящих элементов: +Testplane поддерживает различные стратегии поиска элементов: `CSS`-селекторы (самые распространенные), текстовые селекторы (по содержимому), `XPath` для сложных запросов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а [`$$()`](../commands/browser/$$.mdx) — массив всех подходящих элементов: -```javascript +```typescript const assert = require("assert"); describe("tests", () => { @@ -118,58 +112,57 @@ describe("tests", () => { #### Типы селекторов -Testplane поддерживает несколько типов селекторов. Вот примеры, когда использовать каждый из них: +Testplane поддерживает несколько типов селекторов: -```javascript +```typescript describe("Примеры типов селекторов", () => { it("CSS-селекторы — основной способ поиска элементов", async ({ browser }) => { await browser.url("https://testplane.io/ru/"); - - // ✅ Рекомендуется: data-атрибуты (стабильны, не зависят от вёрстки) + + // Рекомендуется: data-атрибуты (стабильны, не зависят от вёрстки) const button = await browser.$('[data-testid="submit-button"]'); - - // ✅ Хорошо: CSS-классы и теги + + // Хорошо: CSS-классы и теги const logo = await browser.$("a.navbar__brand"); const heading = await browser.$("h1"); }); it("Текстовые селекторы — когда нет стабильных атрибутов", async ({ browser }) => { await browser.url("https://testplane.io/ru/"); - + // Поиск ссылки по точному тексту const link = await browser.$("a=Документация"); - + // Поиск кнопки по частичному совпадению текста const button = await browser.$("button*=Начать"); }); it("XPath — для сложных запросов в DOM", async ({ browser }) => { await browser.url("https://testplane.io/ru/"); - + // Поиск элемента по тексту внутри const element = await browser.$("//button[contains(text(), 'Поиск')]"); - + // Поиск родительского элемента const parent = await browser.$("//a[@class='navbar__brand']/parent::div"); - - // ⚠️ Используйте XPath только когда CSS-селекторы не подходят + + // Используйте XPath только когда CSS-селекторы не подходят }); }); ``` -:::tip Рекомендации по выбору селекторов - **Приоритет использования:** -1. **Data-атрибуты** (`[data-testid="..."]`) — самый надёжный способ -2. **CSS-селекторы** (классы, ID, теги) — для стабильных элементов -3. **Текстовые селекторы** — когда нет других вариантов -4. **XPath** — только для сложных случаев + +1. Data-атрибуты (`[data-testid="..."]`) — самый надёжный способ +2. CSS-селекторы (классы, ID, теги) — для стабильных элементов +3. Текстовые селекторы — когда нет других вариантов +4. XPath — только для сложных случаев **Избегайте:** -- Сложных CSS-селекторов, зависящих от структуры DOM -- Селекторов по порядковому номеру (`:nth-child`) -- XPath без необходимости (медленнее CSS) -::: + +- Сложных CSS-селекторов, зависящих от структуры DOM +- Селекторов по порядковому номеру (`:nth-child`) +- XPath без необходимости (медленнее CSS) ### Взаимодействия с элементами @@ -177,7 +170,7 @@ describe("Примеры типов селекторов", () => { Для клика по элементу используйте метод `element.click()`. -```javascript +```typescript const assert = require("assert"); describe("Тест клика", () => { @@ -199,7 +192,7 @@ describe("Тест клика", () => { Чтобы заполнить поле для ввода текста используйте метод `element.setValue("text")`. -```javascript +```typescript const assert = require("assert"); describe("Тест ввода текста", () => { @@ -225,7 +218,7 @@ describe("Тест ввода текста", () => { Для двойного клика по элементу используйте метод `element.doubleClick()`. -```javascript +```typescript const assert = require("assert"); describe("Тест двойного клика", () => { @@ -249,7 +242,7 @@ describe("Тест двойного клика", () => { Testplane предоставляет специальные методы для работы с различными элементами форм. Например, чекбоксы и радиокнопки управляются через клик. -```javascript +```typescript const assert = require("assert"); describe("Взаимодействие с формами", () => { @@ -295,7 +288,7 @@ describe("Взаимодействие с формами", () => { Для выпадающих списков `()` есть удобные методы выбора опций по видимому тексту или значению атрибута. +#### Jest expect ```typescript -const assert = require("assert"); - -describe("Работа с выпадающим списком", () => { - it("Работа с выпадающим списком (select) — выбор по тексту", async ({ browser }) => { - await browser.url("https://the-internet.herokuapp.com/dropdown"); +it("проверки значений", async ({ browser }) => { + await browser.url("https://example.com/"); - const dropdown = await browser.$("#dropdown"); - await dropdown.waitForDisplayed({ timeout: 5000 }); + const title = await browser.getTitle(); + expect(title).toContain("Example"); - // Выбор опции по видимому тексту - await dropdown.selectByVisibleText("Option 1"); - - // Проверяем выбранное значение - let selectedValue = await dropdown.getValue(); - assert.strictEqual(selectedValue, "1"); - - // Получаем текст выбранной опции - let selectedText = await dropdown.$("option:checked").getText(); - assert.strictEqual(selectedText, "Option 1"); - }); + const links = await browser.$$("a"); + expect(links.length).toBeGreaterThan(0); }); ``` -### Assertions - -Testplane задействует `expect API` из `WebdriverIO` для проверки состояния элементов и страниц — это позволяет формулировать утверждения (`assertions`) о том, какими должны быть свойства элементов или страницы в целом. - -```typescript -const assert = require("assert"); - -describe("tests", () => { - it("WebdriverIO assert — проверка URL", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); +- Используйте WebdriverIO `expect` для проверок элементов (`$`, `$$`) и браузера (`browser`). Он автоматически повторяет проверку до успеха или таймаута. +- Применяйте Jest `expect` для проверок простых значений (строк, чисел, массивов), которые не требуют ожидания. - // WebdriverIO expect для browser - await expect(browser).toHaveUrl("https://testplane.io/ru/"); - }); +### Хуки - it("WebdriverIO assert — проверка существования элемента", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); +Хуки позволяют подготовить окружение перед тестами и очистить его после выполнения. - const logo = await browser.$("a.navbar__brand"); - - // WebdriverIO expect для элемента - await expect(logo).toExist(); +```typescript +describe("Работа с хуками", () => { + beforeEach(async ({ browser }) => { + // Выполняется перед каждым тестом + await browser.url("https://example.com/"); }); - it("WebdriverIO assert — проверка видимости элемента", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); - - const searchButton = await browser.$("button.DocSearch"); - - // WebdriverIO expect - await expect(searchButton).toBeDisplayed(); + afterEach(async ({ browser }) => { + // Выполняется после каждого теста + await browser.deleteAllCookies(); }); - // Примеры с Jest ассертами - it("Jest assert — проверка заголовка страницы", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); - + it("Первый тест", async ({ browser }) => { + // Страница уже открыта благодаря beforeEach const title = await browser.getTitle(); + expect(title).toContain("Example"); + }); - // Jest expect - expect(title).toContain("Testplane"); + it("Второй тест", async ({ browser }) => { + // Страница снова открыта, cookies очищены + const heading = await browser.$("h1"); + await expect(heading).toExist(); }); +}); +``` - it("Jest assert — проверка количества элементов", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); +### Ожидания - const menuItems = await browser.$$("nav.navbar a.navbar__item"); +Явные ожидания необходимы для работы с динамическим контентом: - // Jest expect - expect(menuItems.length).toBeGreaterThan(0); - }); - - it("Jest assert — проверка атрибута элемента", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); +```typescript +it("Ожидание элементов", async ({ browser }) => { + await browser.url("https://example.com/"); - const docsLink = await browser.$("a[href='/ru/docs/v8/']"); - const href = await docsLink.getAttribute("href"); + const button = await browser.$("button"); - // Jest expect - expect(href).toBe("/ru/docs/v8/"); - }); + // Ожидание появления + await button.waitForDisplayed({ timeout: 5000 }); - it("Jest assert — проверка URL с регулярным выражением", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); + // Ожидание кликабельности + await button.waitForClickable({ timeout: 3000 }); - const currentUrl = await browser.getUrl(); + // Ожидание существования + await button.waitForExist({ timeout: 5000 }); - // Jest expect с regex - expect(currentUrl).toMatch(/testplane\.io/); - }); + await button.click(); }); ``` -Когда использовать WebdriverIO expect vs Jest expect +#### Кастомные ожидания -**WebdriverIO expect** — используйте для проверки элементов и браузера: +```typescript +it("Кастомное ожидание", async ({ browser }) => { + await browser.url("https://example.com/"); + + // Ожидание изменения URL + await browser.waitUntil( + async () => { + const url = await browser.getUrl(); + return url.includes("success"); + }, + { + timeout: 5000, + timeoutMsg: "URL не изменился на success", + }, + ); +}); +``` -- Автоматические ожидания (retry механизм) -- Проверка состояния элементов: `toBeDisplayed()`, `toExist()`, `toHaveText()` -- Проверка браузера: `toHaveUrl()`, `toHaveTitle()` +## Визуальное тестирование -**Jest expect** — используйте для проверки значений, чисел, строк: +Testplane позволяет делать скриншоты элементов и сравнивать их с эталонными изображениями с помощью команды `assertView`. -- Синхронные проверки данных -- Проверка чисел: `toBeGreaterThan()`, `toBeLessThan()` -- Проверка строк и массивов: `toContain()`, `toBe()`, `toMatch()` +При первом запуске теста создаются эталонные скриншоты. При последующих запусках Testplane сравнивает новые скриншоты с эталонами и сообщает о различиях. Если различий нет, тест проходит. Если есть различия, тест падает, а diff-изображение сохраняется для анализа. -**Рекомендация:** для проверок элементов и браузера всегда используйте WebdriverIO expect, так как он автоматически ожидает выполнения условия. +```typescript +it("Визуальная проверка кнопки", async ({ browser }) => { + await browser.url("https://example.com/"); -### Хуки + // Скриншот элемента + await browser.assertView("button-default", "button"); + + // Клик и проверка нового состояния + await browser.$("button").click(); + await browser.assertView("button-clicked", "button"); +}); +``` -Хуки — это специальные функции, которые автоматически выполняются в определенные моменты жизненного цикла тестов. Они позволяют подготовить окружение перед тестами и очистить его после выполнения. По умолчанию доступны два вида хуков — `beforeEach` и `afterEach`, первый выполняется перед каждым тестом, а второй — после. +### Параметры assertView ```typescript -describe("Работа с хуками", () => { - beforeEach(async ({ browser }) => { - // Подготовка: открываем страницу перед каждым тестом - await browser.url("https://testplane.io/ru/"); - }); +it("assertView с параметрами", async ({ browser }) => { + await browser.url("https://example.com/"); - afterEach(async ({ browser }) => { - // Очистка: удаляем cookies после каждого теста - await browser.deleteAllCookies(); - }); + await browser.assertView("form", ".form", { + // Игнорировать элементы при сравнении + ignoreElements: [".dynamic-date", ".random-id"], - it("Проверяет заголовок страницы", async ({ browser }) => { - const title = await browser.getTitle(); - expect(title).toContain("Testplane"); - }); + // Допустимое отклонение в пикселях + tolerance: 5, + + // Задержка перед скриншотом (для анимаций) + screenshotDelay: 100, - it("Проверяет наличие логотипа", async ({ browser }) => { - const logo = await browser.$(".navbar__brand"); - await expect(logo).toExist(); + // Отключить анимации + disableAnimation: true, }); }); ``` -### Ожидания - -Явные ожидания необходимы для работы с динамическим контентом, который загружается или изменяется асинхронно. Testplane автоматически ждет появления элементов, но для сложных сценариев можно использовать специальные методы ожидания. +### Скриншот всего viewport ```typescript -const assert = require("assert"); +it("Скриншот viewport", async ({ browser }) => { + await browser.url("https://example.com/"); -describe("Примеры ожиданий в Testplane", () => { - it("Ожидание появления и кликабельности элемента", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); - - // Ожидаем, что кнопка поиска появится на странице - const searchButton = await browser.$("button.DocSearch"); - await searchButton.waitForDisplayed({ - timeout: 5000, - timeoutMsg: "Кнопка поиска не появилась в течение 5 секунд", - }); + // Без селектора — скриншот текущего viewport + await browser.assertView("full-page"); +}); +``` - // Ожидаем, что элемент станет кликабельным - await searchButton.waitForClickable({ - timeout: 3000, - timeoutMsg: "Кнопка поиска не стала кликабельной", - }); +## Работа с JavaScript - await searchButton.click(); +Метод `execute()` выполняет JavaScript-код в контексте страницы: - // Ожидаем появления модального окна поиска - const searchModal = await browser.$(".DocSearch-Modal"); - await searchModal.waitForDisplayed({ timeout: 3000 }); +```typescript +it("Выполнение JavaScript", async ({ browser }) => { + await browser.url("https://example.com/"); - const isDisplayed = await searchModal.isDisplayed(); - assert.strictEqual(isDisplayed, true); + // Работа с localStorage + await browser.execute(() => { + localStorage.setItem("token", "abc123"); }); - it("Ожидание изменения текста элемента", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); - - const heading = await browser.$("h1"); - - // Ожидаем, что элемент будет существовать - await heading.waitForExist({ - timeout: 5000, - timeoutMsg: "Заголовок не найден на странице", - }); - - // Ожидаем, что у элемента будет определенный текст - await heading.waitUntil( - async function () { - const text = await this.getText(); - return text.length > 0; - }, - { - timeout: 5000, - timeoutMsg: "Текст заголовка не появился", - }, - ); - - const text = await heading.getText(); - assert.ok(text.length > 0); + const token = await browser.execute(() => { + return localStorage.getItem("token"); }); + expect(token).toBe("abc123"); - it("Ожидание с использованием browser.waitUntil для проверки URL", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); - - const docsLink = await browser.$("a[href='/ru/docs/v8/']"); - await docsLink.waitForExist({ timeout: 5000 }); - - // Используем JavaScript click для надежности - await browser.execute(el => el.click(), docsLink); - - // Ожидаем изменения URL с помощью browser.waitUntil - await browser.waitUntil( - async () => { - const currentUrl = await browser.getUrl(); - return currentUrl.includes("docs"); - }, - { - timeout: 5000, - timeoutMsg: "URL не изменился на страницу документации", - }, - ); - - const finalUrl = await browser.getUrl(); - assert.ok(finalUrl.includes("docs")); - }); + // Передача параметров + const sum = await browser.execute((a, b) => a + b, 5, 10); + expect(sum).toBe(15); }); ``` -### Работа с JavaScript кодом - -Иногда нужно выполнить произвольный JavaScript-код в контексте страницы — например, для работы с `localStorage`, вызова функций или манипуляции `DOM` напрямую. Метод `execute()` выполняет код в браузере и может возвращать результат. - :::warning Ограничения browser.execute -Код, переданный в `browser.execute()`, выполняется **только в контексте браузера** (на странице). Вы не можете использовать Node.js модули (например, `fs`, `path`) или обращаться к файловой системе. Все переменные и функции должны быть доступны в глобальной области видимости страницы. +Код в `browser.execute()` выполняется в браузере, а не в Node.js. Вы не можете использовать Node.js модули (`fs`, `path`) или обращаться к файловой системе. ::: -```typescript -const assert = require("assert"); +## Шаги теста (runStep) -describe("Примеры работы с JavaScript кодом", () => { - it("Выполнение JavaScript кода в контексте страницы", async ({ browser }) => { - await browser.url("https://testplane.io/ru/"); +Команда `runStep` позволяет структурировать тест и улучшить читаемость отчётов: - // Пример 1: Получение данных из localStorage - await browser.execute(() => { - localStorage.setItem("testKey", "testValue"); - localStorage.setItem("userName", "John Doe"); - }); +```typescript +it("Оформление заказа", async ({ browser }) => { + await browser.runStep("Открыть каталог", async () => { + await browser.url("/catalog"); + await browser.$(".products").waitForDisplayed(); + }); - const storageValue = await browser.execute(() => { - return localStorage.getItem("testKey"); - }); - assert.strictEqual(storageValue, "testValue"); - - // Пример 2: Манипуляция DOM — изменение текста элемента - const newText = await browser.execute(() => { - const heading = document.querySelector("h1"); - if (heading) { - const originalText = heading.textContent; - heading.textContent = "Измененный заголовок"; - return originalText; - } - return ""; - }); + await browser.runStep("Добавить товар в корзину", async () => { + await browser.$(".product-card button").click(); + await expect(browser.$(".cart-count")).toHaveText("1"); + }); - const modifiedHeading = await browser.$("h1"); - const currentText = await modifiedHeading.getText(); - assert.strictEqual(currentText, "Измененный заголовок"); - - // Пример 3: Вызов функции с параметрами - const sum = await browser.execute( - (a, b) => { - return a + b; - }, - 5, - 10, - ); - assert.strictEqual(sum, 15); + await browser.runStep("Оформить заказ", async () => { + await browser.url("/checkout"); + await browser.$('button[type="submit"]').click(); }); }); ``` + +Шаги отображаются в HTML-отчёте, что упрощает отладку упавших тестов. + +## Что дальше? + +Теперь, когда вы знаете основы написания тестов, изучите: + +- [Запуск и отладка](./running-tests.mdx): как запускать тесты и отлаживать проблемы +- [Использование в CI](./usage-in-ci.mdx): автоматический запуск в GitHub Actions +- [Конфигурация](../reference/config/main.mdx): полный список настроек +- [Команды браузера](../commands/browser/url.mdx): все доступные команды +- [HTML Reporter](../html-reporter/overview.mdx): работа с отчётами From 006b99f242cfd4f93ba27edc0170a13a9f7c4c8a Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Mon, 30 Mar 2026 12:46:10 +0300 Subject: [PATCH 09/12] docs(quickstart): fix running-tests --- .../current/quickstart/running-tests.mdx | 9 --------- 1 file changed, 9 deletions(-) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index 416ef2a..ada7e0f 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -156,15 +156,6 @@ it("Отладка", async ({ browser }) => { }); ``` -Или используйте CLI-опции: - -```bash -npx testplane --repl-before-test --grep "Название теста" # REPL перед тестом -npx testplane --repl-on-fail --grep "Название теста" # REPL при падении -``` - -При использовании опции `--repl-on-fail` REPL откроется только если тест упал. - ### Сохранение браузера после теста По умолчанию браузер закрывается сразу после теста. Чтобы изучить финальное состояние страницы: From eaa7dd527be935176140cada0fa1e8505e4e723b Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Tue, 31 Mar 2026 11:23:54 +0300 Subject: [PATCH 10/12] =?UTF-8?q?docs(quickstart):=20remove=20=D1=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../current/quickstart/index.mdx | 16 ++++++++-------- .../current/quickstart/running-tests.mdx | 2 +- .../current/quickstart/usage-in-ci.mdx | 2 +- .../current/quickstart/writing-tests.mdx | 10 +++++----- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx index 48abd9f..5d96c1e 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx @@ -82,13 +82,13 @@ export default { ### Основные параметры конфигурации -- `gridUrl` определяет, где запускать браузеры. Значение `"local"` означает запуск на вашей локальной машине. Для удалённого запуска укажите URL Selenium Grid или облачного сервиса (например, BrowserStack или Sauce Labs). -- `sets` — группы тестов, привязанные к определённым браузерам. Позволяет запускать разные наборы тестов в разных браузерах. Например, можно создать отдельные наборы для десктопных тестов в Chrome/Firefox и мобильных в Safari. Подробнее в [справочнике по sets](../reference/config/sets.mdx). +- `gridUrl` определяет, где запускать браузеры. Значение `"local"` означает запуск на вашей локальной машине. Для удаленного запуска укажите URL Selenium Grid или облачного сервиса (например, BrowserStack или Sauce Labs). +- `sets` — группы тестов, привязанные к определенным браузерам. Позволяет запускать разные наборы тестов в разных браузерах. Например, можно создать отдельные наборы для десктопных тестов в Chrome/Firefox и мобильных в Safari. Подробнее в [справочнике по sets](../reference/config/sets.mdx). - `testTimeout` — максимальное время выполнения одного теста в миллисекундах. Если тест выполняется дольше этого значения, он будет прерван. Настраивайте в зависимости от сложности вашего приложения. - `pageLoadTimeout` — максимальное время ожидания загрузки страницы. - `browsers` — конфигурация для каждого браузера. Параметр `headless: true` запускает браузер в фоновом режиме без графического интерфейса. Подробнее в разделе [Браузеры](../basic-guides/managing-browsers.mdx). - `prepareBrowser` — хук для настройки браузера перед запуском тестов. В конфиге по умолчанию вызывает `setupBrowser(browser)`, который добавляет методы Testing Library к объекту браузера и элементам, позволяя сразу использовать семантические запросы в тестах. -- `plugins` — подключаемые модули. `html-reporter` — инструмент для просмотра результатов тестов в браузере. Предоставляет интерактивные отчёты со скриншотами, логами и возможностями отладки. Подробнее в разделе [HTML Reporter](../html-reporter/overview.mdx). +- `plugins` — подключаемые модули. `html-reporter` — инструмент для просмотра результатов тестов в браузере. Предоставляет интерактивные отчеты со скриншотами, логами и возможностями отладки. Подробнее в разделе [HTML Reporter](../html-reporter/overview.mdx). Полный список параметров конфигурации см. в [справочнике по конфигурации](../reference/config/main.mdx). @@ -114,17 +114,17 @@ Testplane автоматически выполнит следующие дей 1. Загрузит браузеры: если вы не запускали `install-deps`, Testplane скачает Chrome и Firefox 2. Запустит тест: выполнит пример из `testplane-tests/example.testplane.ts` -3. Создаст отчёт: сгенерирует HTML-репорт в папке `testplane-report/` +3. Создаст отчет: сгенерирует HTML-репорт в папке `testplane-report/` ### Просмотр результатов -После завершения тестов откройте интерактивный отчёт: +После завершения тестов откройте интерактивный отчет: ```bash npx testplane gui ``` -Команда запустит локальный сервер и откроет отчёт в браузере. В интерфейсе вы увидите: +Команда запустит локальный сервер и откроет отчет в браузере. В интерфейсе вы увидите: - Список пройденных тестов - Статистику выполнения @@ -133,7 +133,7 @@ npx testplane gui ### Ожидаемый результат -Если всё настроено корректно, вы увидите: +Если все настроено корректно, вы увидите: ``` ✔ test examples › docs search test [chrome] - 3.2s @@ -144,7 +144,7 @@ Total: 2 Passed: 2 Failed: 0 Skipped: 0 Retries: 0 ### Возможные проблемы -Если тест не прошёл, проверьте: +Если тест не прошел, проверьте: - Интернет-соединение (тест обращается к https://testplane.io/) - Браузеры установлены: `npx testplane install-deps` diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index ada7e0f..eda2109 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -130,7 +130,7 @@ npx testplane gui npx testplane --local --devtools --grep "Название теста" ``` -Что произойдёт: +Что произойдет: 1. Откроется видимое окно браузера 2. Автоматически откроются Chrome DevTools diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx index 22d4074..cd1d58a 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/usage-in-ci.mdx @@ -4,7 +4,7 @@ sidebar_position: 4 # Использование в CI -Testplane можно легко интегрировать в любую CI-систему. Для GitHub Actions рекомендуем использовать официальный action [gemini-testing/gh-actions-testplane](https://github.com/gemini-testing/gh-actions-testplane), который автоматически кэширует браузеры и формирует отчёты. +Testplane можно легко интегрировать в любую CI-систему. Для GitHub Actions рекомендуем использовать официальный action [gemini-testing/gh-actions-testplane](https://github.com/gemini-testing/gh-actions-testplane), который автоматически кэширует браузеры и формирует отчеты. ## Настройка GitHub Actions diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx index ced17ec..44e2427 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx @@ -101,7 +101,7 @@ describe("Примеры селекторов", () => { ```typescript describe("Типы селекторов", () => { it("CSS-селекторы", async ({ browser }) => { - // Рекомендуется: data-атрибуты (стабильны, не зависят от вёрстки) + // Рекомендуется: data-атрибуты (стабильны, не зависят от верстки) const button = await browser.$('[data-testid="submit-button"]'); // Хорошо: CSS-классы и теги @@ -129,7 +129,7 @@ describe("Типы селекторов", () => { **Приоритет использования:** -1. Data-атрибуты (`[data-testid="..."]`) — самый надёжный способ +1. Data-атрибуты (`[data-testid="..."]`) — самый надежный способ 2. CSS-селекторы (классы, ID, теги) — для стабильных элементов 3. Текстовые селекторы — когда нет других вариантов 4. XPath — только для сложных случаев @@ -167,7 +167,7 @@ it("Ввод текста в поле", async ({ browser }) => { const input = await browser.$('input[name="email"]'); await input.setValue("user@example.com"); - // Проверяем введённое значение + // Проверяем введенное значение await expect(input).toHaveValue("user@example.com"); }); ``` @@ -388,7 +388,7 @@ it("Выполнение JavaScript", async ({ browser }) => { ## Шаги теста (runStep) -Команда `runStep` позволяет структурировать тест и улучшить читаемость отчётов: +Команда `runStep` позволяет структурировать тест и улучшить читаемость отчетов: ```typescript it("Оформление заказа", async ({ browser }) => { @@ -409,7 +409,7 @@ it("Оформление заказа", async ({ browser }) => { }); ``` -Шаги отображаются в HTML-отчёте, что упрощает отладку упавших тестов. +Шаги отображаются в HTML-отчете, что упрощает отладку упавших тестов. ## Что дальше? From 03011fbfbe645242e8bbd7617da5da99741b4f3d Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Fri, 10 Apr 2026 02:14:42 +0300 Subject: [PATCH 11/12] docs(quickstart): some fixes --- .../current/quickstart/index.mdx | 15 ++++++---- .../current/quickstart/writing-tests.mdx | 28 ++----------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx index 5d96c1e..1460cb0 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx @@ -39,6 +39,9 @@ testplane.config.ts В файле `testplane.config.ts` содержится базовый набор настроек для запуска тестов: ```typescript title="testplane.config.ts" +import { setupBrowser } from "@testplane/testing-library"; +import type { WdioBrowser } from "testplane"; + export default { gridUrl: "local", baseUrl: "http://localhost", @@ -82,13 +85,13 @@ export default { ### Основные параметры конфигурации -- `gridUrl` определяет, где запускать браузеры. Значение `"local"` означает запуск на вашей локальной машине. Для удаленного запуска укажите URL Selenium Grid или облачного сервиса (например, BrowserStack или Sauce Labs). -- `sets` — группы тестов, привязанные к определенным браузерам. Позволяет запускать разные наборы тестов в разных браузерах. Например, можно создать отдельные наборы для десктопных тестов в Chrome/Firefox и мобильных в Safari. Подробнее в [справочнике по sets](../reference/config/sets.mdx). -- `testTimeout` — максимальное время выполнения одного теста в миллисекундах. Если тест выполняется дольше этого значения, он будет прерван. Настраивайте в зависимости от сложности вашего приложения. +- `gridUrl` — где запускать браузеры: `"local"` для локального запуска или URL для Selenium Grid или облака (например, BrowserStack, Sauce Labs). +- `sets` — группы тестов для разных браузеров (например, набор тестов для десктопных Chrome или Firefox и набор для мобильного Safari). Подробнее: [справочник по sets](https://github.com/gemini-testing/testplane-docs/pull/reference/config/sets.mdx). +- `testTimeout` — максимальное время выполнения теста в миллисекундах, после превышения тест прерывается. - `pageLoadTimeout` — максимальное время ожидания загрузки страницы. -- `browsers` — конфигурация для каждого браузера. Параметр `headless: true` запускает браузер в фоновом режиме без графического интерфейса. Подробнее в разделе [Браузеры](../basic-guides/managing-browsers.mdx). -- `prepareBrowser` — хук для настройки браузера перед запуском тестов. В конфиге по умолчанию вызывает `setupBrowser(browser)`, который добавляет методы Testing Library к объекту браузера и элементам, позволяя сразу использовать семантические запросы в тестах. -- `plugins` — подключаемые модули. `html-reporter` — инструмент для просмотра результатов тестов в браузере. Предоставляет интерактивные отчеты со скриншотами, логами и возможностями отладки. Подробнее в разделе [HTML Reporter](../html-reporter/overview.mdx). +- `browsers` — конфигурация браузеров; `headless: true` — запуск без UI. Подробнее: [Браузеры](https://github.com/gemini-testing/testplane-docs/pull/basic-guides/managing-browsers.mdx). +- `prepareBrowser` — хук перед тестами; в конфиге выше вызывает `setupBrowser(browser)` и добавляет методы Testing Library. +- `plugins` — плагины; в конфиге выше `html-reporter` для интерактивных отчетов (скриншоты, логи, отладка). Подробнее: [HTML Reporter](https://github.com/gemini-testing/testplane-docs/pull/html-reporter/overview.mdx). Полный список параметров конфигурации см. в [справочнике по конфигурации](../reference/config/main.mdx). diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx index 44e2427..d3cac1e 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx @@ -65,27 +65,18 @@ describe("Название группы тестов", () => { await browser.url("https://example.com/"); ``` -Для ожидания загрузки страницы используйте [`browser.openAndWait()`](../commands/browser/openAndWait.mdx): - -```typescript -await browser.openAndWait("https://example.com/", { - waitNetworkIdle: true, - timeout: 10000, -}); -``` - -Команда `openAndWait` дожидается загрузки страницы и сетевой активности. +Для перехода на страницу можно также использовать команду [`browser.openAndWait()`](../commands/browser/openAndWait.mdx), которая поддерживает больше настроек, связанных с загрузкой статики на странице. ### Селекторы -Testplane поддерживает различные стратегии поиска элементов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а [`$$()`](../commands/browser/$$.mdx) — массив всех подходящих: +Testplane поддерживает различные стратегии поиска элементов: CSS-селекторы (самые распространенные), текстовые селекторы (по содержимому), XPath для сложных запросов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а [`$$()`](../commands/browser/$$.mdx) — массив всех подходящих: ```typescript describe("Примеры селекторов", () => { it("Поиск элементов", async ({ browser }) => { await browser.url("https://example.com/"); - // CSS-селекторы (рекомендуется) + // Первый найденный элемент const heading = await browser.$("h1"); const button = await browser.$('[data-testid="submit"]'); @@ -127,19 +118,6 @@ describe("Типы селекторов", () => { }); ``` -**Приоритет использования:** - -1. Data-атрибуты (`[data-testid="..."]`) — самый надежный способ -2. CSS-селекторы (классы, ID, теги) — для стабильных элементов -3. Текстовые селекторы — когда нет других вариантов -4. XPath — только для сложных случаев - -**Избегайте:** - -- Сложных CSS-селекторов, зависящих от структуры DOM -- Селекторов по порядковому номеру (`:nth-child`) -- XPath без необходимости (медленнее CSS) - ### Взаимодействие с элементами #### Клик From 4d3022ab40836d09ede4e311dd98c52c0cf24ac3 Mon Sep 17 00:00:00 2001 From: kseniataranov Date: Mon, 13 Apr 2026 13:04:55 +0300 Subject: [PATCH 12/12] docs(quickstart): some fixes, update examples --- .../current/quickstart/index.mdx | 16 +- .../current/quickstart/running-tests.mdx | 120 +++--- .../current/quickstart/writing-tests.mdx | 364 +++++++++--------- 3 files changed, 259 insertions(+), 241 deletions(-) diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx index 1460cb0..5822935 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/index.mdx @@ -4,17 +4,16 @@ sidebar_position: 1 import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; -import Admonition from "@theme/Admonition"; # Установка и настройка ## Системные требования -Чтобы начать работу с testplane, установите `Node.js` версии 18.0 и выше. +Чтобы начать работу с Testplane, установите `Node.js` версии 18.0 и выше. ## Установка {#install} -Для запуска установщика testplane с помощью `npm` выполните следующую команду: +Для запуска установщика Testplane с помощью `npm` выполните следующую команду: ```bash npm init testplane@latest YOUR_PROJECT_PATH @@ -93,7 +92,7 @@ export default { - `prepareBrowser` — хук перед тестами; в конфиге выше вызывает `setupBrowser(browser)` и добавляет методы Testing Library. - `plugins` — плагины; в конфиге выше `html-reporter` для интерактивных отчетов (скриншоты, логи, отладка). Подробнее: [HTML Reporter](https://github.com/gemini-testing/testplane-docs/pull/html-reporter/overview.mdx). -Полный список параметров конфигурации см. в [справочнике по конфигурации](../reference/config/main.mdx). +Полный список параметров конфигурации ищите в [справочнике по конфигурации](../reference/config/main.mdx). Чтобы загрузить браузеры, описанные в конфиге, отдельно от запуска самого Testplane, выполните команду: @@ -145,14 +144,7 @@ npx testplane gui Total: 2 Passed: 2 Failed: 0 Skipped: 0 Retries: 0 ``` -### Возможные проблемы - -Если тест не прошел, проверьте: - -- Интернет-соединение (тест обращается к https://testplane.io/) -- Браузеры установлены: `npx testplane install-deps` - -Подробнее об отладке в разделе [Запуск и отладка](./running-tests.mdx). +Для успешного прохождения тестам нужен доступ к [testplane.io](https://testplane.io/). ## Что дальше? diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx index eda2109..a62b886 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/running-tests.mdx @@ -2,6 +2,8 @@ sidebar_position: 3 --- +import Admonition from "@theme/Admonition"; + # Запуск и отладка ## Запуск тестов @@ -21,15 +23,15 @@ npx testplane gui В GUI вы можете: - Наблюдать выполнение тестов в реальном времени -- Просматривать скриншоты и сравнивать их +- Просматривать скриншоты, сравнивать и обновлять их - Перезапускать отдельные тесты - Видеть подробные ошибки с историей команд -![Интерфейс Testplane GUI](/img/docs/guides/testplane-gui.png) +![Интерфейс Testplane GUI](/gif/docs/ui/run-debug.gif) Подробнее о GUI читайте в разделе [HTML Reporter](../html-reporter/overview.mdx). -### Фильтрация тестов +## Фильтрация тестов при запуске Предположим, у вас есть такие тесты: @@ -45,7 +47,7 @@ describe("Главная страница", () => { }); ``` -#### По имени {#the-grep-option} +### По имени {#the-grep-option} Опция [`--grep`](../reference/cli.mdx) позволяет запускать тесты по совпадению с именем: @@ -56,18 +58,18 @@ npx testplane --grep "Проверка наличия поля поиска" Поддерживаются регулярные выражения: ```bash -npx testplane --grep "поиск|навигация" +npx testplane --grep "поиска|заголовка" ``` Опция `--grep` фильтрует тесты по полному имени (включая все уровни `describe` и `it`). Переданная строка интерпретируется как регулярное выражение. -#### По тегам +### По тегам Теги помогают группировать тесты, например, отделить быстрые smoke-тесты от полных: ```typescript describe("Авторизация", { tag: "auth" }, () => { - it("успешный вход", { tag: "smoke" }, async ({ browser }) => { + it("Успешный вход", { tag: "smoke" }, async ({ browser }) => { // ... }); }); @@ -77,10 +79,10 @@ describe("Авторизация", { tag: "auth" }, () => { ```bash npx testplane --tag "smoke" # только smoke-тесты -npx testplane --tag "auth & smoke" # тесты с обоими тегами +npx testplane --tag "auth&smoke" # тесты с обоими тегами ``` -#### По браузеру +### По браузеру По умолчанию тесты запускаются во всех браузерах из конфига. Чтобы запустить только в одном: @@ -88,7 +90,37 @@ npx testplane --tag "auth & smoke" # тесты с обоими тегами npx testplane --browser chrome ``` -#### По файлу {#running_a_specific_file} +Опцию `--browser` можно указывать несколько раз для запуска в нескольких браузерах: + +```bash +npx testplane -b chrome -b firefox +``` + +Также вы можете указать конкретный браузер в коде теста: + +```typescript +describe("Запуск тестов в разных браузерах", () => { + it("Работает во всех браузерах", async ({ browser }) => { + await browser.url("https://testplane.io/"); + }); + + // Пропустить тест в Safari + testplane.skip.in("safari", "Feature not supported in Safari"); + it("Работает только в Chrome и Firefox", async ({ browser }) => { + await browser.url("https://testplane.io/"); + // ... + }); + + // Запустить только в Chrome + testplane.only.in("chrome"); + it("Работает только в Chrome", async ({ browser }) => { + await browser.url("https://testplane.io/"); + // ... + }); +}); +``` + +### По файлу {#running_a_specific_file} Чтобы запустить тесты из конкретного файла: @@ -96,7 +128,7 @@ npx testplane --browser chrome npx testplane tests/login.testplane.ts ``` -#### Быстрый запуск одного теста +### Быстрый запуск одного теста Во время разработки удобно использовать `.only()`: @@ -120,14 +152,12 @@ npx testplane gui В GUI вы увидите выполнение тестов в реальном времени, скриншоты и ошибки. Можно перезапускать отдельные тесты и наблюдать за их выполнением. -![](/gif/docs/ui/run-debug.gif) - ### Локальный браузер с DevTools -По умолчанию Testplane запускает браузер в headless-режиме (без окна). Для отладки можно открыть видимое окно браузера с DevTools: +Для отладки можно открыть видимое окно браузера с DevTools: ```bash -npx testplane --local --devtools --grep "Название теста" +npx testplane --local --devtools --headless false --grep "Название теста" ``` Что произойдет: @@ -136,25 +166,41 @@ npx testplane --local --devtools --grep "Название теста" 2. Автоматически откроются Chrome DevTools 3. Вы сможете наблюдать за выполнением теста +В браузере Firefox нет поддержки DevTools. + ### REPL-режим -REPL (Read-Eval-Print Loop) — интерактивная консоль для выполнения команд браузера во время теста. +REPL (Read-Eval-Print Loop) — интерактивная консоль для выполнения команд браузера во время теста. Есть несколько способов войти в REPL: -Добавьте `browser.debug()` в код теста: +1. Опции командной строки: -```typescript -it("Отладка", async ({ browser }) => { - await browser.url("/page"); - await browser.debug(); // Тест остановится здесь + - `--repl` — включает REPL-режим. Для входа в консоль вызовите [`browser.switchToRepl()`](../commands/browser/switchToRepl.mdx) в коде теста + - `--repl-before-test` — автоматически открывает REPL перед запуском теста + - `--repl-on-fail` — автоматически открывает REPL при падении теста - // В консоли можно выполнять команды: - // > await browser.$(".button").click() - // > await browser.getTitle() - // > .exit — выйти из REPL и продолжить тест + ```bash + # Открыть REPL при падении теста + npx testplane --repl-on-fail --grep "Название теста" --browser chrome - await browser.$(".button").click(); -}); -``` + # Открыть REPL перед запуском теста + npx testplane --repl-before-test --grep "Название теста" --browser chrome + ``` + +2. Команда `browser.switchToRepl()` в коде: + + ```typescript + it("Отладка", async ({ browser }) => { + await browser.url("/page"); + await browser.switchToRepl(); // Тест остановится здесь + + // В консоли можно выполнять команды: + // > await browser.$(".button").click() + // > await browser.getTitle() + // > Cmd+D или Ctrl+D — выйти из REPL и продолжить тест + + await browser.$(".button").click(); + }); + ``` ### Сохранение браузера после теста @@ -165,19 +211,7 @@ npx testplane --keep-browser --grep "Название теста" npx testplane --keep-browser-on-fail # только при падении ``` -Полезно для проверки DOM, cookies или localStorage после выполнения теста. - -## Что делать, если тест упал - -Запустите тесты в GUI и кликните на упавший тест, чтобы увидеть текст ошибки, скриншот страницы и историю выполненных команд. - -Частые причины: - -- Элемент не найден: проверьте селектор в DevTools -- Элемент не готов: добавьте ожидание: `await element.waitForDisplayed()` -- Тест падает в CI: увеличьте таймауты - -Подробное руководство: [Отладка тестов](../basic-guides/debugging-tests.mdx) +Полезно для проверки DOM, cookies или localStorage после выполнения теста, а также в связке с [MCP](../testplane-mcp.mdx), чтобы AI-агент подключился к уже подготовленному браузеру. ## Полезные команды @@ -194,8 +228,8 @@ npx testplane --grep "название теста" # Запуск только в одном браузере npx testplane --browser chrome -# Отладка с DevTools -npx testplane --local --devtools --grep "название теста" +# Отладка с Chrome DevTools Protocol +npx testplane --devtools --grep "название теста" # Интерактивная отладка при падении npx testplane --repl-on-fail --grep "название теста" diff --git a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx index d3cac1e..e30eb53 100644 --- a/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx +++ b/i18n/ru/docusaurus-plugin-content-docs/current/quickstart/writing-tests.mdx @@ -2,6 +2,8 @@ sidebar_position: 2 --- +import Admonition from "@theme/Admonition"; + # Написание тестов ## Структура теста @@ -62,25 +64,30 @@ describe("Название группы тестов", () => { Для перемещения по страницам используйте метод [`browser.url()`](../commands/browser/url.mdx): ```typescript -await browser.url("https://example.com/"); +await browser.url("https://testplane.io/"); ``` Для перехода на страницу можно также использовать команду [`browser.openAndWait()`](../commands/browser/openAndWait.mdx), которая поддерживает больше настроек, связанных с загрузкой статики на странице. ### Селекторы -Testplane поддерживает различные стратегии поиска элементов: CSS-селекторы (самые распространенные), текстовые селекторы (по содержимому), XPath для сложных запросов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а [`$$()`](../commands/browser/$$.mdx) — массив всех подходящих: +Testplane поддерживает различные стратегии поиска элементов: CSS-селекторы (самые распространенные), текстовые селекторы (по содержимому), XPath для сложных запросов. Метод [`$()`](../commands/browser/$.mdx) возвращает первый найденный элемент, а [`$$()`](../commands/browser/$$.mdx) — массив всех подходящих. + +Testplane интегрирована с Testing Library, это позволяет писать более читаемые тесты, ориентированные на пользовательское поведение. Пакет устанавливается автоматически при инициализации через `npm init testplane`. ```typescript describe("Примеры селекторов", () => { - it("Поиск элементов", async ({ browser }) => { - await browser.url("https://example.com/"); + it("Первый найденный элемент", async ({ browser }) => { + await browser.url("https://testplane-bookstore.website.yandexcloud.net/"); - // Первый найденный элемент const heading = await browser.$("h1"); - const button = await browser.$('[data-testid="submit"]'); + const input = await browser.$('[data-testid="search-input"]'); + const inputTL = await browser.findByTestId("search-input"); + }); + + it("Поиск нескольких элементов", async ({ browser }) => { + await browser.url("https://testplane.io/"); - // Поиск нескольких элементов const links = await browser.$$("a"); expect(links.length).toBeGreaterThan(0); }); @@ -92,125 +99,176 @@ describe("Примеры селекторов", () => { ```typescript describe("Типы селекторов", () => { it("CSS-селекторы", async ({ browser }) => { - // Рекомендуется: data-атрибуты (стабильны, не зависят от верстки) - const button = await browser.$('[data-testid="submit-button"]'); + await browser.url("https://testplane-bookstore.website.yandexcloud.net/"); + + // data-атрибуты + const input = await browser.$('[data-testid="search-input"]'); + const inputTL = await browser.findByTestId("search-input"); - // Хорошо: CSS-классы и теги - const logo = await browser.$("a.navbar__brand"); + // CSS-классы и теги + const navbar = await browser.$(".navbar"); const heading = await browser.$("h1"); }); it("Текстовые селекторы", async ({ browser }) => { + await browser.url("https://testplane.io/"); + // Поиск по точному тексту - const link = await browser.$("a=Документация"); + const match = await browser.$("=Docs"); // Поиск по частичному совпадению - const button = await browser.$("button*=Начать"); + const partial = await browser.$("*=Doc"); }); it("XPath", async ({ browser }) => { - // Поиск по тексту внутри элемента - const element = await browser.$("//button[contains(text(), 'Поиск')]"); + await browser.url("https://testplane.io/"); - // Поиск родительского элемента - const parent = await browser.$("//a[@class='logo']/parent::div"); + // Поиск по тексту внутри элемента + const link = await browser.$('//a[text()="Docs"]'); }); }); ``` +Подробнее про селекторы читайте в [этой статье](../basic-guides/selectors.mdx). + ### Взаимодействие с элементами #### Клик ```typescript -it("Клик по кнопке", async ({ browser }) => { - await browser.url("https://example.com/"); +const assert = require("assert"); + +describe("Клик", () => { + it("Клик: открытие поиска", async ({ browser }) => { + await browser.url("https://testplane.io/"); + + // Клик по кнопке поиска + const searchButton = await browser.$("button.DocSearch"); + await searchButton.waitForClickable({ timeout: 5000 }); + await searchButton.click(); + + // Проверка + const searchModal = await browser.$(".DocSearch-Modal"); + await searchModal.waitForDisplayed({ timeout: 5000 }); + const isDisplayed = await searchModal.isDisplayed(); + assert.strictEqual(isDisplayed, true); + }); + + it("Двойной клик: выделение текста заголовка", async ({ browser }) => { + await browser.url("https://testplane.io/ru/"); - const button = await browser.$("button"); - await button.waitForClickable(); - await button.click(); + // Поиск заголовка на главной странице + const heading = await browser.$("h1"); + await heading.waitForDisplayed({ timeout: 5000 }); + await heading.scrollIntoView(); - // Проверяем результат - const result = await browser.$(".result"); - await expect(result).toBeDisplayed(); + // Двойной клик по заголовку + await heading.doubleClick(); + + // Проверка + const isDisplayed = await heading.isDisplayed(); + assert.strictEqual(isDisplayed, true); + }); }); ``` #### Ввод текста ```typescript -it("Ввод текста в поле", async ({ browser }) => { - await browser.url("https://example.com/login"); +const assert = require("assert"); - const input = await browser.$('input[name="email"]'); - await input.setValue("user@example.com"); +describe("Ввод текста", () => { + it("Ввод текста в поле поиска", async ({ browser }) => { + await browser.url("https://testplane.io/"); - // Проверяем введенное значение - await expect(input).toHaveValue("user@example.com"); + // Клик по кнопке поиска + const searchButton = await browser.$("button.DocSearch"); + await searchButton.waitForClickable({ timeout: 5000 }); + await searchButton.click(); + + // Ввод текста в поле поиска + const searchInput = await browser.$("input.DocSearch-Input"); + await searchInput.waitForDisplayed({ timeout: 5000 }); + await searchInput.setValue("browser"); + + // Проверка + const inputValue = await searchInput.getValue(); + assert.strictEqual(inputValue, "browser"); + }); }); ``` -#### Работа с формами +#### Взаимодействие с формами ```typescript -it("Работа с чекбоксами и селектами", async ({ browser }) => { - await browser.url("https://example.com/form"); - - // Чекбокс - const checkbox = await browser.$('input[type="checkbox"]'); - await checkbox.click(); - await expect(checkbox).toBeSelected(); - - // Выпадающий список - const select = await browser.$("select"); - await select.selectByVisibleText("Option 1"); - await expect(select).toHaveValue("1"); -}); -``` +const assert = require("assert"); -### Assertions +describe("Взаимодействие с формами", () => { + it("Чекбокс", async ({ browser }) => { + await browser.url("https://testplane-bookstore.website.yandexcloud.net/login"); -Testplane использует `expect` API из WebdriverIO для проверки состояния элементов и страниц. + const checkbox = await browser.$('[data-testid="remember-checkbox"]'); + await checkbox.waitForDisplayed({ timeout: 5000 }); -#### WebdriverIO expect + // Проверка начального состояния + let isSelected = await checkbox.isSelected(); + assert.strictEqual(isSelected, false); -```typescript -it("проверки элементов", async ({ browser }) => { - await browser.url("https://example.com/"); + // Выбор + await checkbox.click(); + isSelected = await checkbox.isSelected(); + assert.strictEqual(isSelected, true); + + // Снятие выбора + await checkbox.click(); + isSelected = await checkbox.isSelected(); + assert.strictEqual(isSelected, false); + }); - const heading = await browser.$("h1"); + it("Выпадающий список", async ({ browser }) => { + await browser.url("https://testplane-bookstore.website.yandexcloud.net/"); - // Проверка существования и видимости - await expect(heading).toExist(); - await expect(heading).toBeDisplayed(); + const dropdown = await browser.$('[data-testid="sort-select"]'); + await dropdown.waitForDisplayed({ timeout: 5000 }); - // Проверка текста - await expect(heading).toHaveText("Example Domain"); - await expect(heading).toHaveTextContaining("Example"); + // Выбор опции по видимому тексту + await dropdown.selectByVisibleText("Highest Rated"); - // Проверка браузера - await expect(browser).toHaveUrl("https://example.com/"); - await expect(browser).toHaveTitle("Example Domain"); + // Проверка выбранного значения + let selectedValue = await dropdown.getValue(); + assert.strictEqual(selectedValue, "rating"); + + // Проверка текста выбранной опции + let selectedText = await dropdown.$("option:checked").getText(); + assert.strictEqual(selectedText, "Highest Rated"); + }); }); ``` -#### Jest expect +### Assertions + +Assertions — это проверки, которые сравнивают фактический результат с ожидаемым. ```typescript -it("проверки значений", async ({ browser }) => { - await browser.url("https://example.com/"); +describe("Assertions", () => { + it("Проверка элементов", async ({ browser }) => { + await browser.url("https://testplane.io/"); - const title = await browser.getTitle(); - expect(title).toContain("Example"); + const heading = await browser.$("h1"); + + // Проверка существования и видимости + await expect(heading).toExist(); + await expect(heading).toBeDisplayed(); - const links = await browser.$$("a"); - expect(links.length).toBeGreaterThan(0); + // Проверка текста + await expect(heading).toHaveTextContaining("testplane"); + + // Проверка атрибутов + await expect(heading).toHaveAttribute("class"); + }); }); ``` -- Используйте WebdriverIO `expect` для проверок элементов (`$`, `$$`) и браузера (`browser`). Он автоматически повторяет проверку до успеха или таймаута. -- Применяйте Jest `expect` для проверок простых значений (строк, чисел, массивов), которые не требуют ожидания. - ### Хуки Хуки позволяют подготовить окружение перед тестами и очистить его после выполнения. @@ -219,7 +277,7 @@ it("проверки значений", async ({ browser }) => { describe("Работа с хуками", () => { beforeEach(async ({ browser }) => { // Выполняется перед каждым тестом - await browser.url("https://example.com/"); + await browser.url("https://testplane.io/"); }); afterEach(async ({ browser }) => { @@ -230,7 +288,7 @@ describe("Работа с хуками", () => { it("Первый тест", async ({ browser }) => { // Страница уже открыта благодаря beforeEach const title = await browser.getTitle(); - expect(title).toContain("Example"); + expect(title).toContain("Fast"); }); it("Второй тест", async ({ browser }) => { @@ -246,41 +304,33 @@ describe("Работа с хуками", () => { Явные ожидания необходимы для работы с динамическим контентом: ```typescript -it("Ожидание элементов", async ({ browser }) => { - await browser.url("https://example.com/"); - - const button = await browser.$("button"); +describe("Ожидание", () => { + it("Ожидание элементов", async ({ browser }) => { + await browser.url("https://testplane.io/"); - // Ожидание появления - await button.waitForDisplayed({ timeout: 5000 }); + const button = await browser.$("button*=Get"); - // Ожидание кликабельности - await button.waitForClickable({ timeout: 3000 }); - - // Ожидание существования - await button.waitForExist({ timeout: 5000 }); + // Ожидание появления + await button.waitForDisplayed({ timeout: 5000 }); + }); - await button.click(); -}); -``` + it("Кастомное ожидание", async ({ browser }) => { + await browser.url("https://testplane.io/"); -#### Кастомные ожидания + const heading = await browser.$("h1"); -```typescript -it("Кастомное ожидание", async ({ browser }) => { - await browser.url("https://example.com/"); - - // Ожидание изменения URL - await browser.waitUntil( - async () => { - const url = await browser.getUrl(); - return url.includes("success"); - }, - { - timeout: 5000, - timeoutMsg: "URL не изменился на success", - }, - ); + // Ожидание появления текста заголовка + await heading.waitUntil( + async function () { + const text = await this.getText(); + return text.length > 0; + }, + { + timeout: 5000, + timeoutMsg: "Текст заголовка не появился", + }, + ); + }); }); ``` @@ -291,104 +341,46 @@ Testplane позволяет делать скриншоты элементов При первом запуске теста создаются эталонные скриншоты. При последующих запусках Testplane сравнивает новые скриншоты с эталонами и сообщает о различиях. Если различий нет, тест проходит. Если есть различия, тест падает, а diff-изображение сохраняется для анализа. ```typescript -it("Визуальная проверка кнопки", async ({ browser }) => { - await browser.url("https://example.com/"); - - // Скриншот элемента - await browser.assertView("button-default", "button"); - - // Клик и проверка нового состояния - await browser.$("button").click(); - await browser.assertView("button-clicked", "button"); -}); -``` - -### Параметры assertView - -```typescript -it("assertView с параметрами", async ({ browser }) => { - await browser.url("https://example.com/"); - - await browser.assertView("form", ".form", { - // Игнорировать элементы при сравнении - ignoreElements: [".dynamic-date", ".random-id"], - - // Допустимое отклонение в пикселях - tolerance: 5, +describe("Визуальная проверка", () => { + it("Логотип", async ({ browser }) => { + await browser.url("https://testplane.io/"); - // Задержка перед скриншотом (для анимаций) - screenshotDelay: 100, + // Ожидание появления элемента + const brand = await browser.$(".navbar__brand"); + await brand.waitForDisplayed({ timeout: 10000 }); - // Отключить анимации - disableAnimation: true, + // Скриншот элемента + await browser.assertView("default", ".navbar__brand"); }); }); ``` -### Скриншот всего viewport - -```typescript -it("Скриншот viewport", async ({ browser }) => { - await browser.url("https://example.com/"); - - // Без селектора — скриншот текущего viewport - await browser.assertView("full-page"); -}); -``` - -## Работа с JavaScript +## Выполнение JavaScript Метод `execute()` выполняет JavaScript-код в контексте страницы: ```typescript -it("Выполнение JavaScript", async ({ browser }) => { - await browser.url("https://example.com/"); - - // Работа с localStorage - await browser.execute(() => { - localStorage.setItem("token", "abc123"); - }); - - const token = await browser.execute(() => { - return localStorage.getItem("token"); - }); - expect(token).toBe("abc123"); - - // Передача параметров - const sum = await browser.execute((a, b) => a + b, 5, 10); - expect(sum).toBe(15); -}); -``` +describe("Выполнение JavaScript", () => { + it("Пример", async ({ browser }) => { + await browser.url("https://testplane.io/"); -:::warning Ограничения browser.execute -Код в `browser.execute()` выполняется в браузере, а не в Node.js. Вы не можете использовать Node.js модули (`fs`, `path`) или обращаться к файловой системе. -::: - -## Шаги теста (runStep) - -Команда `runStep` позволяет структурировать тест и улучшить читаемость отчетов: - -```typescript -it("Оформление заказа", async ({ browser }) => { - await browser.runStep("Открыть каталог", async () => { - await browser.url("/catalog"); - await browser.$(".products").waitForDisplayed(); - }); + // Работа с localStorage + await browser.execute(() => { + localStorage.setItem("token", "abc123"); + }); - await browser.runStep("Добавить товар в корзину", async () => { - await browser.$(".product-card button").click(); - await expect(browser.$(".cart-count")).toHaveText("1"); - }); + const token = await browser.execute(() => { + return localStorage.getItem("token"); + }); + expect(token).toBe("abc123"); - await browser.runStep("Оформить заказ", async () => { - await browser.url("/checkout"); - await browser.$('button[type="submit"]').click(); + // Передача параметров + const sum = await browser.execute((a, b) => a + b, 5, 10); + expect(sum).toBe(15); }); }); ``` -Шаги отображаются в HTML-отчете, что упрощает отладку упавших тестов. - ## Что дальше? Теперь, когда вы знаете основы написания тестов, изучите: @@ -397,4 +389,4 @@ it("Оформление заказа", async ({ browser }) => { - [Использование в CI](./usage-in-ci.mdx): автоматический запуск в GitHub Actions - [Конфигурация](../reference/config/main.mdx): полный список настроек - [Команды браузера](../commands/browser/url.mdx): все доступные команды -- [HTML Reporter](../html-reporter/overview.mdx): работа с отчётами +- [HTML Reporter](../html-reporter/overview.mdx): работа с отчетами