Tutorials

Создайте конвейер автоматизированного тестирования с помощью CaptchaAI

Создайте готовый к CI конвейер тестирования, который решает CAPTCHA во время сквозных тестов, чтобы ваш набор автоматизированных тестов никогда не блокировался при выполнении задач CAPTCHA.


Структура проекта

tests/
├── conftest.py          # Shared fixtures
├── helpers/
│   ├── captcha.py       # CaptchaAI integration
│   └── browser.py       # Selenium helpers
├── test_login.py        # Login flow tests
├── test_checkout.py     # Checkout flow tests
└── pytest.ini           # Config

CaptchaAI Помощник по тестированию

# tests/helpers/captcha.py
import requests
import time
import os


class CaptchaTestHelper:
    """Solve CAPTCHAs during automated tests."""

    def __init__(self):
        self.api_key = os.environ.get("CAPTCHAAI_API_KEY")
        if not self.api_key:
            raise EnvironmentError("CAPTCHAAI_API_KEY required for CAPTCHA tests")

    def solve_recaptcha(self, sitekey, pageurl):
        resp = requests.post("https://ocr.captchaai.com/in.php", data={
            "key": self.api_key,
            "method": "userrecaptcha",
            "googlekey": sitekey,
            "pageurl": pageurl,
            "json": 1,
        }, timeout=30)
        result = resp.json()
        if result.get("status") != 1:
            raise RuntimeError(f"Submit failed: {result.get('request')}")

        task_id = result["request"]
        time.sleep(15)

        for _ in range(24):
            resp = requests.get("https://ocr.captchaai.com/res.php", params={
                "key": self.api_key, "action": "get",
                "id": task_id, "json": 1,
            }, timeout=15)
            data = resp.json()
            if data.get("status") == 1:
                return data["request"]
            if data["request"] != "CAPCHA_NOT_READY":
                raise RuntimeError(data["request"])
            time.sleep(5)

        raise TimeoutError("CAPTCHA solve timeout in test")

    def inject_token(self, driver, token):
        """Inject solved token into Selenium browser."""
        driver.execute_script(
            'document.getElementById("g-recaptcha-response").value = arguments[0];',
            token,
        )
        # Trigger callback if available
        driver.execute_script("""
            if (typeof ___grecaptcha_cfg !== 'undefined') {
                var clients = ___grecaptcha_cfg.clients;
                for (var key in clients) {
                    var client = clients[key];
                    for (var prop in client) {
                        var val = client[prop];
                        if (val && typeof val === 'object') {
                            for (var inner in val) {
                                if (typeof val[inner] === 'function') {
                                    val[inner](arguments[0]);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        """, token)

Pytest Светильники

# tests/conftest.py
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from helpers.captcha import CaptchaTestHelper


@pytest.fixture(scope="session")
def captcha_solver():
    return CaptchaTestHelper()


@pytest.fixture(scope="function")
def browser():
    options = Options()
    options.add_argument("--headless")
    options.add_argument("--no-sandbox")
    options.add_argument("--disable-dev-shm-usage")
    driver = webdriver.Chrome(options=options)
    driver.implicitly_wait(10)
    yield driver
    driver.quit()


@pytest.fixture(scope="session")
def base_url():
    return "https://staging.example.com"

Тест входа с помощью CAPTCHA

# tests/test_login.py
import pytest
from selenium.webdriver.common.by import By


class TestLogin:
    def test_valid_login_with_captcha(self, browser, captcha_solver, base_url):
        """Test that login succeeds when CAPTCHA is solved correctly."""
        browser.get(f"{base_url}/login")

        # Fill form
        browser.find_element(By.ID, "email").send_keys("test@example.com")
        browser.find_element(By.ID, "password").send_keys("testpassword123")

        # Solve CAPTCHA
        sitekey = browser.find_element(
            By.CLASS_NAME, "g-recaptcha"
        ).get_attribute("data-sitekey")

        token = captcha_solver.solve_recaptcha(sitekey, browser.current_url)
        captcha_solver.inject_token(browser, token)

        # Submit
        browser.find_element(By.ID, "login-btn").click()

        # Assert redirect to dashboard
        assert "/dashboard" in browser.current_url
        assert browser.find_element(By.CLASS_NAME, "welcome-message")

    def test_invalid_credentials_with_captcha(self, browser, captcha_solver, base_url):
        """Test that wrong credentials show error even with valid CAPTCHA."""
        browser.get(f"{base_url}/login")

        browser.find_element(By.ID, "email").send_keys("wrong@example.com")
        browser.find_element(By.ID, "password").send_keys("wrongpass")

        sitekey = browser.find_element(
            By.CLASS_NAME, "g-recaptcha"
        ).get_attribute("data-sitekey")

        token = captcha_solver.solve_recaptcha(sitekey, browser.current_url)
        captcha_solver.inject_token(browser, token)

        browser.find_element(By.ID, "login-btn").click()

        error = browser.find_element(By.CLASS_NAME, "error-message")
        assert "Invalid" in error.text

