В современном мире мало уметь хорошо работать только с одним инструментом/стеком, нужна широкая экспертиза в современных тулах. Вы можете быть 10+ лет опыта синьор AQA на селениуме, но когда придет пора искать новую работу — обнаружится пробел в навыках, который второпях не очень‑то и закрывается. Поэтому необходимо постоянно быть в курсе и изучать новые и давно зарекомендовавшие себя инструменты и подходы.
На момент написания статьи Playwright в топе востребованных фреймворков для QA на европейском рынке. Готовясь к собеседованиям, я захотел попрактиковаться на стенде, который ведет себя как настоящий продукт, и быстро понял, что выбор невелик. Хорошие курсы платные. Бесплатные тренажёры есть, но задачи там простые. Самый простой и распространенный подход — открываешь доку, любой сайт и вперед, экспериментировать. Но это работает больше как песочница, без плана и структуры.
Проблемы этих подходов:
Курсы стоят денег. А учиться должны иметь возможность все.
Документация+любой сайт = нет структуры. Человеку для обучения нужен прогресс и повышение сложности.
В бесплатных тренажерах довольно простые экраны и тривиальные задачи. В работе часто сталкиваешься с челленджами. Надо уметь их решать.
Так появился playwright‑chat‑lab. Чат‑приложение для практики e2e тестирования, которое умеет ломать ваши тесты. Если опыта с playwright совсем нет, то в проекте есть курс, который учит писать тесты на предсказуемом приложении, потом Hard Mode включает в нём то, что ломает тесты в реальных проектах, а Flake Score показывает, переживает ли тест эти условия. Настройка приложения и тесты фреймворка — все в одном репо. Заодно и React подучить можно.

Приложение
В мессенджерах люди проводят больше всего времени, поэтому интерфейс знаком каждому. Экранов пять:
Chat — переписка с индикатором загрузки и кнопкой сброса;
Search — поиск по локальной истории;
Message history — история по дням;
Playground — виджеты: фото, видеоплеер, календарь, фильтр, слайдер, модалка, drag‑and‑drop;
Help — вопросы в раскрывающихся блоках.
Под капотом нет ни бэкенда, ни LLM, эти варианты стоят денег, а хочется, чтобы проект оставался бесплатным. Зато все ответы бота заранее известны — удобно для тестов легкого уровня. По умолчанию включён Funny mode: шуточные ответы берутся из таблицы A‑Z по первой букве сообщения. Для фанатов третьего эпизода «Звездных войн» есть пасхалка: напишите в чат «Hello there!». Не фанат? Всё равно напишите — заодно протестируете UI элемент.

Встроенный помощник
Чат умеет объяснять собственное устройство: «Как работает сброс?», «Что такое Funny mode?». Он отвечает только на сообщения с вопросительным знаком. Над полем ввода есть саджест «Help» со списком таких вопросов.
Курс
11 уроков с растущей сложностью, в которых вы познакомитесь с локаторами, ассертами, ожиданиями, виджетами, хуками, фикстурами, Page Object Model, CI и параллелизацией. Все лежит в /lessons
У каждого урока есть README.md с теорией, demo.spec.ts с примером и homework.spec.ts с заданием, закрытым test.fixme(). Всего — 68 тестов.
Hard Mode: приложение, которое сопротивляется
Ну а теперь самое интересное: приближаем автоматизацию тестирования к реалиям продукта и тестовых сред.
Для любого инженера одна из самых сильных головных болей — работа с flaky тестами. Напомню, что это тесты, которые и проходят и фейлятся без изменения в коде. А больные они потому, что flakiness приходит из большого числа источников. Нестабильная среда, выскакивающие попапы, изменяющиеся тестовые данные, ну или просто наконец неидеальность самого продукта.
Hard mode возводит все это в абсолют. При включении этого режима вы вправе выбрать то, чем будет «болеть» приложение сегодня: блокирующие попапы, медленные ответы чат‑бота, кнопки закрытия, появляющиеся по таймауту. На данный момент всего 15 флагов, которые также входят в наборы: bad‑network — нестабильный интернет и перегруженный бэкенд или tricky‑dom — фронтенд с надоедливыми попапами.
Да и в целом можно не ходить вокруг да около и включить сразу все. Удачи, она вам пригодится.

