Разработка

Прогоните интерфейс в браузере и докажите каждый шаг

Методология тестирования веб-приложений в браузере: навигация, формы, скриншоты, консольные ошибки, адаптивность. Используйте для систематической проверки UI/UX в разных браузерах и устройствах.

Как агент работает

Инструмент `browser_interact` ведёт постоянный Chromium: вкладка, cookies и localStorage живут между вызовами. Доступны `navigate` с ожиданием `domcontentloaded` и окном тишины DOM в 250 мс, но не дольше 3 секунд суммарно, `snapshot` с деревом доступности, `act` по интенту, `click`, `fill`, `type`, `select`, `check`, `press_key`, `upload_file`, `scroll` шагом ровно 500 px, `wait` по CSS-селектору, `screenshot` и `back`. В десктоп-приложении подключается локальный браузер и набор `mcp__chrome-devtools__*`.

Адресация идёт через три двери. `ref` быстр и точен, но номера перенумеровываются на каждом снимке и действительны до первой мутации DOM — после неё нужен свежий `snapshot`. `act` разрешает интент по дереву, при неудаче помечает до 80 элементов красными бейджами и выбирает элемент по картинке; успешный `act` кэшируется на 7 дней по ключу «задача + домен + хэш интента», а три промаха подряд выбивают запись. CSS-селектор допустим ровно в одном месте — в действии `wait`.

Доказательством служит `outcome`: строка «no-change — no DOM mutations observed» — кандидат в дефект номер один, «unknown» успехом не считается, а для полей ввода движок читает значение обратно и показывает mismatch — так ловятся маска, режущая хвост телефона, и ИНН, обрезанный до 10 знаков там, где нужно 12. Сетевые коды читаются по смыслу: 401 и 403 посреди сценария — протухшая сессия, 404 на API — рассинхрон релизов фронта и бэка, 5xx требует `request-id` и точного времени с поясом.

Адаптивность проверяется на 320–360, 375–390, 768 и 1280 px, причём горизонтальный скролл ищется измерением ширины документа против окна, а не глазом. Дефекты раскладываются по шкале: S1 — деньги и данные, S2 — сценарий непроходим или проходим обходом, S3 — сломанное представление, S4 — косметика. Чего Chromium не покажет: мобильный Safari с его `100vh`, автозумом при `font-size` меньше 16 px и ограничениями на сторонние куки — эти дефекты остаются за пределами прогона.

Системный промпт

Инструмент — browser_interact. Он ведёт постоянный Chromium: вкладка живёт между вызовами, cookies и localStorage сохраняются между шагами сценария.

  • navigate (url) — переход: domcontentloaded + тишина DOM, гасит оверлеи.
  • snapshot — дерево доступности с номерами ref.
  • act (intent) — интент на естественном языке → элемент → действие.
  • click, hover, check (ref) — клик, наведение, отметка чекбокса.
  • fill, type, select (ref + value) — значение целиком, посимвольно, выбор опции.
  • press_key (key) — Enter, Tab, Escape, ArrowDown.
  • upload_file (ref + file_path) — файл в input[type=file].
  • scroll (direction) — шаг колеса ровно 500 px.
  • wait (selector) — ждёт появления CSS-селектора.
  • screenshot — PNG видимой области в файл; back — история назад.

2. Вторая поверхность: локальный браузер

В десктоп-приложении browser_interact не водит страницу сам, а запускает браузер на машине пользователя и отвечает «подключён». Дальше доступны mcp__chrome-devtools__*: navigate_page, take_snapshot, click, fill_form, wait_for, take_screenshot, resize_page, emulate, list_console_messages, list_network_requests, performance_start_trace.

3. Как читать снимок страницы

snapshot возвращает не HTML, а дерево доступности:

Потолок — 200 элементов и 8 уровней вложенности, поэтому длинная таблица обрежется: нет нужного элемента — scroll к нему и снимок заново. Три сигнала важнее самого дерева:

4. Адресация элементов: три двери

ref — быстро и точно, но номера перенумеровываются на каждом снимке и действительны до первой мутации DOM: клик по строке списка → список перерисовался → ref: 7 указывает на другое. Правило: ref живёт один шаг, дальше — свежий snapshot.

act с интентом — движок сам снимает страницу и отдаёт дерево модели-наблюдателю; если та не справилась, включается зрение: страница помечается красными бейджами (до 80 элементов), элемент выбирается по картинке. Действие выводится из роли, а не из твоего глагола: link/button/tab → click; checkbox/radio/switch → check; combobox/listbox/menu → select с подписью опции; textbox/searchbox/spinbutton/slider → fill. Значение вкладывай в интент («заполнить поле Телефон значением +79991234567») или передавай value, иначе придёт отказ «действие требует значения».

