Quando um teste de CAPTCHA passa na sua máquina e falha no runner de CI, o culpado costuma ser o mesmo: o user agent não é igual nas três pontas do fluxo. O navegador headless usa um, a biblioteca HTTP usa outro e a chamada à API de resolução não envia nenhum. A correção é tratar o user agent como configuração da suíte, definida em um lugar só e propagada para as demais etapas.
O escopo é restrito: ambiente próprio, QA ou staging com autorização explícita, sempre com páginas internas, dados fictícios e endpoints da sua equipe.
Por que o user agent quebra testes de CAPTCHA
O widget e o backend do provedor observam o contexto da requisição, e o user agent faz parte dele. Em QA, isso vira problema recorrente.
| Sintoma no pipeline | Causa comum |
|---|---|
| Passa local, falha no CI | O runner usa outra versão de navegador |
| Token aceito no navegador, recusado no backend | O user agent do navegador não foi enviado junto na resolução |
| Resultados que variam entre execuções | Cada worker monta os cabeçalhos por conta própria |
| Quebra após atualizar a imagem Docker | A string do navegador mudou sem registro |
Nada disso tem a ver com esconder automação, e sim com eliminar variáveis para que a falha signifique alguma coisa. Se o user agent muda sozinho, você não sabe se o defeito está na integração ou no ambiente.
Um user agent por caso de teste, definido em um só lugar
Cada caso de QA escolhe um user agent no início e usa essa string até o fim — na requisição que carrega a página, no driver do Selenium, na chamada de resolução e no log. Na prática, isso vira uma variável de ambiente ou um campo de fixtures:
QA_USER_AGENTdefinido no compose do staging, nunca sorteado dentro do teste;- o mesmo valor injetado na sessão HTTP, no
webdrivere no payload enviado à API; - o valor gravado no registro do caso, para que a execução seja reproduzível depois.
Para cobrir vários navegadores, declare uma matriz fixa — Chrome no Linux, Firefox no Linux, Chrome no Windows — em vez de sortear. Matriz é reproduzível; sorteio é ruído.
Modelo de página staging para o teste
Antes do código, monte a página de teste: sitekey de QA, usuário fictício, payload previsível e endpoint de verificação separado da produção. Use identificadores como qa_user_001 e qa_case_001. O backend só deve aceitar tokens do domínio de staging e gravar o resultado em uma tabela de testes, nunca na base de produção.
Enviar a tarefa à CaptchaAI a partir do runner
Com a página no ar, o runner envia a tarefa e guarda o ID. O exemplo usa reCAPTCHA v2 em uma página interna.
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/captcha-demo')
token_qa = aguardar_resultado(task_id)
print({'token_recebido': bool(token_qa)})
Grave o task_id ao lado do qa_case_001 e do user agent escolhido: quando um teste falhar semanas depois, essa tripla é o que permite reconstruir o caso.
Validar a resposta no backend de QA
Recebido o token, encaminhe-o a um endpoint interno como https://staging.example.com/qa-captcha/verify, que valida a resposta junto ao provedor e devolve só um resultado de teste, com o motivo.
Um erro comum: o time envia a resolução pelo runner, mas verifica o token em um serviço com outra configuração. Mantenha a verificação no mesmo ambiente lógico da página de staging.
O que registrar em log
Registre a cada execução: sitekey, pageurl, tipo de CAPTCHA, user agent, horário de envio, tempo de resposta, status do backend e o caso de QA. São campos suficientes para depurar regressões sem expor dado sensível.
Se a equipe opera no Brasil ou em Portugal, vale um cuidado de conformidade: a LGPD (e a RGPD, do lado europeu) alcança logs de teste com dado pessoal real. Como a suíte roda com dados fictícios, o log já nasce limpo — mas confirme com a área responsável antes de detalhar mais.
Quando o teste falha: por onde começar
Percorra na ordem, do mais barato ao mais caro de verificar.
- Sitekey e domínio. A sitekey de QA está liberada para o domínio de staging que o teste realmente acessa?
- Expiração do token. Entre resolver e verificar, quanto tempo passou? A janela é curta.
- Relógio do runner. Horário fora de sincronia produz falhas intermitentes que parecem aleatórias.
- User agent. Compare o valor efetivo no navegador, na sessão HTTP e no que foi enviado à API.
- Navegador versus API. Se o fluxo via API funciona e o do navegador não, o problema está na automação, não na resolução.
Faça retentativas com backoff exponencial apenas dentro da suíte de QA e sempre com teto: repetir sem limite mascara o defeito.
Critérios antes de publicar a mudança
Antes de promover a mudança, confirme que os exemplos usam dados fictícios, que nenhum endpoint de produção é acionado e que os logs têm correlação para auditoria. A página de staging precisa de domínio autorizado, sitekey esperada, backend separado e política clara de expiração.
Quando um número variar entre execuções, trate-o como amostra interna: repita a medição e compare só cenários equivalentes. O custo é fácil de dimensionar, porque os planos da CaptchaAI são por threads simultâneas: uma suíte de QA raramente passa do BASIC (US$ 15/mês, 5 threads), e pipelines com vários jobs em paralelo cabem no STANDARD (US$ 30/mês, 15 threads).
Perguntas frequentes
Preciso mesmo enviar o user agent na chamada de resolução?
Envie sempre que o fluxo passar por um navegador. A mesma string no navegador, no runner e na chamada à API elimina uma variável inteira do diagnóstico.
Posso deixar o teste sortear um user agent a cada execução?
Não em QA. O sorteio quebra a reprodução: duas execuções do mesmo caso deixam de ser comparáveis. Declare uma matriz fixa.
Quais tipos de CAPTCHA posso exercitar nessa suíte?
reCAPTCHA v2 e v3, Cloudflare Turnstile e Challenge, GeeTest v3, CAPTCHAs de imagem/OCR e de grade, além de CaptchaFox (beta), Friendly Captcha (beta) e Lemin (beta). Fora dessa lista, planeje outro caminho de teste: hCaptcha e FunCaptcha não entram no escopo suportado, e o GeeTest v4 ainda está em breve.
Com que frequência devo revisar as strings de navegador da suíte?
Reveja quando a imagem base do CI mudar de versão de navegador. Fixe o valor no ambiente e registre a alteração no changelog da suíte.
Dá para rodar esses testes sem navegador nenhum?
Dá. Para validar só a integração com a API e o endpoint de verificação, o fluxo HTTP puro basta e é mais rápido no CI. Reserve o navegador para os casos que exercitam o widget.
Guias relacionados seguros
- Comece pelo guia de início rápido
- Como estruturar testes de CAPTCHA autorizados
- Testar endpoints de CAPTCHA em formulários próprios
- O navegador falha e a API funciona: como depurar
- Resolver reCAPTCHA v2 pela API
- Resolver Cloudflare Turnstile pela API
- Resolver GeeTest v3 pela API
Monte sua suíte de QA de CAPTCHA em staging e resolva o primeiro desafio com a CaptchaAI.