Reference

Chrome DevTools Protocol + CaptchaAI для диагностики CAPTCHA в тестовых средах

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

Если reCAPTCHA или Turnstile ведёт себя по-разному на staging и в проде, быстрее всего разобраться не через полноценный e2e-тест, а через Chrome DevTools Protocol (CDP): открываете сеть на уровне протокола и видите, какой sitekey реально ушёл в запросе, что вернул CaptchaAI и как отреагировал ваш собственный backend.

CDP полезнее полноценного браузерного теста, когда:

  • проблема воспроизводится только на одном окружении, а причина неочевидна;
  • нужно быстро понять, чей это баг — фронтенда, backend-валидации или самого solver'а;
  • гонять целый Selenium/Playwright-сценарий ради одной проверки sitekey избыточно.

CDP — это протокол, через который сам Chrome общается со своими инструментами разработчика: DevTools, Puppeteer и Playwright используют один и тот же WebSocket-канал. Для QA это значит, что можно подписаться на сетевые события напрямую, без обёртки WebDriver, и увидеть ровно те запросы, которые формирует виджет CAPTCHA на вашей форме.

Локальный пример: распределённая QA-команда и общий CI-дашборд

Команда, разнесённая между Москвой и Алматы, гоняет такую диагностику на странице оформления заказа при каждом merge request. Контейнер поднимает Chrome с открытым CDP-портом, скрипт фиксирует sitekey, время решения через CaptchaAI и код ответа backend, а результат уходит в общий дашборд. Так расхождения между окружениями видно сразу — а не после жалобы пользователя из другого часового пояса, когда воспроизвести баг уже сложнее.

Типичные проблемы CDP + CaptchaAI: с чего начать разбор

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

Симптом Что проверить
Токен валиден, backend не принимает Сверьте secret и домен верификации
sitekey не находится Проверьте, действительно ли виджет рендерится на staging
CDP не подключается Закройте старые процессы Chrome — порт может быть занят
Задача висит в pending Проверьте баланс и число доступных потоков в аккаунте CaptchaAI
Виджет виден, но sitekey не находится обычным querySelector Ищите разметку CAPTCHA внутри Shadow DOM

Если ни один из симптомов не подошёл — переходите к диагностике по шагам ниже.

Подключение к Chrome через CDP на staging-странице

Поднимите Chrome с открытым CDP-портом на своей staging-странице — порт 9222 подключается любым клиентом: websockets, pychrome, встроенный API Puppeteer или Playwright.

chrome --remote-debugging-port=9222 \
  --user-data-dir=./qa-profile \
  https://staging.example.com/captcha-demo

Здесь важно ограничить область диагностики: слушайте только трафик собственной страницы и запросы к вашему backend-эндпоинту верификации — сторонний трафик в эту диагностику не входит.

Как найти sitekey reCAPTCHA или Turnstile на тестовой странице

На staging-версии формы sitekey почти всегда лежит прямо в DOM как атрибут — быстрее всего вытащить его обычным запросом и регулярным выражением, не поднимая браузер целиком:

import re, requests

html = requests.get('https://staging.example.com/captcha-demo').text
sitekey = re.search(r'data-sitekey="([^"]+)"', html).group(1)
print('sitekey:', sitekey)

Сохраните значение sitekey в конфигурации тестов отдельно от production. Расхождение между sitekey на staging и в проде — одна из самых частых причин, почему CAPTCHA «работает у разработчика», но падает в CI.

Проверка sitekey через API CaptchaAI из QA-скрипта

Дальше тот же sitekey и pageurl передаются в CaptchaAI напрямую — без браузера, только запросом к API. Это позволяет отделить проблему на уровне solver'а от проблемы на уровне самой формы:

import os, requests, time

API_KEY = os.environ['CAPTCHAAI_KEY']
PAGE = 'https://staging.example.com/captcha-demo'

def solve(sitekey: str) -> str:
    r = requests.post('https://ocr.captchaai.com/in.php', data={
        'key': API_KEY, 'method': 'userrecaptcha',
        'googlekey': sitekey, 'pageurl': PAGE, 'json': 1,
    }).json()
    tid = r['request']
    for _ in range(40):
        time.sleep(3)
        res = requests.get('https://ocr.captchaai.com/res.php', params={
            'key': API_KEY, 'action': 'get', 'id': tid, 'json': 1,
        }).json()
        if res['status'] == 1:
            return res['request']
    raise TimeoutError(tid)