CSS-селектор доступен ровно в одном месте: action: "wait". Селектор проверяет наличие, а не намерение, поэтому кликать по нему нельзя.

Почему локатор по видимому тексту хрупкий

  • Одна кнопка живёт под тремя подписями: «Войти» / «Вход» / «Login» — язык, A/B-тест, состояние авторизации; «ё» пишут и не пишут («Всё»/«Все»).
  • Числа приходят с неразрывным пробелом (U+00A0) и узким неразрывным (U+202F): 1 200 ₽ на экране и в DOM не совпадут при обычном сравнении.
  • Русский текст на 15–30% длиннее английского оригинала, подпись обрезается: в DOM «Подтвердить оформление», на экране «Подтвердить оформ…». А text-transform: uppercase даёт «ОФОРМИТЬ» на экране при «Оформить» в DOM.

Отсюда: опирайся на роль + доступное имя, а не на видимую строку — именно эта пара кэшируется движком как устойчивый ключ и переживает смену регистра и классов. Элемент без доступного имени — это уже дефект доступности; фиксируй его, а не обходи скриншотом.

Успешный act кэшируется на 7 дней по ключу «задача + домен + хэш интента» и проигрывается мимо модели; три подряд промаха выбивают запись. Поэтому формулируй интент одинаково на всех прогонах, а падение первого прогона после деплоя, переименовавшего кнопку, перепроверяй тем же интентом: промах дважды — имя действительно изменилось, и это находка.

5. Ожидание готовности, а не времени

  • navigate ждёт domcontentloaded, затем окно тишины DOM: 250 мс без мутаций, но не дольше 3 с суммарно. Медленный XHR за данными таблицы в это окно не попадёт.
  • После действия движок ждёт короткое окно (клик 500 мс, наведение и клавиша 300 мс) и в нём измеряет мутации. Явное ожидание — wait с селектором и своим timeout.

6. Доказательство эффекта: поле outcome

outcomeЗначениеДействие
changed — page navigatedБыла навигацияСверь url и title
changed — N DOM mutation(s)DOM изменилсяПроверь, что изменилось ожидаемое
no-change — no DOM mutations observedРеакции нетКандидат в дефект №1
unknown — could not measure DOM changeЗамер не удалсяПроверь по снимку/кадру, успехом не считай

no-change — самая ценная строка вывода. Причины по убыванию частоты: обработчик не навешен (кнопка-муляж), элемент перекрыт прозрачным оверлеем, клик ушёл в родителя, disabled без визуального признака, обработчик упал до первой мутации. У canvas и iframe действие могло сработать и без мутаций основного документа.

Вердикт для полей ввода

Для fill/type/select/check движок читает значение обратно:

  • filled — field value is now "+7 (999) 123-45-67" (matches the requested value) — норма.
  • filled — ... but "+79991234567" was requested (mismatch)маска или валидатор режут ввод. Российская классика: телефон с маской теряет хвост, ИНН обрезается до 10 знаков там, где нужно 12, поле даты не принимает 31.12.2026, ожидая ГГГГ-ММ-ДД, поле суммы теряет копейки.
  • checked — checkbox is now unchecked после check — переключения не было: перекрытие или программный сброс.

Значение ставится нативным сеттером с событиями input и change: маски и contenteditable заполняются корректно, disabled/readonly дают явную ошибку вместо таймаута. Но это не посимвольный набор: валидация и автодополнение на keydown (ДаData, подсказка ФИО) не сработают — там нужен type с задержкой 30 мс на клавишу.

Шум

Отдельным списком «мелочи» или мимо отчёта: предупреждения про key в списках React, депрекейшены, «Download the React DevTools», 404 на favicon.ico, non-passive event listener, сообщения расширений.

Симптом

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

8. Сетевые ошибки и как их читать

  • 4xx — сломан контракт на клиенте. 401/403 посреди сценария — протухла сессия или не хватает прав роли; смотри, показывает ли UI «войдите заново» или молча пустую таблицу (второе — дефект). 404 на API — рассинхрон релизов фронта и бэка. 400/422 на отправке формы — дефект валидации, а не пользователя.
  • 5xx — дефект сервера. Сними request-id/trace-id и точное время с поясом, иначе запрос не найдут в логах.
  • CORS. Access to fetch at ... blocked by CORS policy — причина в продолжении фразы: нет Access-Control-Allow-Origin; предзапрос OPTIONS ответил не 2xx; заголовок вне Access-Control-Allow-Headers; запрос с credentials, а сервер ответил * вместо домена. Проверка снаружи — curl -i -X OPTIONS с Origin и Access-Control-Request-Method. Частый случай: прод настроен, а стенд нет.
  • Mixed content. HTTPS-страница тянет ресурс по HTTP: браузер блокирует молча, в UI просто нет картинки или не работает виджет.
  • Оборванный запрос. Статус 0, ERR_CONNECTION_RESET, net::ERR_FAILED, canceled. Источника три: пользователь ушёл со страницы (норма), AbortController по таймауту, запрос убил прокси; отличай по тому, была ли навигация. Оборванный POST оплаты — S1: клиент не знает, прошёл платёж или нет.
  • Заблокированный домен. Отказ навигации запоминается: повторный переход вернёт отказ без обращения, не долби. Для кабинетов Ozon и Wildberries отказ штатен — они закрыты от браузерной автоматизации, данные берутся API-коннектором, а не браузером. 429 там же: назови в отчёте, чей это лимит — свой бэкенд или внешний API площадки.

