A Arte De Iluminar O Passado: Selenium E A Arqueologia De Bugs Em Sistemas Legados

PRÓLOGO: O CHAMADO DO LEGADO
Era uma manhã comum de dezembro quando recebi o chamado. Do outro lado da linha, a voz preocupada do gerente de TI: "Temos um problema. O sistema de gestão que roda há mais de uma década começou a apresentar falhas críticas. Os usuários não conseguem salvar, editar ou excluir registros em módulos essenciais. Pior ainda: não temos documentação atualizada dos testes."
O sistema em questão era uma aplicação JavaEE monolítica, construída em uma época onde frameworks como Spring Boot ainda não dominavam o mercado. WildFly (anteriormente JBoss), JPA, Hibernate, Stored Procedures SQL Server, AngularJS 1.x no frontend - uma verdadeira cápsula do tempo tecnológica, mas que ainda processava operações críticas de negócio todos os dias.
Como muitos sistemas legados em grandes organizações, ele sofria do "paradoxo da essencialidade": era vital demais para ser substituído rapidamente, mas antigo demais para ter uma equipe completa dedicada à sua manutenção. E agora, bugs silenciosos começavam a emergir das profundezas do código.
Este é o relato de como transformamos o Selenium, uma ferramenta de automação web, em uma máquina do tempo visual - capaz não apenas de encontrar bugs, mas de contar suas histórias através de vídeos que documentam cada falha e cada vitória na jornada de correção.
CAPÍTULO 1: O SILÊNCIO DOS BUGS
O primeiro desafio foi entender a natureza dos problemas. Os usuários relatavam que ao tentar salvar uma nova empresa no módulo de administração, o sistema simplesmente não respondia. Nenhuma mensagem de erro. Nenhum feedback. Apenas silêncio.
Em sistemas modernos, com logs estruturados e ferramentas de APM (Application Performance Monitoring), rastrear isso seria questão de minutos. Mas em sistemas legados, especialmente aqueles que evoluíram através de múltiplas equipes ao longo de anos, a história é diferente.
O código tinha camadas sobre camadas:
- Frontend AngularJS 1.x com lógica de negócio misturada aos controllers
- APIs REST construídas com JAX-RS, mas sem seguir completamente RESTful
- Camada de negócio usando JPA e Hibernate, mas também JDBC direto
- Stored Procedures SQL Server que misturavam lógica de dados e regras de negócio
- Configurações XML espalhadas por diferentes arquivos
- Dependências que não eram atualizadas há anos por medo de quebrar algo
Como você testa algo assim? Como você documenta bugs de forma que qualquer pessoa - desenvolvedor, analista de negócio, ou até mesmo o usuário final - possa entender exatamente o que está errado?
A resposta veio em três palavras: automação, visualização e narrativa.
CAPÍTULO 2: SELENIUM COMO TESTEMUNHA OCULAR
Selenium WebDriver não é apenas uma ferramenta para automatizar testes. Quando usado criativamente, torna-se uma testemunha ocular digital - capaz de observar, documentar e reportar exatamente o que acontece na interface do usuário, frame por frame.
Minha estratégia foi construir um framework de testes que não apenas verificasse se algo funciona ou não, mas que MOSTRASSE o que acontecia. Para isso, desenvolvi um sistema baseado em Python com os seguintes pilares:
1. GRAVAÇÃO DE VÍDEO CONTÍNUA
Cada teste Selenium inicia gravando a tela usando OpenCV e pyautogui. Não capturas de tela estáticas - vídeos completos em 1920x1080 a 30 FPS. Isso permite ver não apenas o estado final, mas toda a jornada: cada clique, cada campo preenchido, cada espera de carregamento.

