Раздел подготовки

Инструменты автоматизации: вопросы для собеседования QA

Инструменты проверяют практическую сторону AQA: локаторы, ожидания, архитектуру тестов, отчеты и запуск в пайплайне.

42 вопросов 6 базовых 3 уровня: Junior, Middle, Senior

Что закрывает этот раздел

Подготовиться к вопросам по Selenium, Playwright, Selenide, Pytest и JUnit.

  • объяснять локаторы
  • работать с ожиданиями
  • понимать запуск автотестов в CI

С чего начать

Если времени мало, начни с базовых вопросов: они чаще всего помогают пройти первый технический фильтр и показать структуру мышления.

  1. Как вы применяете Allure annotations: @step, @description, @severity, @feature?
  2. Как вы применяете Allure Framework: основы и настройка для python/java?
  3. Как вы строите UI-автоматизацию на Selenium WebDriver (Java)?
  4. Что такое Playwright и чем он отличается от Selenium?
  5. Какие способы поиска элементов есть в Playwright и какой предпочтительный?
  6. Что такое авто-ожидание в Playwright и как оно работает?

Вопросы и ответы

Как вы применяете Allure annotations: @step, @description, @severity, @feature?

Middle

@step — маркирует метод как шаг в отчёте, отображается в иерархии шагов теста; @description — добавляет текстовое описание теста; @severity — устанавливает уровень критичности (BLOCKER, CRITICAL, NORMAL, MINOR, TRIVIAL).

@feature и @story группируют тесты по функциональным областям продукта, что позволяет фильтровать отчёт по фичам; @link и @issue добавляют ссылки на задачи и баг-трекер.

Из практики: использую аннотации умеренно — @step и @severity обязательно, остальное там, где это реально помогает навигации по отчёту. Перегруженный отчёт читается хуже, чем простой.

Частые ошибки

  • Overuse @Step - не каждая строка кода нуждается в step.

Дополнительные вопросы

  • Как организуете feature иерархию?
  • Практика с dynamic test naming?

Как вы применяете Allure Framework: основы и настройка для python/java?

Middle

Для Python: устанавливаю allure-pytest, запускаю тесты с флагом --alluredir=allure-results, затем генерирую отчёт командой allure serve. Шаги оборачиваю декоратором @allure.step, вложения добавляю через allure.attach.

Для Java: подключаю allure-junit5 или allure-testng через Maven/Gradle, аннотации @Step, @Attachment и @Description работают из коробки. Отчёт генерируется через mvn allure:report.

Из практики: важно настроить хранение allure-results в CI как артефакты и подключить history для отображения тренда стабильности между прогонами.

Частые ошибки

  • Забывание очистки старых results между запусками.
  • Неправильные пути к allure binary в CI/CD.

Дополнительные вопросы

  • Как интегрируете Allure в CI pipeline?
  • Опыт с Allure Docker containers?

Как вы строите UI-автоматизацию на Selenium WebDriver (Java)?

Middle

Строю UI-автоматизацию на трёх китах: надёжные локаторы (приоритет: data-testid > id > CSS > XPath), явные ожидания через WebDriverWait + ExpectedConditions вместо sleep, Page Object Model для разделения сценария и деталей страницы.

Управление WebDriver: для параллельного запуска использую ThreadLocal<WebDriver> вместо статического поля. WebDriver создаю в @BeforeEach, закрываю в @AfterEach.

Из практики: 90% нестабильности UI-тестов — отсутствие явных ожиданий. `driver.findElement()` без ожидания падает на медленных CI-серверах даже если локально работает стабильно.

Частые ошибки

  • Использование Thread.sleep вместо explicit waits.
  • Нестабильные локаторы (абсолютные xpath).

Дополнительные вопросы

  • Как боретесь с нестабильные UI тестами?
  • Опыт с Selenium Grid?

Как вы применяете Allure attachments: screenshots, logs, video, custom data?

Middle

Вложения добавляю через Allure API: аннотация @Attachment над методом или Allure.addAttachment(name, type, content) — так в отчёт попадают скриншоты, логи, запросы/ответы.

Скриншот снимаю на падении, логи и HTTP-трафик прикладываю как текст, видео прогона подключаю через записывающее расширение/файл.

Custom data кладу как произвольное вложение (JSON, CSV, файл) с нужным mime-type; добавляю только полезное, чтобы отчёт оставался читаемым.

Из практики: хорошо подобранные вложения снимают половину вопросов при разборе падения.

