Como resolver problemas com captchas em testes automatizados

Abordagens para lidar com códigos de verificação

Ao automatizar testes, frequentemente encontramos formulários protegidos por captchas. Duas estratégias comuns são:

  • Solicitar ao desenvolvedor que desabilite o captcha em ambiente de teste ou utilize um código universal.
  • Empregar reconhecimento óptico de caracteres (OCR) para interpretar a imagem.

Focaremos na segunda opção, utilizando o Tesseract-OCR (disponível em repositório oficial).

Preparação da página de teste

Para reproduzir o cenário, crie um HTML simples que exiba um captcha:


<html>
<head>
    <title>Página de Teste com Captcha</title>
</head>
<body>
    <h1>Validação</h1>
    <img src="http://exemplo.com/captcha.aspx?token=123" alt="captcha">
</body>
</html>

Capturando a imagem do elemento

O primeiro passo é obter a parte da tela que contém o captcha. Fazemos um screenshot completo e recortamos a região do elemento:

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;

public class CaptchaHelper {

    /**
     * Captura a imagem de um elemento Web na tela.
     * @param driver WebDriver ativo
     * @param element Elemento alvo
     * @param outputPath Caminho para salvar a imagem
     */
    public static void captureElementImage(WebDriver driver, WebElement element, String outputPath) {
        File screenshot = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        try {
            Point location = element.getLocation();
            int width = element.getSize().getWidth();
            int height = element.getSize().getHeight();
            BufferedImage fullImg = ImageIO.read(screenshot);
            BufferedImage elementImg = fullImg.getSubimage(location.getX(), location.getY(), width, height);
            ImageIO.write(elementImg, "png", screenshot);
            FileUtils.copyFile(screenshot, new File(outputPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

Executando o Tesseract via linha de comando

Após salvar a imagem, utilizamos o executável do Tesseract para extrair o texto:

Runtime runtime = Runtime.getRuntime();
String command = "cmd.exe /C tesseract.exe C:\\ocr\\captcha.png C:\\ocr\\resultado -1";
runtime.exec(command);

Lietura do arquivo de resultado

O Tesseract gera um arquivo .txt. Lemos seu conteúdo:

import java.io.*;

public class FileReaderUtil {

    public static String readFileContent(String filePath) {
        StringBuilder content = new StringBuilder();
        try (BufferedReader reader = new BufferedReader(
                new InputStreamReader(new FileInputStream(filePath), "GBK"))) {
            String line;
            while ((line = reader.readLine()) != null) {
                content.append(line).append("\n");
            }
        } catch (IOException e) {
            System.err.println("Erro ao ler arquivo: " + e.getMessage());
        }
        return content.toString().trim();
    }

}

Integração completa

Exemplo de classe principal que orquestra o fluxo:

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.concurrent.TimeUnit;

public class CaptchaTest {

    public static void main(String[] args) throws InterruptedException {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
        driver.get("file:///C:/teste/captcha.html");

        WebElement imgCaptcha = driver.findElement(By.tagName("img"));
        CaptchaHelper.captureElementImage(driver, imgCaptcha, "C:\\ocr\\captcha.png");
        driver.quit();

        // Executa OCR
        Runtime rt = Runtime.getRuntime();
        rt.exec("cmd.exe /C tesseract.exe C:\\ocr\\captcha.png C:\\ocr\\resultado -1");
        Thread.sleep(2000);

        // Exibe texto reconhecido
        String textoExtraido = FileReaderUtil.readFileContent("C:\\ocr\\resultado.txt");
        System.out.println("Captcha reconhecido: " + textoExtraido);
    }

}

Essa abordagem funciona bem para captchas simples, mas pode falhar com ruídos ou distorções. Para produção, considere serviços especializados.

Tags: Tesseract-OCR Automação de Testes Selenium WebDriver reconhecimento óptico de caracteres CAPTCHA

Publicado em 6-23 17:24