Тест проверки

# tests/test_checkout.py
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


class TestCheckout:
    def test_checkout_flow_with_captcha(self, browser, captcha_solver, base_url):
        """Full checkout flow: add item, fill form, solve CAPTCHA, confirm."""
        # Add item to cart
        browser.get(f"{base_url}/products/test-item")
        browser.find_element(By.ID, "add-to-cart").click()

        # Go to checkout
        browser.get(f"{base_url}/checkout")

        # Fill shipping
        browser.find_element(By.ID, "address").send_keys("123 Test St")
        browser.find_element(By.ID, "city").send_keys("Test City")
        browser.find_element(By.ID, "zip").send_keys("12345")

        # Solve CAPTCHA on checkout page
        captcha_el = browser.find_element(By.CLASS_NAME, "g-recaptcha")
        sitekey = captcha_el.get_attribute("data-sitekey")

        token = captcha_solver.solve_recaptcha(sitekey, browser.current_url)
        captcha_solver.inject_token(browser, token)

        # Submit order
        browser.find_element(By.ID, "place-order").click()

        # Wait for confirmation
        wait = WebDriverWait(browser, 15)
        confirmation = wait.until(
            EC.presence_of_element_located((By.CLASS_NAME, "order-confirmation"))
        )
        assert "Thank you" in confirmation.text

Конфигурация Pytest

# tests/pytest.ini
[pytest]
markers =
    captcha: tests requiring CAPTCHA solving (cost per run)
addopts = -v --tb=short

Рабочий процесс действий GitHub

# .github/workflows/e2e-tests.yml
name: E2E Tests

on:
  push:
    branches: [main]
  schedule:

    - cron: "0 6 * * 1"  # Weekly Monday 6 AM

jobs:
  e2e:
    runs-on: ubuntu-latest
    steps:

      - uses: actions/checkout@v4

      - name: Setup Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.11"

      - name: Install dependencies
        run: pip install pytest selenium requests

      - name: Install Chrome
        uses: browser-actions/setup-chrome@latest

      - name: Run E2E tests
        env:
          CAPTCHAAI_API_KEY: ${{ secrets.CAPTCHAAI_API_KEY }}
        run: pytest tests/ -m captcha -v

Поиск неисправностей

Проблема Причина Исправить
передача токена во внутренний QA endpoint не удалось Текстовое поле не найдено Проверьте идентификатор элемента или используйте querySelector('[name="g-recaptcha-response"]').
Тесты проходят локально, проваливаются в CI Другая версия Chrome Закрепить версию Chrome в настройках CI
CAPTCHA отсутствует на этапе подготовки Постановка отключает CAPTCHA Включите CAPTCHA в настройке конфигурации env.
Тайм-аут ожидания решения Медленная сеть в CI Увеличьте время ожидания опроса до 180 секунд.

Часто задаваемые вопросы

Сколько стоит проведение тестов CAPTCHA?

Каждое решение стоит несколько центов. Ежедневная стоимость запуска набора из 10 тестов составляет менее 10 долларов США/month.. Используйте маркеры pytest для запуска тестов CAPTCHA только при необходимости.

Могу ли я имитировать CAPTCHA в модульных тестах?

Да. Высмеивайте метод CaptchaTestHelper.solve_recaptcha в модульных тестах и ​​используйте только реальные решения для интеграционных тестов E2E.

Как пропустить тесты CAPTCHA локально?

Используйте pytest -m "not captcha", чтобы пропустить тесты, отмеченные декоратором @pytest.mark.captcha.


Связанные руководства

  • Решение CAPTCHA для тестирования качества
  • CAPTCHA в тестировании CI/CD

Никогда не позволяйте CAPTCHA блокировать ваши тесты —начни с CaptchaAI.

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

Похожие сообщения

Use Cases Автоматическая отправка форм с обработкой CAPTCHA
Практическое руководство по Автоматической отработке форм CAPTCHA с реалистичными сценариями, советами по рабочему процессу и практическими действиями по исполь...

Практическое руководство по Автоматической отработке форм CAPTCHA с реалистичными сценариями, советами по рабо...

Apr 23, 2026
Tutorials Кеширование CAPTCHA-токенов в собственном backend в пределах TTL
Корректно кешируйте и переиспользуйте CAPTCHA-токены в пределах официального TTL для идемпотентных ретраев в собственном backend.

Корректно кешируйте и переиспользуйте CAPTCHA-токены в пределах официального TTL для идемпотентных ретраев в с...

May 02, 2026
Integrations Изоляция браузерных профилей для QA с CaptchaAI
Разделяйте cookies, storage, тестовые учетные записи и CAPTCHA-конфигурации по браузерным профилям, чтобы QA-тесты в staging были чистыми и воспроизводимыми.

Разделяйте cookies, storage, тестовые учетные записи и CAPTCHA-конфигурации по браузерным профилям, чтобы QA-т...

Apr 28, 2026