Частые ошибки

  • Большие attachments замедляют генерацию отчётов.
  • Отсутствие cleanup strategy для video files.

Дополнительные вопросы

  • Как управляете размером attachments?
  • Опыт с video recording в headless режиме?

Как вы применяете Allure test organization: suites, categories, environments?

Middle

Suites/иерархию задаю BDD-метками @Epic/@Feature/@Story, чтобы отчёт группировался по логике продукта.

Categories настраиваю через categories.json — правила классификации падений (product defects vs test defects) по сообщению и трейсу.

Environments прокидываю через environment.properties (версия, стенд, браузер), чтобы контекст прогона был виден в отчёте.

Из практики: аккуратная структура и категории ускоряют разбор и принятие решений по релизу.

Частые ошибки

  • Неконсистентная структура Epic/Feature/Story.
  • Отсутствие актуальной environment информации.

Дополнительные вопросы

  • Как синхронизируете с Jira/TestRail?
  • Практика с custom categories?

Как вы интегрируете Allure в CI/CD: Jenkins, GitHub Actions и публикацию отчётов?

Senior

В Jenkins подключаю плагин Allure Jenkins Plugin, указываю путь к результатам (allure-results), история отчётов хранится между сборками автоматически.

В GitHub Actions использую шаг allure-report/allure-action, публикую отчёт на GitHub Pages или как артефакт сборки с retention policy.

Из практики: важно хранить historytrendline — без него команда не видит динамику стабильности, только срез по последнему прогону.

Частые ошибки

  • Потеря истории тестов при перезапусках контейнеров.
  • Проблемы прав доступа при публикации отчётов в GitHub Pages.

Дополнительные вопросы

  • Опыт с Allure TestOps?
  • Как масштабируете это решение для больших команд?

Что такое Playwright и чем он отличается от Selenium?

Junior

Playwright — это фреймворк автоматизации браузера от Microsoft. Управляет Chromium, Firefox и WebKit через единое API. Тесты пишут на TypeScript/JavaScript, Python, Java или .NET.

Отличия от Selenium: встроенное авто-ожидание элементов, изоляция тестов через контексты, поддержка emulation мобильных устройств, перехват сети, скриншоты/видео/трассы без плагинов, более быстрый запуск.

Из практики: на новых проектах для веб-автотестов чаще выбирают Playwright — он стабильнее и удобнее. Selenium остаётся в энтерпрайз-проектах с историей и где нужна совместимость со старым WebDriver-сервером.

Частые ошибки

  • Полагаться, что Playwright заменит всю инфраструктуру Selenium-стенда сразу — миграция требует времени.
  • Думать, что Playwright тестирует «реальный» браузер пользователя — это движки, но загруженные в управляемом режиме.

Дополнительные вопросы

  • Почему Playwright стабильнее Selenium в плане flaky-тестов?
  • Какие языки официально поддерживает Playwright?

Как устроена структура проекта Playwright и где лежит конфиг?

Junior

Стандартный проект содержит playwright.config.ts в корне, папку tests/ с тестовыми файлами *.spec.ts, опционально playwright/.auth для сохранённых сессий и фикстуры.

playwright.config.ts задаёт глобальные настройки: testDir, timeout, expect.timeout, retries, projects (наборы запуска по браузерам), reporters, baseURL, use (общие настройки: viewport, headless, video, screenshot, trace).

Из практики: для разных окружений (dev/stage/prod) удобно через переменные окружения подменять baseURL. Под каждый тип запуска (smoke/regress) делают отдельный project с своим testMatch.

Частые ошибки

  • Хранить захардкоженный baseURL в тестах — все тесты прилипают к одной среде.
  • Не задать reporter и долго искать, как смотреть результаты.

Дополнительные вопросы

  • Зачем нужно несколько project в одном конфиге?
  • Что такое testMatch и testIgnore?

Какие способы поиска элементов есть в Playwright и какой предпочтительный?

Junior

page.locator() — основной способ. Внутри можно использовать CSS, XPath, тексты, role. Также есть удобные ярлыки: getByRole, getByText, getByLabel, getByPlaceholder, getByTestId.

Официальная рекомендация: getByRole и getByText. Они отражают то, как пользователь видит интерфейс, и устойчивы к изменениям разметки. getByTestId — компромисс, когда роли недостаточны.

Из практики: если разработчики аккуратно расставляют data-testid, локаторы получаются стабильными и понятными. CSS и XPath остаются для редких случаев, где роль не подходит.