2. TIMESTAMPS E CONTEXTO
Cada ação importante é marcada no tempo. Quando o teste preenche um campo, o timestamp é registrado. Quando clica em salvar, outro timestamp. Quando verifica se o registro aparece na listagem, mais um timestamp. Isso permite correlacionar o vídeo com os logs de teste e até com logs do servidor.
3. MODO DUAL: ANTES E DEPOIS
Aqui está a mágica: cada bug tem DOIS vídeos. O primeiro, gravado antes da correção, mostra o comportamento incorreto em toda sua glória - ou horror. O segundo, gravado após a correção, demonstra que o problema foi resolvido. É a prova definitiva, visual e irrefutável.
4. ESTRUTURA DE CARDS
Para cada bug, criamos um "card" - um documento de texto estruturado que contém: título, descrição, passos para reprodução, resultado esperado vs atual, evidências (links para os vídeos), e um campo para a tag de commit da correção. É como um JIRA card, mas completamente rastreável e versionado junto com o código de teste.
CAPÍTULO 3: A ANATOMIA DE UM BUG LEGADO
Vou contar a história de um bug específico - vamos chamá-lo de BUG-003.
O SINTOMA
O módulo "Manter Empresa" permitia visualizar empresas cadastradas, mas não permitia criar, editar ou excluir nenhuma. Era como ter uma biblioteca onde você pode ver os livros, mas não pode tocá-los.
A INVESTIGAÇÃO
O teste Selenium revelou algo interessante. Quando você preenchia o formulário e clicava em "Salvar", o navegador enviava uma requisição HTTP POST para a API. A requisição retornava HTTP 200 OK. Mas quando voltava para a listagem, o registro não estava lá.
Isso significava que o problema não estava no frontend. A requisição estava sendo feita corretamente. O backend estava respondendo sem erro. Mas os dados não estavam sendo persistidos.
O MERGULHO NO CÓDIGO
Aqui começou a arqueologia de código. O caminho do dado era:
- AngularJS Controller → enviava objeto JSON com os dados
- JAX-RS Resource → recebia e chamava o serviço
- Serviço de Negócio → aplicava regras e chamava o DAO
- DAO JPA → usava EntityManager para chamar Stored Procedure
- Stored Procedure → SQL Server, lógica de CRUD
Em qual camada estava o problema? O vídeo do Selenium mostrava que a UI funcionava. Os logs mostravam que a requisição chegava ao backend. O banco tinha os dados antigos, mas não os novos.
A REVELAÇÃO
Após horas de debugging, descobri: a Stored Procedure retornava um ResultSet com os dados, seguido de parâmetros de saída. O Hibernate/JPA estava tentando mapear esse ResultSet para a entidade JPA, mas como era resultado de uma SP (não de uma query nativa simples), entrava em conflito com o gerenciamento de contexto de persistência.
O resultado? A operação executava, mas o Hibernate não commitava a transação corretamente. Os dados ficavam em um limbo - nem salvos, nem rejeitados.
A SOLUÇÃO CRIATIVA
A correção exigiu criatividade: abandonar o JPA para essa operação específica e usar JDBC puro através do Session.doWork() do Hibernate. Isso deu controle total sobre o CallableStatement, permitindo processar primeiro o ResultSet, depois os parâmetros de saída, exatamente na ordem que a SP esperava.
Mas havia outro problema: o frontend enviava apenas o ID ao deletar, mas o backend esperava o objeto completo devido a como o Jackson desserializava JSON. A solução: aceitar Map<String,Object> no endpoint de exclusão.
A PROVA VISUAL
O vídeo "ANTES" do Selenium mostrava: formulário preenchido, botão clicado, volta para listagem, registro não aparece. Frustração visual pura.
O vídeo "DEPOIS" mostrava: formulário preenchido, botão clicado, volta para listagem, registro ESTÁ LÁ. O gosto da vitória em 30 segundos de MP4.
CAPÍTULO 4: A ESTRUTURA QUE SUSTENTA A MAESTRIA
Construir testes automatizados para sistemas legados é como fazer arqueologia: você precisa de ferramentas especializadas e muita paciência. Aqui está a estrutura que desenvolvi:
ORGANIZAÇÃO PROFISSIONAL
testes/
├── 01_plano-teste/ # Estratégia e planejamento
│ ├── PLANO_MESTRE_TESTES.md
│ └── ESTRATEGIA_AUTOMACAO.md
├── 02_ambientes/ # Configs de dev, qa, prod
│ └── config.env.template
├── 03_casos-teste/ # Testes organizados por tipo
│ ├── funcional/
│ │ └── bug/
│ │ ├── test_bug001_*.py
│ │ ├── test_bug002_*.py
│ │ └── test_bug003_*.py
│ ├── integracao/
│ └── regressao/
├── 04_evidencias/ # Vídeos e screenshots
│ ├── videos/
│ │ ├── BUG-003_ANTES.mp4
│ │ └── BUG-003_DEPOIS.mp4
│ └── screenshots/
├── 05_relatorios/ # Cards de bugs e relatórios
│ └── bugs/
│ └── CARD_BUG-003.txt
├── 06_dados-teste/ # Massa de dados
└── 07_ferramentas/ # Utilitários
├── src/
│ ├── utils/
│ │ ├── video_recorder.py
│ │ └── selenium_base.py
│ └── config/
└── templates/
PADRÕES DE CÓDIGO
Cada teste segue uma estrutura narrativa:
class TestBug003Empresa:
"""
BUG-003: Manter Empresa - CRUD não funciona
Evidências: videos/BUG-003_*.mp4
"""
def setup_method(self):
"""Prepara ambiente: inicia gravação de vídeo"""
self.recorder = VideoRecorder("BUG-003")
self.driver = self.init_selenium()
def test_001_criar_empresa_deve_persistir(self):
"""
CENÁRIO: Criar nova empresa
DADO que estou na tela de Manter Empresa
QUANDO preencho os dados e salvo
ENTÃO o registro deve aparecer na listagem
"""
# Código do teste
def teardown_method(self):
"""Finaliza: salva vídeo com timestamp"""
self.recorder.stop()
self.driver.quit()
GRAVAÇÃO INTELIGENTE
O VideoRecorder não apenas grava - ele contextualiza:
- Nome do arquivo:
2026_01_15_08_18_38_BUG-003_Empresa_CRUD.mp4 - Resolução: 1920x1080 (full HD, legível em qualquer tela)
- FPS: 30 (fluido, não robotizado)
- Codec: H.264 (compatível com qualquer player)
- Metadata: timestamp de início, nome do teste, resultado
CAPÍTULO 5: OS DESAFIOS DA JORNADA
Nem tudo foram flores. Testar sistemas legados com Selenium traz desafios únicos:
1. ESPERAS IMPREVISÍVEIS
AngularJS 1.x não tem indicadores confiáveis de quando terminou de carregar. Às vezes, a página parece pronta, mas ainda está executando $digest cycles. Solução: esperas explícitas combinadas com verificações de estado do Angular.
2. MODAIS E POPUPS ANTIGOS
A aplicação usava modais jQuery UI, não componentes modernos. O Selenium precisa de estratégias diferentes para interagir com eles - às vezes, executando JavaScript diretamente no navegador.
3. TIMEZONES E FORMATOS DE DATA
O sistema foi construído para um fuso horário específico, mas os testes rodavam em ambientes diferentes. Datas apareciam formatadas de formas inesperadas. Solução: normalização de datas no código de teste.
4. STORED PROCEDURES STATEFUL
Algumas SPs mantinham estado entre execuções (variáveis globais, tabelas temporárias). Isso causava interferência entre testes. Solução: limpeza explícita do banco antes de cada teste.
5. GRAVAÇÃO DE VÍDEO CONSOME RECURSOS
Gravar 1920x1080 a 30 FPS consome CPU e disco. Em máquinas mais lentas, isso interferia com os testes. Solução: opção de desabilitar vídeo em testes de desenvolvimento, mantendo apenas em testes oficiais.
6. PRIVACIDADE E DADOS SENSÍVEIS
O sistema lidava com dados corporativos. Os vídeos não podiam vazar informações reais. Solução: uso exclusivo de dados de teste sintéticos, claramente identificáveis (como "EMPRESA TESTE 623").
CAPÍTULO 6: O PODER DA NARRATIVA VISUAL
O que descobri ao longo dessa jornada é que bugs não são apenas problemas técnicos - são histórias. E histórias precisam ser contadas de forma que as pessoas se importem.
ANTES DE VÍDEOS
- "O módulo X não salva dados" → Resposta: "Funciona na minha máquina"
- Discussões intermináveis sobre se o bug existe
- Semanas para reproduzir em ambiente controlado
- Comunicação por email com capturas de tela confusas
DEPOIS DE VÍDEOS
- "Assista este vídeo de 30 segundos" → Resposta: "Entendi, vou corrigir"
- Zero ambiguidade sobre a existência do bug
- Reprodução imediata através do código de teste automatizado
- Evidência visual que qualquer stakeholder entende
Os vídeos transformaram conversas:
Email típico ANTES:
Assunto: Bug em Empresa
Oi, quando tento salvar não funciona. Cliquei no botão mas não salvou.
Pode ver?
Email típico DEPOIS:
Assunto: BUG-003 - Evidência Visual
Olá,
Identificamos falha crítica no módulo Manter Empresa.
Evidências:
- Vídeo do problema: BUG-003_ANTES.mp4
- Card completo: CARD_BUG-003_EMPRESA.txt
- Teste reproduzível: test_bug003_empresa.py
Assista o vídeo (30s) para visualizar o comportamento incorreto.
Causa raiz já identificada: conflito JPA/Hibernate com ResultSet de SP.
Proposta de correção em andamento.
A diferença? Profissionalismo, clareza e respeito pelo tempo de todos.
CAPÍTULO 7: A ARTE DA COMPARAÇÃO
O momento mais satisfatório é criar o vídeo "DEPOIS". É a prova de que o esforço valeu a pena.
Nosso processo:
1. CAPTURA DO "ANTES"
- Executa teste automatizado
- Bug se manifesta exatamente como reportado
- Vídeo gravado e salvo com sufixo "_ANTES"
- Timestamp registrado no card do bug
2. ANÁLISE E CORREÇÃO
- Investigação da causa raiz
- Implementação da solução
- Code review e testes manuais
- Commit com mensagem padronizada
3. CAPTURA DO "DEPOIS"
- Executa MESMO teste automatizado
- Bug não se manifesta mais
- Vídeo gravado e salvo com sufixo "_DEPOIS"
- Timestamp registrado no card
4. COMPARAÇÃO LADO A LADO
- Editamos os dois vídeos em um split-screen
- Esquerda: ANTES (vermelho)
- Direita: DEPOIS (verde)
- Narração opcional explicando a correção
Essa comparação visual é poderosa em apresentações para stakeholders. É tangível, compreensível e impressionante.
CAPÍTULO 8: LIÇÕES APRENDIDAS
Após meses trabalhando com Selenium em sistemas legados, aqui estão as lições que levarei para sempre:
1. AUTOMAÇÃO NÃO É APENAS SOBRE VELOCIDADE
É sobre consistência, documentação e comunicação. Um teste manual pode ser mais rápido hoje, mas um teste automatizado com vídeo vale ouro amanhã.
2. SISTEMAS LEGADOS MERECEM RESPEITO
É fácil criticar código antigo. Mas ele sobreviveu anos, processou milhões de transações e suportou negócios inteiros. Nossa missão é honrá-lo enquanto o modernizamos.
3. VISUALIZAÇÃO É COMUNICAÇÃO
Um vídeo de 30 segundos comunica mais que 30 páginas de documentação. Invista tempo em tornar suas evidências visuais e acessíveis.
4. PADRÕES SALVAM VIDAS
Estrutura de pastas, nomenclatura de arquivos, formato de cards - tudo isso parece burocracia até você ter 50 bugs para gerenciar. Então, vira salvação.
5. TESTES SÃO DOCUMENTAÇÃO EXECUTÁVEL
O código do teste É a documentação do comportamento esperado. Se alguém quer entender como o sistema deve funcionar, mostre o teste.
6. CRIATIVIDADE > FERRAMENTAS
Selenium é apenas uma ferramenta. O que faz a diferença é COMO você a usa. Pense fora da caixa: grave vídeos, crie narrativas, construa cards de bug.
7. PRIVACIDADE É NÃO-NEGOCIÁVEL
Nunca, jamais, use dados reais em testes ou vídeos de evidência. Sempre dados sintéticos, sempre mascarados, sempre seguro.
CAPÍTULO 9: O FUTURO QUE CONSTRUÍMOS
O sistema legado ainda está lá, rodando, processando operações críticas. Mas agora, ele tem algo que não tinha antes: uma rede de segurança.
Cada módulo crítico tem:
- Testes automatizados que reproduzem cenários reais
- Vídeos que documentam o comportamento esperado
- Cards que explicam cada bug já corrigido
- Um histórico vivo de evolução
Quando um novo desenvolvedor entra na equipe, ele não recebe apenas código. Ele recebe histórias. Ele assiste aos vídeos. Ele entende o PORQUÊ de cada decisão técnica, porque pode ver o problema que ela resolveu.
Quando um stakeholder pergunta "por que isso demora tanto?", mostramos os vídeos dos bugs que já corrigimos. Mostramos a complexidade. E eles entendem.
O Selenium deixou de ser apenas uma ferramenta de teste. Tornou-se nosso contador de histórias digital, nossa memória coletiva, nossa prova de que importamos com qualidade.
EPÍLOGO: A MAESTRIA ESTÁ NO DETALHE
Meses depois daquele primeiro chamado, o sistema está mais estável. Não porque reescrevemos tudo - mas porque entendemos tudo. Porque documentamos tudo. Porque testamos tudo.
A verdadeira maestria em trabalhar com Selenium e sistemas legados não está em conhecer todas as APIs do WebDriver. Está em:
- Saber quando gravar e quando apenas validar
- Entender como contar a história de um bug através de um vídeo
- Ter empatia com quem vai assistir seus testes rodando
- Respeitar a privacidade e a segurança
- Construir não apenas testes, mas documentação viva
- Transformar bugs em oportunidades de aprendizado
Cada vídeo "_ANTES.mp4" é um memorial de um problema.
Cada vídeo "_DEPOIS.mp4" é um certificado de conquista.
E cada card de bug é um capítulo na história de um sistema que se recusa a morrer - porque ainda tem valor, ainda serve pessoas, ainda importa.
No final, não estamos apenas testando software.
Estamos preservando legados.
Estamos iluminando o passado para construir um futuro melhor.
Estamos praticando a arte de cuidar do que veio antes de nós.
E isso, sim, é maestria.
SOBRE ESTE ARTIGO
Este artigo é baseado em experiências reais de testes automatizados em sistemas legados JavaEE, mas todos os nomes de empresas, aplicações e dados foram alterados ou omitidos para preservar a privacidade e a confidencialidade.
As técnicas descritas são aplicáveis a qualquer sistema legado que precise de modernização com segurança e qualidade.
O código e as estruturas mencionadas estão disponíveis como referência para equipes que enfrentam desafios similares.