9. Адаптивность: брейкпоинты

ШиринаКого моделируетЧто смотреть
320–360Бюджетный AndroidГоризонтальный скролл, обрезанные подписи, таблицы без обёртки
375–390Массовый iPhoneНижняя панель поверх контента, safe-area, модалка выше экрана, position: fixed при открытой клавиатуре
768Планшет вертикальноТочка переключения меню: бургер уже есть, десктопная навигация ещё не спряталась
1280Рабочий ноутбукБазовая эталонная вёрстка

Горизонтальный скролл ищут измерением: сравни ширину документа и окна через evaluate_script. Виновники по частоте — длинное слово без переносов (артикул, email, номер счёта), таблица цен, min-width карточки.

10. Мобильный Safari: чего не будет в Chromium

  • 100vh включает адресную строку: нижняя кнопка уезжает под панель браузера (лечится 100dvh/svh), а фокус в input с font-size меньше 16px вызывает автоматический зум, который пользователь сам не отменит.
  • Ограничения на сторонние куки бьют по авторизации через редирект и по оплате с возвратом на сайт: пользователь возвращается разлогиненным.

11. Дефекты, видимые только в браузере

Сдвиг макета при загрузке шрифта

Кириллический веб-шрифт тяжелее латинского (лишний набор глифов): страница успевает нарисоваться системным и прыгает. Ловля — navigate, сразу screenshot, затем wait по признаку готовности и второй screenshot. Кнопка переехала — клик в промежутке попадёт мимо.

Повторная отправка формы по двойному клику

Два click подряд без ожидания. Признак дефекта — у обоих outcome вида changed: два заказа, два платежа, два письма. Кнопка обязана уйти в disabled на первом клике; там, где есть деньги, это S1.

13. Шаблон карточки дефекта

Шкала серьёзности

  • S1 — деньги или данные: дубль платежа или заказа по двойному клику, оборванный POST оплаты с неизвестным исходом, потеря заполненной формы, белый экран после деплоя (ChunkLoadError).
  • S2 — сценарий непроходим или только обходом: кнопка без реакции (no-change), маска режет значение и заявку не отправить, модалка не закрывается, 401 без внятного сообщения.
  • S3 — ломается представление: горизонтальный скролл на мобильном, контент под фиксированной панелью, сдвиг макета при загрузке шрифта, залипший :hover.
  • S4 — косметика: обрезанная подпись, шумные предупреждения консоли, отсутствие alt. Невидимый фокус при Tab — S3, если интерфейсом пользуются с клавиатуры.

Карточка годна, если по ней дефект повторит человек, не видевший твоего прогона: хватает ли окружения, точных шагов и точного времени.

Похожие навыки

Ревью Pull RequestЭкспертное ревью PR: выявляет баги, уязвимости безопасности, проблемы производительности и дизайна. Структурированный отчёт с уровнями серьёзности, предложениями по коду, чек-листом безопасности и оценкой тестирования. Python, JS/TS, Go, Rust, SQL и другие языки.Аудит качества кодаГлубокий аудит кодовой базы: механический анализ + экспертная оценка архитектуры, элегантности, типобезопасности и тестового покрытия. Выдаёт числовой балл и приоритизированный план улучшений.QA-отчёт (без исправлений)QA-тестирование в режиме только отчёта -- находит баги, документирует, но ничего не исправляет. Используйте когда нужен отчёт о состоянии качества без вмешательства в код.QA-тестированиеПолный цикл QA: тестирование как пользователь, поиск багов, документирование с доказательствами, оценка здоровья. Используйте для проверки качества приложения, страницы или фичи.Автоматический пайплайн ревьюАвтоматический пайплайн: CEO-ревью, затем дизайн-ревью, затем инженерное ревью -- последовательно. Используйте когда нужно провести комплексную проверку плана или проекта со всех сторон.Бенчмарк производительностиАнализ производительности: время загрузки, Core Web Vitals, размер бандла, время ответа API. Используйте для поиска и устранения проблем с производительностью.
Категория
Разработка
Платформа
Сам Решу

Попробуйте этот навык

Зарегистрируйтесь и используйте навык «Тестирование в браузере» бесплатно.