Частые ошибки

  • Жёсткие CSS-цепочки .container > div:nth-child(3) — ломаются при изменении вёрстки.
  • Полагаться на текст без учёта локализации.

Дополнительные вопросы

  • Чем locator отличается от $/$$ из старого API?
  • Что такое strict mode у Locator?

Что такое авто-ожидание в Playwright и как оно работает?

Middle

Перед выполнением каждого действия (click, fill, check) Playwright автоматически ждёт, пока элемент станет видимым, стабильным (без анимации), включённым и пригодным к действию.

Если за timeout (по умолчанию 30 с) условия не выполнены — тест падает с понятной ошибкой. Это резко уменьшает количество явных waitFor в коде.

Из практики: благодаря авто-ожиданию большинство тестов не требует ручных пауз. Если всё-таки нужно — есть locator.waitFor({ state: 'visible' | 'hidden' | 'attached' | 'detached' }).

Частые ошибки

  • Добавлять page.waitForTimeout(2000) — это анти-паттерн, превращающий тесты в flaky.
  • Поднимать timeout вместо разбора причины — маскировка реальной проблемы.

Дополнительные вопросы

  • Чем отличается state: 'visible' и state: 'attached'?
  • Как ждать, пока элемент исчезнет?

Какие ассерты есть у expect в Playwright?

Middle

У expect(locator) есть ретраящиеся проверки: toBeVisible, toBeEnabled, toHaveText, toHaveValue, toHaveCount, toContainText, toHaveAttribute, toHaveURL, toHaveTitle и другие.

Они автоматически повторяются до выполнения условия или истечения таймаута. Это устраняет необходимость в ручных retry-обёртках.

Из практики: всегда предпочитайте ретраящиеся ассерты над «expect(await locator.textContent()).toBe(...)» — последний делает снимок один раз и часто моргает на медленной отрисовке.

Частые ошибки

  • Использовать обычный Jest-стиль expect для интерфейса — потеряете ретраи.
  • Завышать таймаут отдельных ассертов, маскируя реальные проблемы.

Дополнительные вопросы

  • Как сделать кастомный matcher?
  • Чем toHaveText отличается от toContainText?

Что такое fixture в Playwright и для чего она?

Middle

Fixture — это переиспользуемое окружение, которое автоматически создаётся для тестов: страница, авторизованный пользователь, тестовые данные. В Playwright фикстуры объявляют через test.extend.

Каждая фикстура имеет область действия (scope): test (по умолчанию, на тест) или worker (один раз на воркер). Также поддерживается auto: true, чтобы применять без явного запроса.

Из практики: типовые фикстуры — авторизованная страница (loggedInPage), тестовый юзер, базовые данные. Это убирает дублирование beforeEach из тестов.

Частые ошибки

  • Делать тяжёлую фикстуру с scope: 'test' — будет медленно, надо worker.
  • Хранить состояние между тестами в worker-фикстуре, не думая про изоляцию.

Дополнительные вопросы

  • Чем worker-фикстура отличается от test-фикстуры?
  • Как сделать фикстуру с автозапуском?

Что такое trace viewer и зачем он нужен?

Middle

Trace viewer — это инструмент, показывающий пошаговую трассировку теста: каждое действие, снимок DOM на каждом шаге, сетевые запросы, консоль, источник падения.

Включается в конфиге через use.trace: 'on' | 'retain-on-failure' | 'on-first-retry'. Открывается командой npx playwright show-trace trace.zip.

Из практики: retain-on-failure — самый практичный вариант. Тогда трассу видно для упавших тестов, и почти всегда можно понять, где именно сломалось, без перезапуска.

Частые ошибки

  • Включать trace: 'on' для всех тестов в большом проекте — медленно и тяжело хранить.
  • Забывать прикладывать трассу к отчёту CI — теряется главный артефакт для разбора.

Дополнительные вопросы

  • Чем trace viewer отличается от video?
  • Как открыть трассу прямо из CI?

Как запустить тесты в нескольких браузерах одновременно?

Junior

В playwright.config.ts задаются projects, каждый с use.browserName или device. Стандартно — chromium, firefox, webkit. Запуск npx playwright test пройдёт все project параллельно.

Можно ограничить запуск: npx playwright test --project=chromium. Под мобильные устройства используются предустановленные device-профили: { ...devices['iPhone 13'] }.

Из практики: в CI ставят отдельные джобы на каждый браузер, чтобы видеть результаты раздельно. Для smoke-наборов часто достаточно одного chromium.

