Протестируйте приложение как пользователь до релиза
Полный цикл QA: тестирование как пользователь, поиск багов, документирование с доказательствами, оценка здоровья. Используйте для проверки качества приложения, страницы или фичи.
Как агент работает
Прогон начинается с трёх ответов: какой URL стенда проверяем, под гостем или под учёткой, запрошенной через `request_form`, и что запрещено трогать — оплату, письма, SMS, остатки в боевом 1С или МойСклад, публикацию на Ozon и WB. Дальше выбирается режим: быстрый — главная и пять ключевых страниц, около пятнадцати действий; полный — все маршруты, формы и граничные значения, 60–120 действий; регрессия — область прошлого бага и соседние экраны, 20–40 действий; по изменениям — диф последнего PR, развёрнутый в список URL.
Каждый шаг доказывается полем `outcome`: «changed — page navigated», «changed — N DOM mutation(s)», «no-change» или «unknown», причём шаг с `unknown` считается непройденным, пока не подтверждён вторым фактом. Ложные баги отсекаются знанием ограничений: диалоги `confirm` и `alert` принимаются автоматически, cookie-баннеры закрываются по типовым селекторам, `console_errors` приходят только на `navigate` и не более двадцати записей, а браузер headless с десктопным юзер-агентом — вывод «на телефоне сломано» без эмуляции недействителен.
Прицельно проверяются классы, на которых ломаются российские формы: ОГРН в 13 знаков и ОГРНИП в 15 с контрольной цифрой по остатку от деления на 11 и на 13, КПП в 9 знаков, где 5-я и 6-я позиции бывают латинскими буквами, телефон в форматах +79991234567 и 89991234567, суммы «1 234,56» с неразрывным пробелом U+00A0, индекс из шести цифр строкой, «Артём» против «Артем» и разложенные буквы из буфера macOS.
Итог сводится в Health Score с фиксированными весами: функциональность 20%, консоль и UX по 15%, доступность 15%, ссылки и визуал по 10%, производительность 10% с порогом LCP 2,5 с, контент 5%. Вердикт из числа не выводится: критический баг даёт «Не готов» при любом score. Навык не чинит найденное по дороге и не проверяет ветку «Отмена» из-за автопринятия диалогов, поэтому раздел «Не проверено» в отчёте обязателен.
С чего начинаешь
- Что тестируем — URL стенда (не прод, если есть выбор), сценарии, что считается «работает».
- Под кем — гость или авторизованный; учётку запроси через
request_form, а не сообщением в чат. - Что запрещено — по умолчанию всё, что видит третье лицо: оплата, письмо, SMS, заказ поставщику, остатки в боевом 1С/МойСклад, публикация на Ozon/WB.
| Режим | Покрытие | Действий |
|---|---|---|
| Быстрый | Главная + 5 ключевых страниц, один сквозной сценарий | ~15 |
| Полный | Все маршруты, формы, граничные значения, адаптивность | 60–120 |
| Регрессия | Область прошлого бага + соседние по данным экраны | 20–40 |
| По изменениям | Диф последнего PR → карта затронутых маршрутов | по дифу |
Диф бери через git_clone и git_ops и разворачивай в список URL: изменился компонент формы → тестируешь все страницы, где он встроен, а не только названную; изменилась миграция → все экраны, читающие таблицу.
Это управление постоянным Chromium: navigate, snapshot, act, click, fill, type, select, check, hover, scroll, press_key, upload_file, wait, screenshot, back.
По ref: сначала snapshot — он отдаёт дерево доступности с номерами элементов, дальше click/fill с номером; точно и дёшево, так и работай по умолчанию. По intent: act с фразой «нажми кнопку Оформить заказ» — интент разрешается по дереву, при неудаче по скриншоту; бери, когда дерево не даёт однозначного имени.
Что возвращается и как это читать
outcome— самое ценное поле. Дляclickиpress_key— вердиктchanged — page navigated/changed — N DOM mutation(s)/no-change/unknown. Дляfill/type/select— значение поля после действия с пометкой расхождения: готовый детектор багов масок (вводишь+7 (999) 123-45-67, поле вернуло+7 (999) 123-45-6).no-change— не всегда провал: canvas-, iframe- и Flutter-интерфейсы не мутируют DOM. Прежде чем писать «кнопка не работает», проверь иначе:screenshot,url, повторныйsnapshot.unknown— не доказательство: такой шаг непройден, пока не подтверждён вторым фактом.element_count: 0— почти всегда редирект на пустой экран, незагрузившийся SPA или требование входа, а не страница без кнопок.console_errors— приходят только наnavigate, не более 20, обрезаны до 300 символов, только уровняerrorплюс необработанные исключения: ошибку после клика этим полем не увидишь.
Ограничения, из-за которых пишут ложные баги
- Диалоги принимаются автоматически:
confirm/alert/beforeunloadгасятся согласием — ветку «Отмена» этим инструментом не проверить. - Cookie-баннеры закрываются автоматически по типовым селекторам — баг баннера смотри первым
navigate+screenshot. - Скриншот — видимая часть в JPEG невысокого качества: годится для «поехала вёрстка», не для «отступ 3px вместо 4px».
- Браузер headless с десктопным юзер-агентом Windows Chrome: ширина окна одна, touch нет — вывод «на телефоне сломано» без эмуляции ложен.
- Сессия сохраняется между вызовами: вход делаешь один раз, зато тесту «первый вход» после этого нужен свежий контекст.
Когда возможностей не хватает: CDP из repl_execute
scrollWidth > clientWidth при overflow:hidden — машинный признак обрезанного текста, горизонтальный скролл на 360px — несжимаемой вёрстки. Слушатели дают то, чего browser_interact не отдаёт после клика. Обрыв сети и часовой пояс — через ctx.new_cdp_session(page): Network.emulateNetworkConditions с offline: True и Emulation.setTimezoneOverride.
Протокол одного сценария
Сценарий — путь к результату, за который платят: «оформил заказ», «выгрузил акт сверки», а не «открыл страницу».
Классы дефектов, которые ищешь прицельно
Гонка при двойной отправке
Воспроизведение: два click по кнопке отправки без ожидания между ними; отдельно — press_key: Enter в поле сразу после клика.
Признаки: два одинаковых заказа/платежа/письма, два POST с одинаковым телом, счётчик вырос на 2, у кнопки нет состояния «отключена». Цена: двойное списание, две отгрузки, два письма клиенту. В баге не пиши «заблокировать кнопку»: она спасает только от клиентского дубля, настоящая защита — идемпотентный ключ на стороне API.
Потеря состояния при возврате
Воспроизведение: фильтры → карточка → back; три шага мастера → back → вперёд; ошибка валидации → back.
Признаки: фильтры сброшены, пагинация на первой странице, скролл в начало, введённое пропало, форма оплаты пустая — но заказ создан. Подкласс: back после успешной отправки показывает прежние данные, и повторная отправка создаёт дубль.
Часовые пояса и даты
В России 11 часовых зон, от UTC+2 (Калининград) до UTC+12 (Камчатка), и почти всегда сервер живёт по Москве, а пользователь — нет.
Воспроизведение: Emulation.setTimezoneOverride на Asia/Kamchatka и Europe/Kaliningrad, затем те же сценарии; создай запись в 23:30 по местному времени и смотри, какой датой она попала в отчёт.
Признаки: дата документа сдвинута на сутки; «сегодня» в фильтре не включает только что созданную запись; отчёт «за 1 июля» у клиента из Владивостока содержит часть 30 июня; время в списке и в карточке различается на 3 часа — одно место форматирует UTC, другое локальное.
Правило: если хранение в UTC, а бизнес-сутки идут по местному времени пользователя, сутки считаются в его зоне; на закрытых сутках это расхождение с 1С, которое заметит бухгалтер.
Поведение форм при потере сети
Воспроизведение: заполнил → offline через CDP → отправил → вернул сеть. Признаки: вечный спиннер без таймаута; «Ошибка» без ответа, сохранились ли данные; после возврата сети форма ушла повторно; сетевая ошибка показана как «Неверный логин или пароль». Разделяй два случая: запрос не ушёл (повтор безопасен) и запрос ушёл, но ответ не получен (повтор опасен). Интерфейс, который их не различает, — «высокий» на денежном шаге.
Числа, деньги и файлы из 1С
Воспроизведение: 1 234,56, 1234.56, 1 234 567,89 ₽ с неразрывными пробелами (U+00A0), минус U+2212 вместо дефиса, отрицательный остаток, три знака после запятой. Признаки: запятая отвергается или молча превращает 1 234,56 в 1; вставка из Excel/1С ломается о неразрывный пробел; построчное округление копеек расходится с итогом.
Файлы (upload_file): CSV в CP1251, CSV с BOM, .xlsx с объединёнными ячейками в шапке, файл 0 байт. Признак бага: кракозябры, «файл повреждён» без номера строки, импорт половины строк.
Пустые состояния и базовая безопасность
Пустое проверяй в свежем контексте: пустой список, поиск с 0 результатов, отчёт без данных, удалён последний элемент. Признаки: белая область, undefined, NaN, «0 из 0», вечный спиннер, шапка без «Ничего не найдено».
В поля подставь <script>alert(1)</script>, "><img src=x onerror=alert(1)>, ' OR 1=1--, {{7*7}}: признак — значение отрисовалось как разметка или появилось 49. Отдельно — чужой id документа в URL. Найденное здесь всегда «критический»; описывай без подробностей эксплуатации.
Граничные значения для российских форм
ФИО
Дефис («Салтыков-Щедрин»), пробел внутри фамилии («Мамед оглы»), апостроф, одна буква («Ю»), 40+ символов, латиница, все заглавные. Поле не режет, не запрещает дефис и пробел, не «исправляет» регистр; «только кириллица» — дефект сам по себе.
ё/е и разложенные буквы
«Артём» и «Артем» — разные строки для поиска и для уникальности. Вторая ловушка: «й» и «ё» из буфера macOS приходят в разложенной форме (буква + диакритика) — визуально совпадает, побайтово нет. Проверка: заведи «Артём», ищи «Артем» и наоборот; баг, если поиск не находит, а повторное создание даёт нового контрагента.
ОГРН и КПП
ОГРН — 13 знаков, ОГРНИП — 15; последняя цифра контрольная и равна последней цифре остатка от деления числа без неё (13 знаков — на 11, 15 — на 13). КПП — 9 знаков, где 5-я и 6-я позиции могут быть латинскими буквами для иностранных организаций: форма «только цифры» отсекает часть контрагентов.
Телефон
+79991234567, 89991234567, +7 (999) 123-45-67, 8-800-555-35-35, городской с кодом, «доб. 123», международный +375…. Отдельно — вставка из буфера в маску и ввод в середину заполненной маски: каретка прыгает в конец. Баг, если 8 и +7 сохранились как разные номера.
Адрес, индекс, даты
Длинные названия («улица имени 40-летия Победы»), литера дома («д. 5Б» — кириллическая Б и латинская B разные символы), «корп. 2 стр. 3», квартира «12/1», сёла без улиц. Индекс — 6 цифр строкой: числом теряет ведущий ноль. При подсказках адресов проверь, что можно дописать вручную то, чего нет в справочнике. Даты: 01.07.2026 и 2026-07-01 в одном интерфейсе — уже дефект; проверь 29.02 невисокосного года, конец периода раньше начала, ручной ввод с клавиатуры.
Классификация серьёзности
- Критический — теряются деньги или данные, обхода нет: двойное списание, доступ к чужим данным, потеря документа, отказ входа.
- Высокий — ключевой сценарий не проходится, обход неочевиден: отчёт не выгружается, оплата проходит без уведомления.
- Средний — сценарий проходится с потерей времени или доверия: слетают фильтры, непонятная ошибка, обрезанный реквизит.
- Низкий — косметика: отступы, опечатка, несогласованный термин.
Серьёзность задаёт последствие: опечатка в сумме — критический баг, не низкий.
Health Score
Оценка нужна, чтобы сравнивать прогоны между собой: категории и веса не меняй.
| Категория | Вес | Почему столько |
|---|---|---|
| Функциональность | 20% | Единственная, где дефект — потерянные деньги сегодня |
| Консоль (JS-ошибки) | 15% | Молчащая ошибка сегодня — сломанный сценарий завтра |
| UX | 15% | Потери данных и неясные ошибки — из-за чего пишут в поддержку |
| Доступность | 15% | Элемент без имени не виден ни скринридеру, ни автоматизации |
| Ссылки | 10% | Считается машинно и полностью — вес умеренный |
| Визуал | 10% | Заметно, но обходится пользователем |
| Производительность | 10% | Влияет на конверсию, но редко блокирует |
| Контент | 5% | Дёшево чинится; ошибки в суммах — в баги, а не сюда |
- Функциональность = 100 × (пройденные шаги / запланированные); шаг с
unknownнепройден. - Консоль = 100 − 15 × (уникальные JS-ошибки, дедуп по первой строке) − 25 × (ошибки на денежном или регистрационном шаге), не ниже 0.
- UX = 100 − 10 за каждое: действие без отклика дольше секунды, потеря введённого, ошибка без объяснения, что делать.
- Доступность = 100 × (доля интерактивных элементов с непустым именем в дереве) − 20, если фокус не виден, − 20, если сценарий непроходим с клавиатуры (
press_key: Tab,Enter): элементы видаbutton ""— прямой счётчик. - Ссылки = 100 × (доля ответов 2xx); 4xx/5xx — ноль, редирект длиннее двух хопов — половина.
- Визуал = 100 − 8 за обрезанный элемент, − 15 за нечитаемый или перекрытый текст, − 20 за скролл вбок на 360px.
- Производительность — по худшей странице маршрута: LCP до 2,5 с → 100, до 4 с → 60, дольше → 20; CLS выше 0,25 → −20 (пороги Core Web Vitals на 2026-07-28).
- Контент = 100 − 10 за опечатку или расхождение в терминах.
Вердикт не выводится из числа. Критический баг есть → «Не готов» при любом score; критических нет, но score < 70 или есть высокие на ключевом сценарии → «Нужна доработка»; иначе → «Готов к релизу».
Итоговый отчёт
Раздел «Не проверено» обязателен: без него отчёт читается как «проверено всё», и первый баг из непокрытой области обнулит доверие. Отдавай отчёт через documents, регулярный прогон — через propose_schedule, критические находки — в emit_insight; правку можно довести до open_pull_request, но отчёт описывает состояние до неё.
Правила работы
- Экран — не факт. «Кнопка не нажалась» без
outcomeи второй проверки — гипотеза, а не баг. - Один шаг — один вызов: склейка делает невоспроизводимым и баг, и отчёт.
- Валидный путь сначала: пока сценарий не пройден целиком, непонятно, что считать нормой.
- Пять попыток для плавающего бага, и число в отчёте.
- Не чини по дороге: правки в середине прогона делают отчёт описанием несуществующей версии.
- Не трогай боевые данные: оплата — в тестовом режиме провайдера, рассылки — на свои адреса, остатки и заказы в 1С/МойСклад/Ozon/WB не меняешь.
- Пять доказанных багов лучше двадцати расплывчатых: закроют те, что удаётся воспроизвести.
- Ограничения инструмента — часть отчёта, а не оправдание: не проверил «Отмену» из-за автопринятия диалогов — так и напиши.
Похожие навыки
Попробуйте этот навык
Зарегистрируйтесь и используйте навык «QA-тестирование» бесплатно.