Integrations

Selenium Wire + CaptchaAI para inspeção de requests em QA

Quando um teste com CAPTCHA falha, a captura de tela quase nunca explica o motivo. A resposta está no tráfego HTTP: qual sitekey o widget carregou, em qual domínio, quanto tempo o token levou para voltar e o que o backend respondeu. O Selenium Wire entrega esse tráfego como objetos Python dentro do teste, e a CaptchaAI resolve o desafio pela API enquanto o runner segue rodando. Este guia combina as duas peças em staging, com dados fictícios e verificação separada da produção.

O que o Selenium Wire acrescenta ao Selenium padrão

Recurso Selenium padrão Selenium Wire
Ler requisições da página Não Sim, como objetos Python
Ajustar cabeçalhos Limitado Controle total
Inspecionar o corpo das respostas Não Sim
Log de rede Apenas via DevTools Direto na asserção do teste

A divisão de responsabilidades é clara: o Selenium Wire observa o que a página pediu, e a CaptchaAI resolve o desafio. Sem observação, você só sabe que o teste quebrou; com ela, sabe onde a quebra começou.

Escopo autorizado deste guia

Tudo aqui vale para ambientes próprios: QA, staging ou pré-produção com autorização explícita. Os exemplos usam páginas internas, contas fictícias e endpoints que a sua equipe controla.

Como preparar a página de staging

A página de teste reproduz o fluxo técnico sem gerar efeito real para clientes:

  • uma sitekey (chave pública do widget) emitida para o domínio de staging;
  • um formulário com campos previsíveis, preenchido por um usuário fictício;
  • um endpoint de verificação separado, gravando em tabela de testes;
  • expiração explícita, para o teste falhar quando o token chegar tarde.

Use identificadores rastreáveis como qa_user_001, qa_session_001 e qa_case_001. Semanas depois, eles dizem qual caso gerou qual requisição.

Passo 1: capture a sitekey e a pageurl no tráfego

Depois de carregar a página, percorra driver.requests atrás das chamadas do widget: a URL do iframe do reCAPTCHA traz a sitekey como parâmetro, e o Cloudflare Turnstile aparece com host próprio. Ler esses valores do tráfego costuma ser mais confiável do que fazer parsing do DOM, já que o widget pode estar em um iframe fora do alcance do seletor. Guarde a sitekey e a URL atual.

Passo 2: envie a tarefa à CaptchaAI

Envie a partir do runner autorizado e guarde o ID da tarefa. O padrão é sempre o mesmo: POST para in.php e consultas em res.php até o status voltar como concluído.

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)})

O intervalo de 5 segundos entre consultas é um bom ponto de partida: consultar a cada 500 ms não acelera nada e só multiplica respostas vazias.

Passo 3: entregue o token ao endpoint de verificação

Com o token em mãos, preencha o campo g-recaptcha-response e envie a requisição a um endpoint interno como https://staging.example.com/qa-captcha/verify. O backend valida a resposta junto ao provedor e devolve apenas um resultado de teste — nunca uma sessão real.

Faça a asserção sobre a resposta do backend, não sobre a presença do token na página: o token existir prova apenas que a API respondeu.

O que registrar em log — e o que deixar de fora

Grave sitekey, pageurl, tipo de CAPTCHA, horário de envio, tempo até o token, status do backend e o identificador do caso. Com isso, uma regressão intermitente vira gráfico em vez de palpite.

Deixe de fora qualquer dado pessoal real. Com dados fictícios, o log de QA não carrega informação de pessoas naturais — o que simplifica a conversa sobre a LGPD (RGPD, em Portugal) ao definir a retenção dos artefatos.

Cenário: uma suíte noturna rodando em sa-east-1

Imagine um time em São Paulo com 40 casos que passam por um formulário com reCAPTCHA v2 em staging. O runner fica em sa-east-1 para manter o RTT baixo e a suíte roda de madrugada, antes do deploy da manhã.

Em sequência, cada resolução espera a anterior e a janela noturna fica apertada. Com quatro casos em paralelo, o plano BASIC (US$ 15/mês, 5 threads) cobre a suíte inteira: a cobrança é por thread simultânea, com resoluções ilimitadas por thread. Se a suíte passar a rodar a cada pull request, o STANDARD (US$ 30/mês, 15 threads) absorve o pico sem mudar o código.

Quando o teste falha: causas comuns

Sintoma Causa provável O que fazer
Nenhuma requisição capturada Asserção antes de o widget carregar Espere o elemento do CAPTCHA
Token recusado pelo backend pageurl diferente do domínio de staging Envie a URL exata da página
Sitekey inválida Chave copiada de outra página Use a sitekey do domínio de QA
Token expirado Intervalo longo até o envio do formulário Resolva perto do submit
Erro de SSL na inspeção Certificado do proxy local do Selenium Wire Instale o certificado do proxy no runner
Memória do runner subindo Histórico de requisições acumulado Limpe as requisições a cada caso

Retentativas com backoff cabem dentro da suíte de QA, sempre com teto de tentativas: uma falha que se repete três vezes é sinal, não ruído.

Checklist antes de subir a mudança

Confirme que os exemplos usam dados fictícios, que nenhum endpoint de produção é acionado e que os logs permitem auditoria. Quando os tempos variarem, trate os números como amostra interna e compare cenários equivalentes.

Perguntas frequentes

Preciso do Selenium Wire só para resolver o CAPTCHA?

Não. A API da CaptchaAI funciona sem navegador — bastam a sitekey e a pageurl. O Selenium Wire entra quando você precisa descobrir esses valores automaticamente ou entender por que um caso falhou.

Dá para rodar esse fluxo em modo headless no CI?

Sim. O navegador headless captura o mesmo tráfego e o polling não depende de interface gráfica. Guarde o log de rede como artefato do job.

Esses testes cobrem hCaptcha ou FunCaptcha?

Não. A CaptchaAI não resolve hCaptcha nem FunCaptcha (Arkose Labs). Os tipos cobertos aqui são reCAPTCHA v2 e v3, Cloudflare Turnstile, GeeTest v3 e desafios de imagem, grade e OCR; CaptchaFox, Friendly Captcha e Lemin estão em beta. O GeeTest v4 é anunciado como em breve.

Quantas threads a minha suíte precisa?

Uma thread por caso executado em paralelo. Cinco casos simultâneos pedem 5 threads; escolha o plano pelo paralelismo, não pelo total de desafios do mês.

O tempo de resolução deve entrar no timeout do teste?

Sim, mas separe as medidas: meça o tempo da API à parte do tempo total do caso, para que uma resolução demorada apareça como métrica, não como teste vermelho.

Guias relacionados

Valide a integração de CAPTCHA do seu ambiente de staging com a CaptchaAI.

Os comentários estão desativados para este artigo.