Частые ошибки

  • Запускать все проекты локально и удивляться долгому прогону.
  • Не учитывать, что WebKit на Linux — это сборка для Linux, а не настоящий Safari.

Дополнительные вопросы

  • Чем browser context отличается от browser?
  • Можно ли в одном тесте использовать два браузера?

Как сохранить и переиспользовать сессию авторизации в Playwright?

Middle

Через storageState: один раз логинятся в global setup, сохраняют состояние (cookies, localStorage) в файл методом context.storageState({ path: 'auth.json' }), а в use.storageState указывают путь к этому файлу.

Все тесты будут стартовать сразу авторизованными, без повторного логина. Можно иметь несколько storageState для разных ролей.

Из практики: даёт большое ускорение прогона. Глобальный setup — это отдельный «тест» (globalSetup), который не отображается в отчёте.

Частые ошибки

  • Не обновлять storageState при изменении схемы авторизации — тесты падают без понятной причины.
  • Хранить storageState с продакшен-токенами в репозитории.

Дополнительные вопросы

  • Как иметь несколько ролей пользователей?
  • Что делать, если токен в storageState протух?

Что такое browser context и как он связан с изоляцией тестов?

Middle

Browser context — это изолированный «профиль» внутри одного браузерного процесса. У каждого свои cookies, localStorage, кеш, разрешения. По сути — лёгкое подобие отдельного браузера.

В Playwright по умолчанию каждый тест получает новый context, что гарантирует чистое состояние без перезапуска браузера. Это и обеспечивает изоляцию, и быстро.

Из практики: чтобы создать «второго пользователя» в том же тесте, открывают новый context через browser.newContext() и в нём page.

Частые ошибки

  • Шарить один context между тестами — наследуете cookies и состояние от предыдущего.
  • Создавать слишком много context, не закрывая — утечка памяти.

Дополнительные вопросы

  • Можно ли иметь два контекста с разными storageState?
  • Чем context.newPage отличается от browser.newPage?

Как перехватывать и подменять сетевые запросы в Playwright?

Middle

page.route(url, handler) перехватывает запросы по шаблону URL. В handler можно: route.continue() — пропустить как есть, route.fulfill({ status, body }) — ответить заранее заданным, route.abort() — отменить.

Это удобно для моков API, эмуляции ошибок (5xx, таймауты), тестирования пограничных сценариев без поднятого бэкенда.

Из практики: для unit-подобных тестов фронта — fulfill. Для проверки реальной интеграции — continue с проверкой запроса. Для отказоустойчивости — abort.

Частые ошибки

  • Не убирать route после теста и видеть моки в следующем тесте.
  • Перехватывать все запросы и пропускать через ручку — медленно и шумно.

Дополнительные вопросы

  • Как ждать конкретный запрос?
  • Чем waitForResponse отличается от route?

Как эмулировать мобильное устройство в Playwright?

Junior

В Playwright есть набор предустановленных профилей в devices: import { devices } from '@playwright/test'. Передают как ...devices['iPhone 13'] в use конкретного project.

Это задаёт viewport, userAgent, deviceScaleFactor, isMobile, hasTouch и другое. Получается полноценный эмулированный мобильный браузер.

Из практики: для проверки адаптива и mobile-only сценариев. Это не замена тестов на реальных устройствах — они нужны для проверки поведения железа и нативных компонентов.

Частые ошибки

  • Считать, что эмуляция = тестирование на устройстве.
  • Забыть про hasTouch и эмулировать клик вместо тапа.

Дополнительные вопросы

  • Чем эмуляция Playwright отличается от Appium?
  • Можно ли смешать desktop и mobile project в одном конфиге?

Как делать скриншоты и видео в Playwright?

Junior

В конфиге use можно задать screenshot: 'only-on-failure' | 'on' | 'off' и video: 'retain-on-failure' | 'on' | 'off'. Артефакты попадают в test-results.

В коде вручную: page.screenshot({ path: 'shot.png', fullPage: true }) и expect(page).toHaveScreenshot('homepage.png') для визуального сравнения.

Из практики: only-on-failure / retain-on-failure — оптимальный баланс между отладочной информацией и размером артефактов. Полные скриншоты страниц помогают в репортах.

Частые ошибки

  • Хранить миллионы скриншотов в репозитории — лучше CI-артефакты.
  • Полагаться на screenshot для визуального тестирования без специальной библиотеки — динамика и шрифты ломают сравнение.

Дополнительные вопросы

  • Что такое visual regression и как его сделать на Playwright?
  • Как замаскировать динамические области на скриншоте?