Функция опрашивает res.php каждые 3 секунды и возвращает готовый токен, как только status становится 1. Если задача висит дольше пары минут — почти всегда дело не в CaptchaAI, а в том, что sitekey или pageurl не совпадают с реальной страницей. Учтите также: пока скрипт ждёт ответа от res.php, он занимает один поток CaptchaAI. Если диагностика гоняется в CI на каждый pull request, закладывайте план с запасом по потокам — например, ADVANCE ($90/мес, 50 потоков), а не самый маленький тариф, иначе параллельные прогоны будут вставать в очередь друг за другом.

Передайте полученный токен на свой QA-backend и убедитесь, что серверная проверка действительно подтверждает успех, а не просто принимает любое непустое значение. Если backend отвечает не 200 — почти всегда виноват несовпадающий secret, домен или pageurl верификации, а не сам solver.

Структурированные логи и метрики P90/P99

Чтобы сравнивать поведение CAPTCHA между релизами, а не полагаться на ощущения, каждую попытку стоит логировать в едином формате:

import json, time, logging

log = logging.getLogger('captcha-qa')

def record(event: str, **fields) -> None:
    payload = {'ts': time.time(), 'event': event, **fields}
    log.info(json.dumps(payload, ensure_ascii=False))

Минимальный набор полей: slug, captcha_type, task_id, wait_seconds, verify_status, env. Этого достаточно для дашборда медианы, P90 и P99 по типу CAPTCHA и по окружению.

Не сохраняйте в логах реальные данные тестовых пользователей: по духу 152-ФЗ «О персональных данных» (и аналогично для GDPR, если в команде есть коллеги за пределами РФ) в диагностические логи должны попадать только синтетические тестовые значения.

Перед тем как доверять диагностике целиком, пройдитесь по короткому чек-листу:

  1. Запросы уходят только на собственные или явно авторизованные endpoints.
  2. Тестовые аккаунты, заказы и платежи помечены как фиктивные.
  3. Токен CAPTCHA проверяется на вашем backend, а не принимается на веру на клиенте.
  4. В логах есть task_id, тип CAPTCHA, время ожидания и итоговый статус.
  5. Скрипт возвращает корректный exit code, чтобы CI мог принять решение автоматически.

FAQ

Можно ли использовать этот подход на сторонних сайтах?

Нет. Описанные сценарии применимы только к собственным или явно авторизованным средам. Для чужих ресурсов сначала запрашивайте письменное разрешение владельца.

Что делать, если CaptchaAI вернул ошибку при отправке задачи?

Логируйте task_id, тип CAPTCHA и текст ошибки, повторяйте запрос с экспоненциальной задержкой и следите за долей ошибок на дашборде. Устойчивый рост ошибок — повод перепроверить sitekey и саму страницу, а не считать это сбоем solver'а.

Как сравнивать результаты решения CAPTCHA между релизами?

Храните логи в одном формате и стройте отчёт по медиане, P90 и P99 на сопоставимом наборе сценариев. Сравнивать имеет смысл только выборки из одной и той же собственной среды, а не staging с продом вперемешку.

Можно ли подключить Playwright или Puppeteer к тому же CDP-сеансу, что и диагностический скрипт?

Да — оба инструмента работают поверх CDP и умеют переиспользовать уже открытую сессию через её WebSocket-адрес. Это удобно, когда диагностика нужна как дополнительный слой поверх уже существующих браузерных тестов, а не вместо них.

Почему CDP не видит sitekey, хотя виджет CAPTCHA точно отображается на странице?

Скорее всего разметка спрятана внутри Shadow DOM, а обычный document.querySelector туда не заглядывает. Используйте DOM.describeNode с обходом shadow-root'ов или инструменты, которые явно поддерживают pierce-режим для Shadow DOM.

Для дальнейшего чтения см. быстрый старт CaptchaAI, авторизованное QA-тестирование CAPTCHA, тестирование CAPTCHA API на собственных формах и разбор ситуации, когда браузерный тест падает, а API проходит. Пошаговые руководства по конкретным типам: reCAPTCHA v2 через API, Cloudflare Turnstile через API, GeeTest v3 через API.

Хотите такую диагностику в собственном CI? Подключите CaptchaAI и добавьте проверку sitekey и backend в пайплайн уже на этой неделе.

Комментарии для этой статьи отключены.