Как обойти капчу в Cypress
Cypress — это стандарт де-факто для E2E-тестирования современного веба. Но когда ваши автотесты сталкиваются с CAPTCHA (reCAPTCHA, Cloudflare Turnstile и др.), сценарий ломается.
Cypress работает непосредственно в браузере, исполняя команды в том же цикле выполнения, что и ваше приложение. Это делает его быстрым, но создает две фундаментальные проблемы при работе с капчей:
- Cross-domain iframes: Капчи обычно загружаются в
iframeс чужого домена. Политика безопасности браузера (Same-Origin Policy) и самого Cypress блокирует доступ к таким элементам,. - Анти-бот защита: Простого клика (
.click()) недостаточно. Современные защиты анализируют поведение мыши и сетевые отпечатки, которые у Cypress слишком «роботизированные».
Часть 1: Простой способ (Как НЕ решать капчу)
Профессиональный подход к QA подразумевает, что на средах разработки и тестирования (Development/Staging) вы не должны тратить ресурсы на решение реальной капчи. Вместо этого используйте методы обхода,.
1. Использование тестовых ключей Google
Для reCAPTCHA v2 Google предоставляет официальные тестовые ключи. Они всегда показывают виджет "No CAPTCHA", и проверка проходит мгновенно,.
Если у вас есть доступ к коду приложения, настройте его так, чтобы на тестовом стенде использовались эти ключи:
- Site key:
6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI - Secret key:
6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe
2. Мокинг запросов (Stubbing) с cy.intercept
Самый быстрый способ "пройти" капчу в Cypress — это обмануть фронтенд, подменив ответ от сервера капчи. Мы можем перехватить сетевой запрос и вернуть статус "Успех".
javascript
describe('Login bypass', () => {
it('should verify user without real captcha', () => {
// Перехватываем запрос валидации капчи на вашем бэкенде
cy.intercept('POST', '/api/validate-captcha', {
statusCode: 200,
body: { success: true, verificationPassed: true }
}).as('bypassCaptcha');
cy.visit('/login');
// ...заполнение полей...
cy.get('#submit').click();
cy.wait('@bypassCaptcha');
});
});
Часть 2: Cypress и сервис обхода (решение через API)
Если вы тестируете Production, внешний сайт (парсинг) или не можете отключить капчу, вам потребуется интеграция с API 2Captcha или SolveCaptcha.
Так как Cypress не умеет ждать асинхронных событий (вроде решения капчи) внутри синхронной цепочки команд, мы вынесем логику в Node.js процесс через cy.task.
Шаг 1: Настройка безопасности (Критически важно)
Чтобы Cypress мог взаимодействовать с элементами капчи внутри iframe (например, чтобы вставить токен), вы обязаны отключить веб-безопасность Chrome,.
В файле cypress.config.js:
javascript
const { defineConfig } = require("cypress");
const axios = require("axios");
module.exports = defineConfig({
// ВАЖНО: Разрешает доступ к cross-domain iframes
chromeWebSecurity: false,
e2e: {
setupNodeEvents(on, config) {
on("task", {
async solveCaptcha({ sitekey, pageurl, type = "recaptcha2" }) {
// Логика решения описана ниже
const API_KEY = "ВАШ_API_KEY";
try {
// 1. Создаем задачу
const { data: createData } = await axios.post("https://api.service.com/createTask", {
clientKey: API_KEY,
task: {
type: type === "turnstile" ? "TurnstileTaskProxyless" : "NoCaptchaTaskProxyless",
websiteKey: sitekey,
websiteURL: pageurl
}
});
if (!createData.taskId) throw new Error("TaskId не получен");
// 2. Ждем решения (Polling)
console.log(`Captcha task created: ${createData.taskId}`);
for (let i = 0; i < 20; i++) {
await new Promise(r => setTimeout(r, 5000)); // Ждем 5 сек
const { data: result } = await axios.post("https://api.service.com/getTaskResult", {
clientKey: API_KEY,
taskId: createData.taskId
});
if (result.status === "ready") {
return result.solution.gRecaptchaResponse || result.solution.token;
}
if (result.status === "failed") {
throw new Error("Ошибка решения капчи сервисом");
}
}
throw new Error("Таймаут ожидания решения");
} catch (e) {
return null;
}
}
});
}
}
});
Шаг 2: Использование в тесте
Теперь, когда у нас есть задача solveCaptcha, мы можем использовать её в тесте для captcha automation. Мы получаем токен и принудительно вставляем его в скрытое поле формы, имитируя успешное прохождение проверки.
Пример для reCAPTCHA v2:
javascript
describe('Automated Captcha Solver Test', () => {
it('bypasses reCAPTCHA automatically', () => {
const pageUrl = 'https://example.com/login';
const siteKey = '6Lc_aXkUAAAAA...'; // Найдите в исходном коде страницы (data-sitekey)
cy.visit(pageUrl);
// Вызываем задачу решения
cy.task('solveCaptcha', { sitekey: siteKey, pageurl: pageUrl })
.then((token) => {
if (!token) throw new Error('Не удалось получить токен капчи');
// Вставляем токен в скрытое поле
cy.get('#g-recaptcha-response')
.invoke('attr', 'style', 'display: block') // Делаем поле видимым (для отладки)
.invoke('val', token);
// Иногда нужно вызвать callback-функцию сайта (если есть)
// cy.window().then(win => win.onCaptchaSuccess(token));
cy.get('#submit-btn').click();
});
cy.url().should('include', '/dashboard');
});
});
Пример для Cloudflare Turnstile:
Логика идентична, меняется только селектор поля:
javascript
cy.task('solveCaptcha', {
type: 'turnstile',
sitekey: '0x4AAAAAA...',
pageurl: 'https://example.com'
}).then(token => {
cy.get('[name="cf-turnstile-response"]').invoke('val', token);
cy.get('form').submit();
});
Troubleshooting: Что делать, если не работает?
Даже с правильным кодом анти-бот системы могут блокировать Cypress.
-
Проблема с Headless Mode:
Некоторые капчи ведут себя агрессивнее, если браузер запущен в headless-режиме (без интерфейса). Попробуйте запустить тест с флагом--headed, чтобы проверить, решит ли это проблему. -
Обнаружение автоматизации:
Сайт может видеть глобальные переменныеwindow.Cypress. В сложных случаях (Cloudflare, Akamai) обычного Cypress недостаточно. Рассмотрите возможность интеграции анти-детект браузеров или специальных плагинов (например,cypress-plugin-stripe), которые маскируют факт автоматизации,. -
Форма не отправляется после вставки токена:
Современные фреймворки (React, Angular) могут не "увидеть", что вы изменили значение поля через.invoke('val'). После вставки токена попробуйте принудительно вызвать событие:javascriptcy.get('#g-recaptcha-response').invoke('val', token).trigger('change');
Заключение
Автоматизация капчи в Cypress (Cypress captcha automation) требует обходных путей, так как инструмент создан для тестирования, а не для обхода защиты.
- Для staging сред всегда используйте моки (
cy.intercept) или тестовые ключи Google. - Для production используйте API-решатели через
cy.taskс обязательным отключениемchromeWebSecurity.