Как тестировать API через Playwright без браузера?

Middle

У Playwright есть APIRequestContext (request fixture). Делает HTTP-запросы напрямую: const res = await request.post('/api/login', { data: {...} }).

Удобно соединять с UI-тестами: подготовить данные через API, потом проверить интерфейс. Также можно писать чистые API-тесты в том же проекте, что и UI.

Из практики: подготовка тестовых данных через API сильно ускоряет тесты — не нужно прокликивать формы. Также удобно для smoke API в одном репозитории.

Частые ошибки

  • Смешивать request и page контексты, ожидая общих cookies без storageState.
  • Делать тяжёлую подготовку данных в каждом тесте, когда хватит worker-фикстуры.

Дополнительные вопросы

  • Как использовать общий API клиент для подготовки и проверки?
  • Чем request лучше fetch внутри теста?

Что такое retries и flaky-тесты в Playwright?

Middle

Retries — это количество повторов упавшего теста перед окончательным фейлом. Задаётся в конфиге: retries: 2 — будет до трёх попыток.

Тест, упавший один раз и прошедший после повтора, помечается flaky. В отчёте видно общее количество flaky — это сигнал, что в тестах есть нестабильность, которую стоит чинить.

Из практики: retries полезны в CI для смягчения сетевых дёрганий. Локально часто оставляют 0, чтобы видеть проблему сразу. Постоянные flaky — это технический долг, а не повод увеличивать retries.

Частые ошибки

  • Лечить flaky увеличением retries — проблема прячется, но накапливается.
  • Не различать настоящий продуктовый баг и flaky — пользователю всё равно одинаково плохо.

Дополнительные вопросы

  • Где смотреть статистику flaky-тестов?
  • Что делать с тестом, который flaky только в CI?

Что такое codegen и как его использовать?

Junior

Playwright codegen — это инструмент, который записывает действия в браузере и генерирует код теста. Запускается npx playwright codegen https://example.com.

Удобно для быстрого старта: открыть страницу, поклацать, получить готовый скрипт. Locators codegen старается выбирать осознанно (getByRole, getByText).

Из практики: используют для черновика теста, который потом доводят руками. Слепое использование codegen даёт фрагильные тесты, поэтому полученный код всегда стоит переписать в стиле проекта.

Частые ошибки

  • Сохранять сгенерированный код один-в-один без рефакторинга — будут хрупкие селекторы.
  • Использовать codegen как «полный тест» вместо подсказки.

Дополнительные вопросы

  • Можно ли codegen использовать с авторизованной сессией?
  • Как codegen выбирает локатор?

Как организовать Page Object Model в Playwright?

Middle

POM — это класс на страницу с локаторами в конструкторе и методами действий: class LoginPage { readonly emailInput; constructor(page) { this.emailInput = page.getByLabel('Email'); } async login(email, password) {...} }.

В тестах: const loginPage = new LoginPage(page); await loginPage.login(...). Это убирает дублирование, делает рефакторинг безопасным и читаемым.

Из практики: страницы со сложной логикой выносят в POM. Для простых форм иногда хватает функций. Большинство команд использует гибрид: POM для основных экранов плюс утилитные функции.

Частые ошибки

  • Раздувать POM до анемичных классов с сотнями локаторов.
  • Прятать в POM логику ассертов — лучше держать ассерты в тестах.

Дополнительные вопросы

  • Что такое Component Object Model?
  • Где хранить тестовые данные при использовании POM?

Как параметризовать тест данными в Playwright?

Middle

Самый простой способ — обычный цикл for/forEach по массиву данных, создающий test() для каждого случая: for (const tc of cases) test(`login ${tc.name}`, async ({ page }) => { ... }).

Также можно сделать собственную фикстуру test.extend, принимающую параметры через test.use({...}).

Из практики: для проверки одной логики на разных данных — for-цикл с информативным именем. Не используйте динамический test внутри test — это запрещено.

Частые ошибки

  • Создавать test внутри другого test — Playwright бросит ошибку.
  • Имя теста, не отражающее данные — в отчёте сложно понять, что упало.

Дополнительные вопросы

  • Как использовать одни и те же данные с разными user-ролями?
  • Чем хорош data-driven подход и где он плох?

Что такое global setup и global teardown в Playwright?

Middle

globalSetup — это файл с функцией, запускающейся один раз перед всеми тестами (после загрузки конфига). Подходит для общей подготовки: логин, прогрев кеша, миграции, создание тестовых пользователей.

