Se a sua suíte Puppeteer passa por login, formulário e clique, mas trava no widget reCAPTCHA ou Turnstile da tela seguinte, o problema quase nunca é o navegador — falta um passo que resolva o desafio e devolva o token ao campo certo. Este guia conecta a API da CaptchaAI a um runner Puppeteer dentro do seu próprio ambiente: staging, pré-produção ou QA interno. Os exemplos usam páginas de teste, dados fictícios e endpoints controlados pela sua equipe — nada aqui automatiza login real, fila pública ou serviço de terceiros.
Ambiente e escopo do teste
Use o Puppeteer apenas em páginas próprias, como https://staging.example.com/qa-form, https://staging.example.com/captcha-demo e https://staging.example.com/checkout-test. Se o seu time ainda não tem uma página de staging com CAPTCHA de teste, crie uma antes de automatizar qualquer coisa — testar contra produção ou contra sites de terceiros fica fora do escopo deste guia.
Por que a suíte trava no widget CAPTCHA
Três causas respondem pela maioria dos testes que falham nesse ponto: o widget carrega de forma assíncrona e o seletor é consultado cedo demais; o campo que recebe o token vive dentro de um iframe, não no documento principal; ou o valor foi escrito no campo certo, mas o evento que avisa o formulário nunca foi disparado. A CaptchaAI resolve o desafio e devolve o token — cabe ao seu runner aguardar o widget certo, escrever no campo certo e, quando necessário, disparar o evento correto.
Configurando o runner Puppeteer para QA
Rode o Chrome no modo padrão do seu pipeline de teste, com logging, traces e variáveis de ambiente para a sitekey de QA. Use usuários fictícios, formulários fictícios e pagamento em sandbox — nunca dados reais.
import os, time, requests
API_KEY = os.environ['CAPTCHAAI_API_KEY']
SITEKEY = os.environ['QA_CAPTCHA_SITEKEY']
def criar_tarefa_captcha(pageurl):
resposta = requests.post('https://ocr.captchaai.com/in.php', data={
'key': API_KEY,
'method': 'userrecaptcha',
'googlekey': SITEKEY,
'pageurl': pageurl,
'json': 1,
}).json()
return resposta['request']
def aguardar_resultado(task_id):
while True:
time.sleep(5)
resposta = requests.get('https://ocr.captchaai.com/res.php', params={
'key': API_KEY,
'action': 'get',
'id': task_id,
'json': 1,
}).json()
if resposta.get('status') == 1:
return resposta['request']
task_id = criar_tarefa_captcha('https://staging.example.com/qa-form')
token_qa = aguardar_resultado(task_id)
print({'token_recebido': bool(token_qa)})
Detectando o widget na página de staging
Antes de enviar qualquer tarefa à CaptchaAI, aguarde o seletor do widget aparecer no DOM, leia os atributos públicos da página (sitekey, tipo de desafio) e confirme que a pageurl corresponde ao domínio de staging esperado. Um erro comum: o script capturar a sitekey de produção por engano quando os dois ambientes compartilham o mesmo template de página.
import os, time, requests
API_KEY = os.environ['CAPTCHAAI_API_KEY']
SITEKEY = os.environ['QA_CAPTCHA_SITEKEY']
def criar_tarefa_captcha(pageurl):
resposta = requests.post('https://ocr.captchaai.com/in.php', data={
'key': API_KEY,
'method': 'userrecaptcha',
'googlekey': SITEKEY,
'pageurl': pageurl,
'json': 1,
}).json()
return resposta['request']
def aguardar_resultado(task_id):
while True:
time.sleep(5)
resposta = requests.get('https://ocr.captchaai.com/res.php', params={
'key': API_KEY,
'action': 'get',
'id': task_id,
'json': 1,
}).json()
if resposta.get('status') == 1:
return resposta['request']
task_id = criar_tarefa_captcha('https://staging.example.com/qa-form')
token_qa = aguardar_resultado(task_id)
print({'token_recebido': bool(token_qa)})
Enviando a tarefa e aguardando o token
Com o tipo, a sitekey e a URL confirmados, envie a tarefa à CaptchaAI a partir do próprio runner de QA e aguarde o token via polling. O tempo de resposta varia por tipo de desafio; trate variações pontuais como amostra interna, não como regressão automática do pipeline.
import os, time, requests
API_KEY = os.environ['CAPTCHAAI_API_KEY']
SITEKEY = os.environ['QA_CAPTCHA_SITEKEY']
def criar_tarefa_captcha(pageurl):
resposta = requests.post('https://ocr.captchaai.com/in.php', data={
'key': API_KEY,
'method': 'userrecaptcha',
'googlekey': SITEKEY,
'pageurl': pageurl,
'json': 1,
}).json()
return resposta['request']
def aguardar_resultado(task_id):
while True:
time.sleep(5)
resposta = requests.get('https://ocr.captchaai.com/res.php', params={
'key': API_KEY,
'action': 'get',
'id': task_id,
'json': 1,
}).json()
if resposta.get('status') == 1:
return resposta['request']
task_id = criar_tarefa_captcha('https://staging.example.com/qa-form')
token_qa = aguardar_resultado(task_id)
print({'token_recebido': bool(token_qa)})
Validando a resposta no endpoint interno
O backend interno da sua aplicação deve validar o token recebido e devolver um dos três estados que a suíte espera: pass, fail ou retryable_error. Esse contrato evita que um timeout de rede vire falso negativo no relatório de QA — a retentativa com backoff trata o retryable_error separadamente de um fail definitivo.
Logs que sustentam a auditoria
Grave trace id, screenshot do momento do teste, task id retornado pela CaptchaAI, tempo de resposta, status do backend e o commit da aplicação testada. Esse conjunto mínimo permite reconstruir qualquer execução semanas depois, quando alguém perguntar por que um teste específico passou ou falhou naquele dia.
Quando o navegador falha e a API funciona
Se a chamada direta à API resolve o desafio, mas o teste no navegador continua falhando, compare quatro pontos: timing entre carregamento do widget e consulta do seletor, renderização do iframe que recebe o token, domínio autorizado no widget de staging e a action configurada para o reCAPTCHA v3. Na prática, a maioria dos casos se resolve com um waitForSelector antes da detecção ou corrigindo o iframe alvo da injeção.
Checklist antes de publicar a mudança
Antes de mesclar a mudança testada, confirme que a documentação aponta para o ambiente próprio, que os exemplos usam dados fictícios, que nenhum endpoint de produção é acionado durante o teste e que os logs guardam correlação suficiente para auditoria. A página de staging deve ter domínio autorizado, sitekey esperada, configuração de backend separada da produção e uma política clara de expiração dos dados de teste. Quando o resultado variar entre execuções, trate os números como amostra interna: repita a medição, anote a janela e compare apenas cenários equivalentes.
Perguntas frequentes
O CaptchaAI não resolve hCaptcha nesse tipo de teste, certo?
Correto. Hoje o CaptchaAI resolve reCAPTCHA v2, reCAPTCHA v3, Cloudflare Turnstile e GeeTest v3. hCaptcha e FunCaptcha não são suportados — se a sua página de staging usa um desses widgets, o teste precisa de outra estratégia.
Dá para rodar esses testes em pipeline de CI, tipo GitHub Actions?
Sim. O runner roda como qualquer outro job headless: Chrome em modo padrão, variáveis de ambiente para a chave de API e a sitekey de QA, e o mesmo fluxo de detecção, envio e validação. O cuidado é isolar o staging usado pelo CI do ambiente usado por desenvolvedores em paralelo, para não misturar dados de teste.
Quantos testes de CAPTCHA posso rodar em paralelo?
Depende do número de threads do seu plano CaptchaAI — cada thread processa uma tarefa por vez. O plano BASIC (US$ 15/mês, 5 threads) já cobre uma suíte pequena rodando em série ou com pouco paralelismo; suítes maiores em CI costumam usar planos com mais threads para não enfileirar tarefas.
Preciso reescrever o teste toda vez que o site muda o tipo de desafio?
Normalmente não. Como o runner detecta o tipo de desafio (reCAPTCHA v2, v3 ou Turnstile) em tempo de execução, uma mudança de tipo costuma exigir só ajustar o dicionário de parâmetros enviado à CaptchaAI — não reescrever a suíte.
Guias relacionados
- Comece pelo início rápido da CaptchaAI
- Padrões de testes QA autorizados com CAPTCHA
- Como testar o endpoint CAPTCHA em formulários próprios
- O que fazer quando o navegador falha e a API funciona
- Como resolver reCAPTCHA v2 com a API
- Como resolver Cloudflare Turnstile com a API
- Como resolver GeeTest v3 com a API
Valide a integração CAPTCHA do seu Puppeteer em ambiente próprio com a CaptchaAI.