Tenho um aplicativo da web para testar com Selenium. Há muito JavaScript em execução no carregamento da página.
Este código JavaScript não é tão bem escrito, mas não posso mudar nada. Portanto, esperar que um elemento apareça no DOM com o findElement()
método não é uma opção.
Quero criar uma função genérica em Java para aguardar o carregamento de uma página, uma possível solução seria:
- execute um script JavaScript do WebDriver e armazene o resultado
document.body.innerHTML
em uma variável de stringbody
. - compare a
body
variável com a versão anterior debody
. se eles forem iguais, defina o incremento de um contador,notChangedCount
caso contrário, definanotChangedCount
como zero. - espere um pouco (50 ms, por exemplo).
- se a página não mudou por algum tempo (500 ms, por exemplo),
notChangedCount >= 10
então saia do loop, caso contrário, volte para a primeira etapa.
Você acha que é uma solução válida?
findElement
espera que um elemento esteja disponível, mas às vezes o elemento está disponível antes que o código javascript seja inicializado completamente, por isso não é uma opção.Respostas:
Se alguém realmente soubesse uma resposta geral e sempre aplicável, ela teria sido implementada em todos os lugares há muito tempo e tornaria nossas vidas MUITO mais fáceis.
Há muitas coisas que você pode fazer, mas cada uma delas tem um problema:
Como Ashwin Prabhu disse, se você conhece bem o script, pode observar seu comportamento e rastrear algumas de suas variáveis em
window
oudocument
etc. Esta solução, no entanto, não é para todos e pode ser usada apenas por você e apenas em um conjunto limitado de Páginas.Sua solução, observando o código HTML e se ele foi ou não alterado por algum tempo, não é ruim (também, há um método para obter o HTML original e não editado diretamente
WebDriver
), mas:setTimeout()
) e trabalham continuamente e podem alterar o HTML toda vez que são executados. Sério, toda página "Web 2.0" faz isso. Até Stack Overflow. Você poderia sobrescrever os métodos mais comuns usados e considerar os scripts que os usam como concluídos, mas ... você não pode ter certeza.innerHTML
diversão.Existem ferramentas para ajudá-lo nisso. Ou seja, Progress Listeners juntamente com nsIWebProgressListener e alguns outros. O suporte do navegador para isso, no entanto, é horrível. O Firefox começou a tentar dar suporte a partir do FF4 (ainda em evolução), o IE tem suporte básico no IE9.
E acho que posso encontrar outra solução falha em breve. O fato é - não há uma resposta definitiva sobre quando dizer "agora a página está completa" por causa dos scripts eternos fazendo seu trabalho. Escolha aquele que melhor atende a você, mas cuidado com suas deficiências.
fonte
Obrigado Ashwin!
No meu caso, devo esperar a execução de um plugin jquery em algum elemento .. especificamente "qtip"
com base na sua dica, funcionou perfeitamente para mim:
Observação: estou usando o Webdriver 2
fonte
Você precisa esperar que o Javascript e o jQuery terminem de carregar. Execute o Javascript para verificar se
jQuery.active
é0
edocument.readyState
écomplete
, o que significa que o carregamento de JS e jQuery está completo.fonte
document.readyState == 'complete' && jQuery.active == 0
funciona muito bem, mas há algo assim para React? Uma vez que essas verificações não travarão o carregamento de dados / componentes de reação?A biblioteca JS define / inicializa alguma variável conhecida na janela?
Nesse caso, você pode esperar que a variável apareça. Você pode usar
((JavascriptExecutor)driver).executeScript(String script, Object... args)
para testar essa condição (algo como
window.SomeClass && window.SomeClass.variable != null
:) e retornar um booleanotrue
/false
.Envolva isso em um
WebDriverWait
e espere até que o script retornetrue
.fonte
Eu tive o mesmo problema. Esta solução funciona para mim do WebDriverDoku:
http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp
fonte
Se tudo o que você precisa fazer é esperar que o html na página se torne estável antes de tentar interagir com os elementos, você pode pesquisar o DOM periodicamente e comparar os resultados. Se os DOMs forem os mesmos dentro do tempo de pesquisa determinado, você dourado. Algo assim onde você passa o tempo máximo de espera e o tempo entre as pesquisas de página antes de comparar. Simples e eficaz.
fonte
O código abaixo funciona perfeitamente no meu caso - minha página contém scripts java complexos
Fonte - Como esperar que a página carregue / pronta no Selenium WebDriver
fonte
Duas condições podem ser usadas para verificar se a página foi carregada antes de encontrar qualquer elemento na página:
Usar o readyState abaixo irá esperar até o carregamento da página
Abaixo do JQuery irá esperar até que os dados não sejam carregados
Após esses JavaScriptCode, tente encontrarOut webElement.
fonte
Pedi aos meus desenvolvedores para criar uma variável JavaScript "isProcessing" que eu possa acessar (no objeto "ae") que eles definem quando as coisas começam a funcionar e limpa quando as coisas são feitas. Em seguida, executo-o em um acumulador que o verifica a cada 100 ms até que ele obtenha cinco em uma linha para um total de 500 ms sem nenhuma alteração. Se 30 segundos se passarem, lanço uma exceção porque algo deveria ter acontecido até lá. Isso está em C #.
fonte
Para fazer isso corretamente, você precisa lidar com as exceções.
Aqui está como eu faço uma espera por um iframe. Isso requer que sua classe de teste JUnit passe a instância de RemoteWebDriver para o objeto de página:
NOTA: Você pode ver todo o meu exemplo de trabalho aqui .
fonte
Para a
nodejs
biblioteca Selenium, usei o seguinte trecho. No meu caso, eu estava procurando por dois objetos que são adicionados à janela, que neste exemplo são<SOME PROPERTY>
,10000
é o tempo limite em milissegundos,<NEXT STEP HERE>
é o que acontece depois que as propriedades são encontradas na janela.fonte
Você pode escrever alguma lógica para lidar com isso. Eu escrevi um método que retornará o
WebElement
e este método será chamado três vezes ou você pode aumentar o tempo e adicionar uma verificação nula paraWebElement
Aqui está um exemplofonte
Aqui está o meu próprio código:
Window.setTimeout executa somente quando o navegador está ocioso.
Portanto, chamar a função recursivamente (42 vezes) levará 100 ms se não houver atividade no navegador e muito mais se o navegador estiver ocupado fazendo outra coisa.
Como bônus, o contador pode ser redefinido em document.readyState ou em chamadas jQuery Ajax ou se alguma animação jQuery estiver em execução (apenas se seu aplicativo usar jQuery para chamadas ajax ...)
...
...
EDIT: Percebi que executeAsyncScript não funciona bem se uma nova página for carregada e o teste pode parar de responder indefinidamente, melhor usar isso em vez disso.
fonte
Não sei como fazer isso, mas no meu caso, o carregamento e renderização do final da página correspondem ao FAVICON exibido na guia Firefox.
Portanto, se conseguirmos obter a imagem favicon no navegador da web, a página da web estará totalmente carregada.
Mas como fazer isso ....
fonte
Usar a espera implícita funciona para mim.
Consulte esta resposta Selenium c # Webdriver: Aguarde até que o elemento esteja presente
fonte
É assim que eu faço:
fonte
Gosto da sua ideia de pesquisar o HTML até que esteja estável. Posso adicionar isso à minha própria solução. A abordagem a seguir está em C # e requer jQuery.
Sou o desenvolvedor de um projeto de teste SuccessFactors (SaaS) em que não temos nenhuma influência sobre os desenvolvedores ou as características do DOM por trás da página da web. O produto SaaS pode alterar potencialmente seu design de DOM subjacente 4 vezes por ano, de modo que a busca é permanente por maneiras robustas e de alto desempenho de testar com Selenium (incluindo NÃO testar com Selenium quando possível!)
Aqui está o que eu uso para "página pronta". Ele funciona em todos os meus próprios testes atualmente. A mesma abordagem também funcionou para um grande aplicativo da web Java interno alguns anos atrás, e já era robusta por mais de um ano na época em que deixei o projeto.
Driver
é a instância do WebDriver que se comunica com o navegadorDefaultPageLoadTimeout
é um valor de tempo limite em ticks (100ns por tick)A seguir, observe a ordem das esperas no método
PageReady
(documento Selenium pronto, Ajax, animações), o que faz sentido se você pensar bem:Algo como a abordagem de comparação do DOM pode ser usado entre 1 e 2 para adicionar outra camada de robustez.
fonte