globalTeardown — симметрично, после всех тестов. Часто чистит созданные ресурсы.

Из практики: типичный сценарий — globalSetup логинится и сохраняет storageState. Тесты потом стартуют уже авторизованными. Также сюда удобно класть seed данных через API.

Частые ошибки

  • Делать в globalSetup долгую работу, которая может упасть и сломать весь прогон.
  • Забывать чистить ресурсы в teardown и засорять окружение.

Дополнительные вопросы

  • Чем globalSetup отличается от worker-фикстуры?
  • Можно ли иметь несколько globalSetup?

Как написать тест на shadow DOM в Playwright?

Middle

Playwright прозрачно проходит через open shadow DOM при использовании getByRole, getByText и текстовых селекторов. Для CSS-цепочек тоже работает, в отличие от классического Selenium.

Если shadow root закрытый, доступ из JS невозможен — поможет только evaluate с прямым доступом к компонентам.

Из практики: большинство Web Components с открытым shadow DOM тестируется без специальных приёмов. Главное — выбирать локаторы по ролям и текстам, а не по сложным CSS.

Частые ошибки

  • Использовать XPath, который не пробивает shadow DOM, и удивляться, что элемент не находится.
  • Полагаться на ::shadow и >>> синтаксис, который в современных движках не везде работает.

Дополнительные вопросы

  • Чем open shadow DOM отличается от closed?
  • Как тестировать iframe в Playwright?

Как тестировать iframe в Playwright?

Middle

Получают FrameLocator: page.frameLocator('iframe[name="checkout"]'). Далее frame.locator(...) ведёт себя как обычный page.locator, но внутри указанного iframe.

Альтернатива — page.frame({ name: 'checkout' }) возвращает объект Frame с тем же API, что у Page.

Из практики: для платёжных виджетов, чатов, embed-форм iframe — обычная история. FrameLocator + getByRole внутри даёт стабильные тесты.

Частые ошибки

  • Искать элементы iframe прямо в page.locator — они не найдутся.
  • Полагаться на индекс frame() — он может меняться.

Дополнительные вопросы

  • Чем frameLocator отличается от frame()?
  • Как дождаться, что iframe загрузился?

Как загружать файл и скачивать файл в Playwright?

Middle

Загрузка: page.locator('input[type="file"]').setInputFiles('path/to/file.pdf') — поддерживает массив для нескольких файлов и Buffer для контента в памяти.

Скачивание: const downloadPromise = page.waitForEvent('download'); await page.click('text=Download'); const download = await downloadPromise; await download.saveAs('out.pdf');

Из практики: для setInputFiles не нужно симулировать клик по input — Playwright под капотом работает с DOM API. Для нестандартных drag-and-drop загрузчиков может понадобиться DataTransfer вручную.

Частые ошибки

  • Делать click и ждать диалог — Playwright обрабатывает downloads автоматически.
  • Передавать относительный путь, который не существует относительно процесса теста.

Дополнительные вопросы

  • Как загрузить файл через drag-and-drop?
  • Где хранить скачанные файлы?

Какие репортеры есть у Playwright?

Junior

Встроенные: list (живой вывод в консоль), line (компактный), dot (точки), json, junit, html (интерактивный отчёт со скриншотами и трассами). Можно подключать несколько одновременно.

В конфиге: reporter: [['list'], ['html', { open: 'never' }]]. Открыть HTML-отчёт: npx playwright show-report.

Из практики: list/line — для локального запуска. html — для разбора падений (его сохраняют в CI как артефакт). junit — для интеграции с системами вроде GitLab CI / Jenkins.

Частые ошибки

  • Использовать только dot-репортер в CI — теряется отладочная информация.
  • Не настроить путь к отчёту и затирать его при повторных прогонах.

Дополнительные вопросы

  • Что такое Allure-репортер и зачем его подключают?
  • Как сделать кастомный репортер?

Как настроить Playwright в CI (GitHub Actions, GitLab CI)?

Middle

Стандартный рецепт: установить зависимости (npm ci), установить браузеры (npx playwright install --with-deps), запустить тесты (npx playwright test), загрузить html-отчёт и trace как артефакты.

Отдельный GitHub-action не нужен — актуальный гайд Playwright рекомендует именно npm ci + npx playwright install --with-deps (старый microsoft/playwright-github-action заброшен). Как альтернатива — официальный Docker-образ mcr.microsoft.com/playwright, где браузеры и системные зависимости уже предустановлены.

