Суть урока
Представь что нанял тестировщика который работает со скоростью компьютера: за 30 секунд проверяет 50 форм, кликает по каждой кнопке, заполняет поля, проверяет что появляется правильное сообщение — и делает это одинаково каждый раз. Playwright (Плэйрайт — библиотека автоматизации браузера от Microsoft) + Claude Code — это этот тестировщик. Ты наблюдаешь как он работает, замечаешь проблемы, говоришь ему исправить — и он улучшается на глазах.
Термины урока: API (эй-пи-ай — интерфейс программирования), headless (хедлесс — без графического интерфейса), CI/CD (Continuous Integration/Delivery — автоматическая сборка и доставка), deploy (деплой — развёртывание), workflow (воркфлоу — рабочий процесс).
Ключевые концепции
- Claude Code управляет браузером: клики, ввод, скрейпинг, скриншоты
- Playwright: headed (хэдед — браузер с видимым окном) vs headless (хэдлесс — браузер без окна, только в фоне) режимы
- Живой пример: QA (Quality Assurance — контроль качества) тест многостраничной формы с итерацией
- Параллельные браузеры для ускорения
- Аутентифицированный браузер через профиль Chrome
Теория
Что умеет делать Claude Code с браузером
Claude Code через Playwright может управлять браузером программно:
- Навигация: открыть URL, перейти назад/вперёд, обновить страницу
- Взаимодействие: кликнуть на элемент, ввести текст, выбрать из dropdown, загрузить файл
- Скрейпинг: извлечь текст, таблицы, изображения, метаданные
- Скриншоты: сделать скриншот всей страницы или конкретного элемента
- Ожидание: ждать пока элемент появится, исчезнет, изменится
- Перехват запросов: перехватить и модифицировать API (эй-пи-ай — интерфейс программирования) запросы
Playwright — это полноценное управление браузером из кода. Есть и второй путь, без собственного скрипта: расширение Claude in Chrome (подробнее ниже).
Второй путь: Claude in Chrome
Claude Code умеет работать с твоим браузером через расширение Claude in Chrome. Скрипт писать не нужно: описываешь задачу словами, Claude открывает вкладки, кликает, читает консоль и скриншоты.
claude --chromeКоманда /chrome в сессии показывает статус подключения и настройки разрешений. Что нужно: Google Chrome или Microsoft Edge (другие браузеры на Chromium тоже определяются), актуальная версия расширения Claude in Chrome, платный тариф Anthropic (Pro, Max, Team или Enterprise) и вход через /login. По API-ключу интеграция не включается. В WSL не поддерживается.
Тонкости:
- Claude использует твою авторизацию в браузере, поэтому может открыть любой сайт, где ты уже вошёл. Это удобно и опасно одновременно: см. урок Разрешения и безопасность.
- Если встречается страница входа или капча, Claude останавливается и просит тебя сделать это руками. Обходить капчу автоматикой не нужно и не получится.
- Когда нужен именно повторяемый тест, который запускается на сервере без экрана, пиши Playwright-скрипт: он быстрее и не привязан к твоему браузеру.
- Расширение Claude in Chrome вышло из беты; актуальные требования смотри в документации и на странице Актуальное сейчас.
Headed vs Headless
Headed режим (браузер виден на экране):
browser = playwright.chromium.launch(headless=False)- Видишь каждое действие в реальном времени
- Можешь вмешаться если что-то идёт не так
- Идеален для разработки и отладки
- Медленнее (рендерит интерфейс)
Headless режим (браузер в фоне):
browser = playwright.chromium.launch(headless=True)- Браузер не виден — работает в фоне
- Быстрее (нет рендеринга)
- Идеален для продакшена и CI/CD
- Можно запускать на сервере без экрана
Золотое правило:
- Разработка → headed (смотришь что происходит, отлаживаешь)
- Деплой (развёртывание) → headless (скорость, нет экрана на сервере)
Сценарии применения
QA автоматизация: Тестировать каждую форму, каждую кнопку, каждый сценарий пользователя. Один раз написал тест — запускаешь сотни раз. Нашёл регрессию (откат к старой ошибке) до того как пользователи нашли.
Веб-скрейпинг: Собирать данные с сайтов которые используют JavaScript (язык программирования для веб-страниц, динамический контент). Простой HTTP (HyperText Transfer Protocol — протокол передачи данных) запрос не сработает — нужно дождаться загрузки DOM (Document Object Model — структура страницы). Playwright ждёт автоматически.
Автоматизация действий: Заполнять формы, постить контент, взаимодействовать с веб-приложениями как пользователь. Например: автоматически постить статьи в блог-платформу по расписанию (cron — крон — планировщик задач по расписанию).
Визуальное тестирование: Делать скриншоты каждой страницы и сравнивать с эталоном. Если пиксели изменились — значит что-то сломалось визуально.
Живой пример: QA тест многостраничной формы
Представь: у тебя 5-страничная форма заявки на кредит. Нужно убедиться что:
- Каждая страница загружается без ошибок
- Валидация работает правильно (нельзя перейти дальше с пустым полем)
- Прогресс-бар показывает правильный процент
- Финальная страница показывает правильный summary
Шаг 1: Claude Code пишет Playwright скрипт
from playwright.sync_api import sync_playwright
def test_loan_application_form():
with sync_playwright() as p:
# Headed режим для разработки
browser = p.chromium.launch(headless=False)
page = browser.new_page()
# Страница 1: Личные данные
page.goto("https://myapp.com/apply")
page.fill("#first-name", "Иван")
page.fill("#last-name", "Петров")
page.fill("#email", "ivan@example.com")
page.click("#next-button")
# Проверяем что перешли на страницу 2
page.wait_for_url("**/apply/step-2")
assert page.locator(".progress-bar").get_attribute("value") == "40"
# Страница 2: Финансы
page.fill("#monthly-income", "150000")
page.fill("#loan-amount", "500000")
page.click("#next-button")
# ... и т.д.Шаг 2: Запуск и наблюдение
Открывается Chrome. Видишь как автоматически:
- Вводится текст в поля
- Кликается кнопка "Далее"
- Переходит на следующую страницу
Шаг 3: Обнаружена проблема
Наблюдаешь: кнопка "Далее" кликается дважды при быстром выполнении. Это создаёт двойной submit.
Ошибка в тесте: Expected URL: /apply/step-2 Actual URL: /apply/step-3 # Перепрыгнул страницу!
Шаг 4: Останавливаем и исправляем
Говоришь Claude Code: "Кнопка клика выполняется дважды, страница 2 пропускается. Исправь: добавь wait_for_load_state после клика, убедись что следующая страница загрузилась перед следующим действием."
Claude Code исправляет скрипт:
page.click("#next-button")
page.wait_for_load_state("networkidle") # Ждём полной загрузки
page.wait_for_url("**/apply/step-2") # Убеждаемся в правильном URLШаг 5: Снова запускаем
Теперь работает корректно. Тест проходит все 5 страниц.
Петля разработки:
Строим тест → Запускаем → Видим проблему → Исправляем → Запускаем сноваЭта петля повторяется 5-10 раз пока тест не будет надёжно проходить.
Параллельные браузеры
Запуск одного браузера тестирует один сценарий. Параллельный запуск — несколько сценариев одновременно:
from playwright.sync_api import sync_playwright
import concurrent.futures
test_cases = [
{"user": "иван_петров", "loan": "500000"},
{"user": "мария_сидорова", "loan": "1000000"},
{"user": "алексей_козлов", "loan": "250000"},
]
def run_test(test_case):
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
# ... тест для конкретного случая
with concurrent.futures.ThreadPoolExecutor(max_workers=3) as executor:
results = executor.map(run_test, test_cases)Три браузера работают параллельно — тестирование в 3x быстрее.
Аутентифицированный браузер
Проблема: хочешь автоматизировать Gmail, или любой сайт требующий авторизации. Playwright в headless режиме — не авторизован.
Решение: использовать профиль Chrome с сохранёнными сессиями. Лучше создать для этого отдельный профиль (а не основной): робот получит доступ только к тому, что ты в этом профиле открыл:
browser = playwright.chromium.launch_persistent_context(
user_data_dir="/Users/yourname/Library/Application Support/Google/Chrome/Default",
headless=False,
channel="chrome"
)Playwright открывает Chrome с сохранёнными в профиле сессиями и cookies — автоматизация работает с аутентифицированным браузером. Современные версии Chrome могут отказаться запускать автоматизацию на основном профиле по умолчанию, поэтому отдельный профиль работает надёжнее.
Применение:
- Проверка собственного кабинета или админки сайта
- Выгрузка данных из своих разделов сайтов
- Автоматизация SaaS инструментов без API
Важно: используй только для своих аккаунтов. Автоматизация чужих аккаунтов — нарушение ToS сервисов. Многие платформы (соцсети, LinkedIn и другие) запрещают автоматизацию действий и в твоём собственном аккаунте: прочитай условия сервиса, иначе рискуешь блокировкой. Не давай автоматизации больше доступа, чем нужно для задачи: сессия, где ты залогинен везде, — лакомая цель для prompt injection (см. защита от prompt injection).
Живая итерация: как работает процесс
Пример процесса: проверка собственного интернет-магазина.
Итерация 1:
Задача: каждое утро проверять, что на 50 карточках товаров работает кнопка "В корзину"
Запускаем → браузер открывается → открываем карточку → нажимаем кнопку
Проблема: "клик по кнопке выполняется дважды"
(в корзину попадает два товара)
Исправление: дождаться, пока кнопка станет активной, и кликать один раз
---
Итерация 2:
Запускаем → клики работают → проходим карточки одну за другой
Проблема: "через 20 карточек сервер отвечает ошибкой 429 (слишком много запросов)"
Исправление: добавить паузы между карточками (1-3 секунды),
проверять не все 50 подряд, а по 10 с перерывом,
говорить с собственным сервером вежливо
---
Итерация 3:
Запускаем → работает стабильно → 50 карточек за прогон без ошибок
Запускаем по расписанию: раз в день, результат — отчёт на почтуКаждая итерация решает конкретную проблему обнаруженную в предыдущем запуске.
⚠️ Автоматизировать чужие сервисы так, чтобы обойти защиту (капчу, лимиты запросов), нельзя: это нарушает условия сервисов и может привести к блокировке аккаунта. Тренируйся на собственных сайтах и тестовых стендах.
Чего избегать при автоматизации браузера
Агрессивность: слишком быстрые действия → сервер ограничивает запросы или блокирует. Добавляй паузы, уважай robots.txt и условия сервиса.
Отсутствие ожиданий: click() без wait_for_element() → клик на элемент который ещё не загрузился → ошибка. Всегда жди элемент перед взаимодействием.
Hardcoded селекторы: #submit-btn-v2 → сайт обновился → селектор сломался. Используй семантические селекторы: button[type="submit"], role=button name="Отправить".
Отсутствие retry: сеть нестабильна → один запрос упал → весь тест упал. Добавляй retry для нестабильных операций.
Практика
Задание: Написать QA тест для публичной формы
- Выбери публичный сайт с формой (например: форма регистрации на любом сервисе, форма обратной связи)
- Попроси Claude Code установить Playwright:
pip install playwright && playwright install chromium - Опиши тест: "напиши Playwright тест для формы регистрации на [URL]. Тест должен проверить: все поля заполняются, валидация работает (пустое поле блокирует отправку), успешная регистрация показывает подтверждение"
- Запусти в headed режиме — наблюдай за браузером
- Найди хотя бы одну проблему (реальную или намеренно введи неверные данные) — попроси исправить
- После успешного прогона: переключи на headless режим, убедись что работает
- Бонус: добавь параллельный запуск двух браузеров с разными тестовыми данными
Сравнение инструментов автоматизации браузера
| Критерий | Playwright | Puppeteer | Selenium |
|---|---|---|---|
| Языки | Python, JS, Java, C# | JavaScript/TypeScript | Python, JS, Java, C#, Ruby |
| Браузеры | Chromium, Firefox, WebKit | Chromium (Firefox beta) | Все основные |
| Скорость | Быстрый | Быстрый | Медленнее |
| Автоматическое ожидание | Да (встроено) | Частично | Нет (нужно вручную) |
| Параллельные контексты | Да (browser contexts) | Да (incognito) | Через Grid |
| Codegen (запись действий) | Да | Нет | IDE-плагины |
| Поддержка мобильных устройств | Эмуляция | Эмуляция | Реальные устройства |
| Лучше всего для | Современные проекты, QA | Лёгкие скрипты Chrome | Legacy проекты, Selenium Grid |
Рекомендация: для новых проектов начинай с Playwright — лучший баланс скорости, документации и возможностей.
Частые ошибки
1. Не ждать динамический контент
# ❌ Неправильно — элемент может ещё не загрузиться
page.click("#dynamic-button")
# ✅ Правильно — ждём пока элемент появится
page.wait_for_selector("#dynamic-button")
page.click("#dynamic-button")2. Не использовать headed режим при отладке Если тест падает — переключись на headless=False и НАБЛЮДАЙ что происходит. Большинство проблем становятся очевидны визуально.
3. Хардкодить XPath вместо семантических селекторов
# ❌ Хрупкий — сломается при любом изменении вёрстки
page.click("//div[3]/div[2]/button[1]")
# ✅ Устойчивый — не зависит от положения в DOM
page.click("button:has-text('Отправить')")
page.get_by_role("button", name="Отправить").click()4. Не обрабатывать таймауты Сеть может быть медленной. Всегда устанавливай разумный timeout и обрабатывай его.
5. Запускать тесты без retry для нестабильных элементов Добавляй expect(locator).to_be_visible(timeout=10000) перед взаимодействием с элементами которые загружаются асинхронно.
Инструменты и ресурсы
- Claude in Chrome — расширение для работы Claude Code с твоим браузером:
claude --chrome— документация - Playwright —
pip install playwright— библиотека автоматизации браузера — playwright.dev - Playwright Python docs — playwright.dev/python
- Puppeteer (альтернатива для Chrome) — pptr.dev
- Selenium (legacy альтернатива) — selenium.dev
- playwright install — установка браузеров: chromium, firefox, webkit
- Playwright Inspector —
PWDEBUG=1 python test.py— визуальный отладчик - Playwright Codegen —
playwright codegen https://example.com— запись действий и генерация кода - Playwright Trace Viewer — просмотр записи выполнения теста пошагово
Ключевые выводы
Headed режим для разработки — видишь что происходит и можешь поймать баг. Headless для продакшена — быстро и работает на сервере без экрана.
Петля "строим → тестируем → видим → исправляем → тестируем снова" — это норма. 5-10 итераций для стабильного теста — хороший результат.
Аутентифицированный браузер через профиль Chrome = автоматизация всего к чему у тебя есть доступ, без борьбы с OAuth и 2FA.
Связанные уроки
- Computer Use: управление нативными приложениями (когда Playwright не подходит — нужна автоматизация десктопных приложений)
- Сайты и веб-приложения: Playwright идеален для тестирования сайтов, которые ты создал по этому уроку
Что дальше
→ Разрешения и безопасность: как безопасно давать агенту доступ
Отметка хранится только в этом браузере и никуда не отправляется. Мой прогресс