Flake Score: одного зелёного прогона мало
Вся случайность в Hard Mode считается из сида — числа от 1 до 10. Флаги решают, какие проблемы включены, а сид задаёт числа внутри них: сколько идёт каждый ответ, какая отправка упадёт, когда впервые покажется виджет. В тесте задается так:
test.use({ hardMode: { flags: ‘bad-network’, seed: 2 } })
То есть это 10 наборов значений для таймеров, порядка показов и задержки сообщений. Перебирая все десять сидов можно проверить свой тест на прочность. Для этого на сцену выходит Flake Score.
Flake Score запускает тест на всех 10 сидах, по два раза на каждый и без ретраев, и считает, на скольких сидах есть ошибки.
Запуск:
npm run flake-score -- lessons/hard-mode/01-popups/homework.spec.ts
Если результат не 100%, лучше тест усилить.

Hard mode уроки
После 11 уроков начинается отдельный трек в lessons/hard-mode/. Приложение то же, форма уроков та же, но теперь домашка считается сданной, только когда Flake Score показывает 10/10.
На данный момент доступен только первый урок — «Попапы, которые мешают». Урок разбирает пять проблем. Для каждой есть два пути: пройти её вручную, как пользователь, или убрать хаком.
1. Cookie‑баннер закрывает страницу
Нажать кнопку в баннере | Заранее записать согласие. |
+ Проверяет сам баннер: текст, кнопки, что выбор запоминается | + Баннер не появляется вообще, мешать нечему |
— Лишние шаги в каждом тесте | — Нужно знать, где приложение хранит выбор |
2. Формы в iframe лежат поверх кнопок
Три формы появляются одна за другой и закрывают кнопку Send, вкладки и поле ввода. Кнопка закрытия у каждой появляется не сразу. Внутрь iframe обычные локаторы не видят, туда заходят только через contentFrame().
Закрыть каждую вручную | Обработчик + перемотка времени. |
+ Интуитивно понятно | + Тест без ожиданий и условий |
— Нужно знать, когда какая форма появится | — Работает только с |
— Если форма появится посреди шага, шаг упадёт |
3. Промо появляется когда захочет
Первый раз через 7–10 с, потом снова после каждого закрытия. Короткий тест обычно успевает до него, пока однажды не перестаёт успевать.
Дождаться и закрыть Ассерт с увеличенным таймаутом, потом «Maybe later» | Обработчик + перемотка времени Тот же приём, что для форм. Обработчик промо регистрируем первым: промо лежит поверх кнопок закрытия форм |
+ Проверяет само промо | + Закрывает промо при каждом возвращении |
— Тест ждёт до 10 с реального времени | — Нельзя проверить |
— Промо вернётся, и в длинном тесте всё повторится |
4. Нативный confirm() на сбросе чата
Это окно браузера, его нет в DOM, локатор его не найдёт. Если ничего не сделать, Playwright сам нажмёт «Cancel», и чат не сбросится.
Ответить на диалог до клика, потом | Подменить |
+ Можно проверить текст вопроса | + Диалога нет совсем |
— Если подписаться после клика, тест не сработает | — Текст вопроса никто не проверяет, если не сохранить его самому |
Как это устроено в уроке
Демо: по каждой помехе два теста, сначала вручную, потом хаком. В каждой паре включена только эта помеха. В конце один тест со всеми помехами сразу.
Домашка: все помехи включены одновременно. Первый тест проходит их вручную, второй хаками.
Главный вывод: вручную проверяем саму помеху, хаком убираем её из всех остальных тестов. Тест должен проходить на всех 10 сидах: проверяем через npm run flake-score.
Домашка как pull request
Обратная связь — основа для любого обучения. Взгляд со стороны и вопросы по существу развивают инженера в разы лучше сотни написанных в соло тестов. Поэтому я провожу код‑ревью для домашек. Отводим ветку, решаем задание, коммит, пуш, ПР — все как в реальном цикле разработки. Ну и важное условие — сиай должен быть зеленым.
Что в планах
Развивать сложный режим и уроки к нему. Идеи приветствуются в issues
Несколько браузеров для прогона тестов. Сейчас только Chromium
Скриншот тесты UI компонентов. Супер полезный подход, особенно для редизайнов.
Новые виджеты в playground.
Заключение
Проект молодой и будет расти, любой вклад приветствуется.
Приходите с домашкой, идеями для новых фич и флагов.
Если проект оказался полезен, поставьте звезду на GitHub — так его проще найти тем, кто тоже учится.