Из практики: с Docker-образом сборка кешируется, а с install --with-deps на чистом раннере нужно дождаться установки системных зависимостей. В CI обычно включают video: retain-on-failure и trace: retain-on-failure.

Частые ошибки

  • Забывать npx playwright install — браузеры не подтянутся.
  • Не сохранять артефакты — упавший тест разобрать почти невозможно.

Дополнительные вопросы

  • Как параллелить прогон по нескольким раннерам?
  • Что такое sharding в Playwright?

Что такое sharding в Playwright и для чего он?

Middle

Sharding — это разделение тестов на несколько частей (shard) и параллельный прогон каждой части на отдельной машине/контейнере. Запуск: npx playwright test --shard=1/4.

Playwright сам делит тесты примерно поровну. После прогона можно объединить отчёты blob-репортов в один общий HTML-отчёт.

Из практики: даёт почти линейное ускорение прогона больших наборов. В GitHub Actions удобно через матрицу: shard 1..N как отдельные джобы, потом merge-отчётов в финальной.

Частые ошибки

  • Полагаться, что shard поровну разделит время — иногда один shard сильно дольше из-за тяжёлых тестов.
  • Не объединять отчёты и иметь N разрозненных HTML.

Дополнительные вопросы

  • Чем sharding отличается от worker-параллелизма внутри одного процесса?
  • Как объединить blob-репорты?

Что такое Playwright fixtures с базовым URL?

Middle

В playwright.config.ts use.baseURL = 'http://localhost:3000' задаёт корневой адрес. После этого page.goto('/login') автоматически добавит baseURL.

Это позволяет менять окружение через env-переменную без правки тестов.

Из практики: всегда настраивайте baseURL — тесты становятся переносимыми между dev/staging/prod.

Частые ошибки

  • Хардкодить URL в каждом тесте.
  • Забывать про разные baseURL для разных projects.

Дополнительные вопросы

  • Чем page.goto отличается от page.goto с абсолютным URL?
  • Как использовать переменные окружения?

Как работать с диалогами alert/confirm/prompt в Playwright?

Middle

В Playwright диалоги обрабатываются через event dialog: page.on('dialog', async dialog => { await dialog.accept(); }). Регистрируют до действия, вызывающего диалог.

Можно прочитать тип (dialog.type()), сообщение (dialog.message()), значение по умолчанию (dialog.defaultValue()).

Из практики: для confirm нужно решить — accept или dismiss. Для prompt можно передать ввод: dialog.accept('значение').

Частые ошибки

  • Не регистрировать обработчик заранее — диалог зависнет.
  • Забыть снять обработчик после теста.

Дополнительные вопросы

  • Чем dialog отличается от page.evaluate(window.alert)?
  • Как обработать несколько диалогов подряд?

Что такое page.waitForResponse и waitForRequest?

Middle

waitForResponse(url) ждёт, пока сервер вернёт ответ на URL, соответствующий шаблону. Полезно при асинхронных действиях, где результат приходит не сразу.

waitForRequest симметрично ждёт отправки запроса. Применяется реже — обычно интересует именно ответ.

Из практики: используйте, когда UI обновляется после API-вызова — дожидайтесь конкретного response, не sleep.

Частые ошибки

  • Запускать waitForResponse после действия — может пропустить.
  • Использовать слишком широкий шаблон URL — поймает не тот запрос.

Дополнительные вопросы

  • Чем waitForResponse отличается от route?
  • Как ждать запрос с определённым статусом?

Как тестировать многооконные сценарии?

Middle

Новое окно открывается через context.waitForEvent('page'): const newPagePromise = context.waitForEvent('page'); await page.click('a[target=_blank]'); const newPage = await newPagePromise.

После этого newPage — обычный Page, с которым можно работать как с основным.

Из практики: типовой сценарий — попап с OAuth, новая вкладка с условиями. Важно не забыть закрыть после теста.

Частые ошибки

  • Полагаться на context.pages() без waitForEvent — могут не успеть открыться.
  • Не закрывать окна — утечка.

Дополнительные вопросы

  • Чем page отличается от popup?
  • Как обработать множество окон?

Что такое test.step и зачем он?

Middle

test.step('название', async () => { ... }) — группирует действия в логический шаг. В Trace Viewer и HTML-отчёте они видны как отдельные шаги.

Полезно для длинных сценариев — отчёт становится самодокументируемым.

Из практики: BDD-стиль тестов через step делает их понятными даже не-инженерам, которые читают отчёт.

Частые ошибки

  • Делать слишком много мелких шагов — шум в отчёте.
  • Прятать важные ассерты внутри step без описания.

