Hacks de QA: Como localizar elementos web que não aparecem no inspetor?
Encontrando elementos de Schrödinger perdidos pelo HTML!
Checklist do conteúdo
- Introdução e apresentação geral do problema
- Entendendo por quê os elementos não aparecem na inspeção
- Contornando o problema de uma maneira simples e elegante
- Um pouco de considerações sobre o uso na prática
- TL;DR
Me ajuda a te ajudar tecnologia
Por mais estranho que pareça, a ideia que deu vida à dica dessa publicação é a prova “viva” que qualquer evolução tecnológica pode vir acompanhada de resultados positivos e negativos.
E̶n̶q̶u̶a̶n̶t̶o̶ ̶v̶o̶c̶ê̶ ̶l̶ê̶ ̶i̶s̶s̶o̶ ̶s̶u̶a̶ ̶l̶i̶b̶ ̶p̶r̶e̶f̶e̶r̶i̶d̶a̶ ̶a̶c̶a̶b̶o̶u̶ ̶d̶e̶ ̶a̶t̶u̶a̶l̶i̶z̶a̶r̶.
E sim, eu não resisti ao trocadilho da estrutura HTML com vida própria. Em minha defesa eu também não acho que as coisas não devam evoluir, então vamos observar uma maneira de contornar um desses detalhes evolutivos.
Entendendo o problema
Atualmente muitos frameworks de desenvolvimento web possibilitam a elaboração de sistemas utilizando técnicas que otimizam o consumo de recursos e colaboram para a construção de interfaces que contribuem significativamente com a experiência do usuário.
Mencionadas como aplicações modernas por algumas literaturas, normalmente a arquitetura por trás do frontend desses sistemas utiliza ferramentas baseadas em JavaScript para promover os benefícios já citados.
O detalhe na elaboração desses web apps é que, dependendo da maneira que foram construídos, os elementos da interface são colocados na camada DOM (Document Object Model) do navegador de maneira dinâmica, ou seja, à medida que são chamados para interação do usuário.
Podemos observar esse comportamento através desse exemplo que encontrei sem grandes dificuldades no CodePen ao fazer uma busca rápida pelo Google.
vue-select example codepen
No gif acima podemos notar que as opções de seleção do componente não existem na camada DOM até que o usuário acione o botão que abre a listagem de itens selecionáveis do elemento.
Podemos notar também que ao interagir com qualquer outro recurso dentro do navegador a listagem é encerrada na interface e sua representação na camada DOM deixa de existir.
Apesar do exemplo apresentado estar utilizando a biblioteca Vue.js, é importante ressaltar que esse comportamento não é exclusivo dessa ferramenta e também pode ser notado em outros frameworks como Angular e React.
Lembre-se, tudo depende da maneira com que a implementação foi realizada.
Hackeando o comportamento na DOM
Confesso que já perdi algumas horas em atividades de automação de testes para conseguir mapear elementos com esse comportamento dinâmico, quase como um malabarista pulando de janela em janela para tentar deixar o componente presente no inspetor de elementos.
E se a gente pudesse fazer isso sem precisar passar pelo processo difícil?
Em uma visão geral, quando fazemos as mil e uma manobras para tentar manter o elemento na DOM, não estamos fazendo nada mais que tentar preservar o estado da página para que possamos olhar para ela do jeito que ela está naquele momento.
Voltando então à pergunta, a resposta que procuramos nos trouxe até aqui: dá para fazer e é muito simples “congelar” esse comportamento.
- Acesse as ferramentas de desenvolvedor do navegador.
- Insira o seguinte código no console e pressione [ENTER].
setTimeout(() => { debugger; }, 5000)
- Faça o elemento dinâmico ser apresentado na tela.
- Aguarde 5 segundos para a ativação do debug.
Após a ativação do debug nenhum elemento mudará mais de estado até que o usuário normalize a execução do processo e você poderá realizar a inspeção dos elementos sem nenhum problema.
5 segundos é pouco
Então vamos entender o que essa linha de código faz para melhorar as coisas.
A função setTimeout() serve para executar uma instrução de comandos quando depois que um tempo predeterminado atingir o limite estabelecido. No final do período estabelecido o código que você informou dentro da função é executado uma única vez e a vida segue normalmente.
// Sintaxe
setTimeout(código, tempo)
Já a instrução debugger em nosso contexto faz com que o navegador inicie a funcionalidade de depuração, atuando como um breakpoint na execução do código.
Em outras palavras, ao executar nosso código estamos basicamente pedindo para o browser fazer uma pausa depois de algum tempo (take your time 😎).
// Executar em 9 segundos
setTimeout(() => { debugger; }, 9000)// Executar em 12 segundos
setTimeout(() => { debugger; }, 12000)
Agora sim! Para alterar o tempo de ativação do nosso debug basta alterar o valor do parâmetro tempo para um valor de sua preferência, lembrando que aqui utilizamos milissegundos (1000 = 1 segundo).
Abrindo a caixa de ferramentas
Dando um passo além da opção apresentada, é válido observar que navegadores modernos oferecem outro recurso para facilitar nossa vida em situações que nos deparamos como elementos dinâmicos saltando pelo front.
botão direito no elemento pai > break on > subtree modifications
Através da opção break on do menu de ações do elemento é possível configurar 3 tipos de pausa conforme o comportamento do elemento.
- Mudança na estrutura interna do elemento selecionado.
- Mudança nos atributos do elemento elemento selecionado.
- Exclusão do elemento selecionado.
Apesar do caminho com um pouco mais de passos (e da necessidade em identificar o elemento que será alterado), essa e estratégia também vai um pouco além da possibilidade de inspeção do elemento.
Quando o debug é acionado através de uma dessas opções, a ferramenta de desenvolvimento do browser nos apresenta também o arquivo com o código que está sendo executado naquele exato momento.
Isso nos dá a possibilidade de aprofundar nossa análise quando necessário e compreender melhor o comportamento do código por trás da interface.
Tudo que é bom tem seu fim
Em nosso caso, o fim é apenas o do post mesmo. A dica que descrevi hoje aqui foi feita observando uma situação que rotineiramente volta a aparecer como dúvida em alguns grupos que mantenho contato.
Pelo que pude perceber na prática, apesar de ser um processo bem simples, ela economiza algumas dezenas de minutos de dor de cabeça e a reação final ao apresentar esse hackezinho é sempre a mesma…
Espero que ela te ajude bastante também! 😉
PS: Obrigado Deuzo Rafael ❤ pelo apoio na revisão do conteúdo. Tu é 1000!
TL;DR
Congelar o estado da DOM para permitir a inspeção de elementos.
- Acesse as ferramentas de desenvolvedor do navegador.
- Insira o seguinte código no console e pressione [ENTER].
setTimeout(() => { debugger; }, 5000)
- Faça o elemento dinâmico ser apresentado na tela.
- Aguarde 5 segundos para a ativação do debug.
- Prossiga com a inspeção de elementos normalmente.