Дополнительные вопросы

  • Чем step отличается от Allure step?
  • Можно ли вкладывать step?

Как работать с date pickers в Playwright?

Middle

Если поле — обычный input[type=date], то fill('2025-01-15'). Если кастомный — кликают по календарю как обычно, через getByRole/getByText('15').

Также можно установить значение напрямую через evaluate: page.locator('#date').evaluate(el => el.value = '2025-01-15').

Из практики: предпочтительно через UI — это ближе к пользовательскому пути. Прямой ввод — для ускорения, когда календарь сложный.

Частые ошибки

  • Полагать, что fill всегда работает для date — может не пройти валидацию.
  • Игнорировать формат локали (MM/DD vs DD/MM).

Дополнительные вопросы

  • Как кликать по конкретной дате в month-grid?
  • Что такое keyboard shortcut для даты?

Что такое visual regression testing в Playwright?

Middle

expect(page).toHaveScreenshot('home.png') сравнивает текущий скриншот с эталонным (хранится рядом с тестом). При первом запуске эталон создаётся.

Можно задать threshold (порог совпадения) и mask (зоны, исключаемые из сравнения — например, дата/счётчик).

Из практики: визуальные тесты ловят регрессии вёрстки. Но они хрупкие — шрифты, анимации, рендеринг отличаются между ОС. Эталоны нужно хранить под каждую ОС или замораживать рендеринг.

Частые ошибки

  • Хранить эталоны под одну ОС и запускать в CI под другой — все падают.
  • Не использовать mask для динамических зон.

Дополнительные вопросы

  • Что такое toHaveScreenshot threshold?
  • Чем Playwright VR отличается от Percy?

Как настроить таймауты в Playwright?

Middle

В конфиге: timeout (общий на тест), expect.timeout (на ассерты), use.actionTimeout, use.navigationTimeout. По умолчанию — 30 секунд на тест, 5 секунд на ассерт.

В коде можно переопределить: test.setTimeout(60000), expect(...).toHaveText('x', { timeout: 10000 }).

Из практики: не повышайте таймауты, чтобы скрыть проблемы. Сначала разберитесь, почему действие медленное.

Частые ошибки

  • Глобально поднять timeout до 5 минут — тесты тормозят в CI.
  • Не различать action и assertion timeout.

Дополнительные вопросы

  • Что такое navigationTimeout?
  • Где задавать таймауты — глобально или в тесте?

Как настроить параллелизм workers в Playwright?

Middle

В конфиге: workers: 4 — четыре теста параллельно. По умолчанию Playwright берёт примерно половину логических ядер CPU. В CI часто фиксируют workers: 1 или 2 для стабильности.

Параллелизация — на уровне тестов (файлов); внутри одного теста всё последовательно.

Из практики: больше workers — быстрее прогон, но больше нагрузки на тестовую среду. Найдите баланс — где БД/сервер не упирается.

Частые ошибки

  • Параллелить тесты, которые делят shared state.
  • Включать максимум workers в CI без понимания ресурсов раннера.

Дополнительные вопросы

  • Чем worker отличается от shard?
  • Как сделать тесты независимыми для параллелизма?

Что такое test.fixme и test.skip?

Junior

test.skip — пропустить тест безусловно. test.fixme — то же, но семантически означает «тест нерабочий, нужно починить».

В отчётах различимы. Помогает командам отслеживать, какие тесты сейчас не работают и почему.

Из практики: всегда добавляйте комментарий с причиной и тикетом. Без него быстро забывают, почему пропустили.

Частые ошибки

  • Использовать skip без объяснения и тикета.
  • Использовать fixme как permanent skip.

Дополнительные вопросы

  • Чем skip отличается от fixme?
  • Что делать с долгими skipped-тестами?

Что такое Allure Report и какие фичи?

Middle

Allure — фреймворк для красивых отчётов автотестов. Интегрируется с JUnit, TestNG, pytest, Cypress, Playwright и многими другими.

Фичи: шаги теста, скриншоты, видео, attachments, история, trend по запускам, разбивка по features/epics.

Из практики: для команды, регулярно смотрящей отчёты, Allure сильно удобнее, чем встроенные HTML-репортеры.

Частые ошибки

  • Не интегрировать с CI и иметь Allure только локально.
  • Не настраивать step listeners — отчёт без шагов.

Дополнительные вопросы

  • Что такое allure-results?
  • Чем Allure TestOps отличается от обычного Allure?