Aguarde o carregamento da página no Selenium

240

Como você faz o Selenium 2.0 aguardar o carregamento da página?

karthick kumar
fonte
7
Para mim, apenas a resposta de Paulo parece correta, a maioria das respostas altamente votadas fala sobre esperar por um elemento específico.
Xyz #

Respostas:

138

Você também pode verificar o carregamento de página usando o seguinte código

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

 wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));
Imran
fonte
22
Você poderia pensar que algo assim seria incorporado. Esperar o carregamento da página é uma coisa bastante comum na web.
PRMan
19
isso realmente funciona o tempo todo? Talvez eu esteja perdendo alguma coisa do seu código, mas você esteja esperando o domínio estar pronto. Mas considere que, se seu código for executado muito rápido, a página anterior ainda não pode ser descarregada e retornará verdadeira, mesmo que você ainda esteja na página antiga. O que você precisa fazer é aguardar o descarregamento da página atual e chamar o código acima. Uma maneira de detectar o descarregamento da página é obter um elemento da Web na página atual e aguardar até que se torne obsoleto. obeythetestinggoat.com/…
George
6
FYI - Mesmo assim, o acima exposto não garante que a página esteja completa - apenas que o dom está pronto. Qualquer dojo / jquery ainda pode estar construindo dinamicamente elementos na página, portanto, é necessário aguardar primeiro os elementos dinâmicos antes de interagir com eles.
George George
3
Esteja ciente de que este método verifica apenas o DOM. Se você usar Ajax ou AngularJS, isso não funcionará porque haverá algumas chamadas assíncronas que não podem ser detectadas pelo document.readyState.
Homewrecker
3
Este é o código C #. Isso não funciona com Java e a pergunta feita sobre Java .
Kingamere 18/02/19
89

Use a classe WebDriverWait

Veja também aqui

Você pode esperar mostrar algum elemento. algo como em C #:

WebDriver _driver = new WebDriver();
WebDriverWait _wait = new WebDriverWait(_driver, new TimeSpan(0, 1, 0));

_wait.Until(d => d.FindElement(By.Id("Id_Your_UIElement"));
Artem
fonte
Isso funcionou muito bem. É uma maneira moderna e muito agradável de resolver o problema.
22411 CrazyDart
3
@ EmmanuelAngelo.R TimeSpan é uma estrutura de dados .Net.
rjzii
12
e se eu não souber qual elemento estará na página?
JustGoscha
3
Isso funcionará para aguardar o carregamento de um elemento específico e não para a página inteira.
Xyz #
1
Isso não garante que um elemento seja totalmente carregado nem responda à pergunta. Como alguém pode votar nisso?
Boris D. Teoharov 23/11
36

Se você definir a espera implícita do driver e chamar o findElementmétodo em um elemento que você espera estar na página carregada, o WebDriver pesquisará esse elemento até encontrar o elemento ou atingir o valor do tempo limite.

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

fonte: espera implícita

Sam
fonte
3
Não vai ajudar na espera pelo carregamento da página.
Xyz #
Isso significa que ele tentará algo durante 10 segundos, antes de gerar uma exceção. portanto, não é possível garantir um atraso de 10 segundos.
Skysign 23/07/16
1
@xyz - por que não ajuda?
MasterJoe2
@ testerjoe2 espera até que um elemento em particular seja encontrado, a pergunta é sobre como esperar pelo carregamento da página.
Xyz
35

Em geral, com o Selenium 2.0, o driver da web deve retornar o controle apenas ao código de chamada depois de determinar que a página foi carregada. Caso contrário, você pode ligar waitforelemement, que executa o ciclo de chamadas findelementaté que seja encontrado ou expire (o tempo limite pode ser definido).

Paul Hadfield
fonte
2
Adicionando a resposta de Paulo. Verifique também isso stackoverflow.com/questions/5858743/… .
9ikhan
27
Infelizmente, o Selenium 2 não espera em todos os casos o carregamento de uma página. Por exemplo, WebElement: click () não espera e isso é explicitamente dito no Javadoc pertencente. No entanto, eles não informam como posso verificar se uma nova página é carregada. If click() causes a new page to be loaded via an event or is done by sending a native event (which is a common case on Firefox, IE on Windows) then the method will not wait for it to be loaded and the caller should verify that a new page has been loaded.
Sebi 28/09
De doc ..e o método irá bloquear até que a carga está completa ...
xyz
2
@ Karna: Sim, em teoria, deveria sempre e na prática o fazia na maioria das vezes. O uso do Selenium na época destacou que havia momentos em que pensava que a página havia terminado de carregar, mas não havia. Eu não usei selênio muito recentemente, então isso pode ou não ser o caso.
Paul Hadfield 22/10
3
Eu concordo: especialmente o driver do Internet Explorer é buggy e retorna o controle imediatamente em alguns casos, mesmo que uma página ainda esteja carregando. No meu caso, adicionei uma espera usando JavascriptExecutor, aguardando document.readyState estar "completo". Por causa da ida e volta do selênio ao navegador, acho que as condições da corrida são atenuadas, e isso "sempre" funciona para mim. Após "click ()", quando espero que uma página seja carregada, espero explicitamente (usando o WebDriverWait) pelo readystate. ]
dmansfield
22

Implementação Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}
allenhwkim
fonte
17
Equivalente em Python: WebDriverWait (driver, 10) .until (lambda d: d.execute_script ('return document.readyState') == 'complete')
blaze
2
Python usa o código acima, mas não se esqueça dessa linha .. | de selenium.webdriver.support.ui importar WebDriverWait
t3dodson
Ocorreu um problema ao clicar em um elemento quando a página não estava totalmente carregada. Em Python, tentei time.sleep (30). Funcionou. No entanto, sempre aguardará no máximo 30 segundos. Tentei o código a seguir e agora é mais eficiente, mais rápido. WebDriverWait (driver, 10) .until (lambda d: driver.find_element_by_xpath ("// div [. = 'Administração']").
Click
20

Você pode remover a System.outlinha. É adicionado para fins de depuração.

WebDriver driver_;

public void waitForPageLoad() {

    Wait<WebDriver> wait = new WebDriverWait(driver_, 30);
    wait.until(new Function<WebDriver, Boolean>() {
        public Boolean apply(WebDriver driver) {
            System.out.println("Current Window State       : "
                + String.valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState")));
            return String
                .valueOf(((JavascriptExecutor) driver).executeScript("return document.readyState"))
                .equals("complete");
        }
    });
}
QIKHAN
fonte
Obrigado por estas dicas. Eu o adiciono no meu SeleniumHelper; cf. javabox
boly38
17

Todas essas soluções são válidas para casos específicos, mas elas sofrem de pelo menos um dos dois possíveis problemas:

  1. Eles não são genéricos o suficiente - eles querem que você saiba, antecipadamente, que alguma condição específica será verdadeira para a página que você está acessando (por exemplo, algum elemento será exibido)

  2. Eles estão abertos a uma condição de corrida em que você usa um elemento que está realmente presente na página antiga e na nova página.

Aqui está minha tentativa de uma solução genérica que evita esse problema (em Python):

Primeiro, uma função genérica de "espera" (use um WebDriverWait, se quiser, acho-os feios):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Em seguida, a solução se baseia no fato de que o selênio registra um número de identificação (interno) para todos os elementos em uma página, incluindo o nível superior <html> elemento de . Quando uma página é atualizada ou carregada, ela obtém um novo elemento html com um novo ID.

Então, supondo que você queira clicar em um link com o texto "meu link", por exemplo:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

Para um auxiliar genérico Python, reutilizável e reutilizável, você pode criar um gerenciador de contexto:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

E então você pode usá-lo em praticamente qualquer interação de selênio:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

Eu acho que é à prova de balas! O que você acha?

Mais informações em um post sobre isso aqui

hwjp
fonte
Li sua página da web antes de pesquisar novamente mais especificamente o código java que implementa sua solução. Nada até agora ...
andrew lorien
11

Você também pode usar a classe: ExpectedConditionspara aguardar explicitamente a exibição de um elemento na página da web antes de executar qualquer ação.

Você pode usar a ExpectedConditionsclasse para determinar se um elemento está visível:

WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));

Veja ExpectedConditions class Javadoca lista de todas as condições que você pode verificar.

TedEd
fonte
11

A resposta de Imran foi reformulada para o Java 7:

    WebDriverWait wait = new WebDriverWait(driver, 30);

    wait.until(new ExpectedCondition<Boolean>() {
        public Boolean apply(WebDriver wdriver) {
            return ((JavascriptExecutor) driver).executeScript(
                "return document.readyState"
            ).equals("complete");
        }
    });
Fin
fonte
10

Essa parece ser uma limitação séria do WebDriver. Obviamente, esperar por um elemento não implica que a página esteja sendo carregada, em particular, o DOM pode ser totalmente construído (estado onready) no qual o JS ainda está em execução e o CSS e as imagens ainda estão sendo carregados.

Acredito que a solução mais simples é definir uma variável JS no evento onload depois que tudo for inicializado e verificar e aguardar essa variável JS no Selenium.

sibidiba
fonte
É simples se o site é seu para modificar!
Reinierpost
Sim, basta usar um JavascriptExecutor para executar o jQuery.js e, em seguida, você terá acesso aos eventos de carregamento do jQuery. É um caso raro quando isso é necessário. O Webdriver padrão tem energia suficiente para realizar 98% das esperas adequadas.
djangofan
@djangofan seria incrível ver um exemplo disso ... Eu sou um cara de front-end, então não sei onde ou como o JavascriptExecutor é usado.
precisa saber é o seguinte
@BradGreens - Ok, veja meu projeto aqui: github.com/djangofan/jquery-growl-selenium-example . Se você tiver a largura de banda para concluir esse exemplo, não consegui fazer o jGrowl funcionar nesse projeto de teste, embora o jQuery funcione bem.
precisa saber é o seguinte
1
@BradGreens Além de comentário de djangofan ver a minha resposta aqui: stackoverflow.com/a/24638792/730326
jmathew
9

Se você desejar aguardar o carregamento de um elemento específico, poderá usar o isDisplayed()método em RenderedWebElement:

// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
while (System.currentTimeMillis() < end) {
    // Browsers which render content (such as Firefox and IE) return "RenderedWebElements"
    RenderedWebElement resultsDiv = (RenderedWebElement) driver.findElement(By.className("gac_m"));

    // If results have been returned, the results are displayed in a drop down.
    if (resultsDiv.isDisplayed()) {
      break;
    }
}

(Exemplo do Guia de introdução de 5 minutos )

Tristan
fonte
4
Um ano depois (atual versão Selenium 2.23.1), não há RenderedWebElementna API. No entanto, o isDisplayed()método agora está disponível diretamente no WebElement.
Petr Janeček 10/06/12
1
A votação é terrível quando pode ser evitada.
Reinierpost
8

Aguarde explicitamente ou espera condicional nessa espera até receber essa condição.

WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));

Isso aguardará cada elemento da web por 60 segundos.

Use aguardar implicitamente a espera de todos os elementos da página até o momento especificado.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

Isso aguardará cada elemento da web por 60 segundos.

Anuj Teotia
fonte
5

Use aguardar implicitamente a espera de todos os elementos da página até o tempo determinado.

driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);

aguarde cada elemento da página por 30 segundos.

Outra espera é a espera explicitamente ou a espera condicional nessa espera até a condição especificada.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

Em id, forneça o ID do elemento estático que é exibido de forma diferente na página, assim que a página for carregada.

Kuldeep Yadav
fonte
4

Estou surpreso que os predicados não tenham sido a primeira escolha, pois você normalmente sabe com quais elementos você irá interagir na página que espera carregar. Minha abordagem sempre foi criar predicados / funções como waitForElementByID(String id)ewaitForElemetVisibleByClass(String className) etc., e depois usá-los e reutilizá-los onde eu precisar, seja para carregar uma página ou alterar o conteúdo da página que estou esperando.

Por exemplo,

Na minha aula de teste:

driverWait.until(textIsPresent("expectedText");

No meu pai da classe de teste:

protected Predicate<WebDriver> textIsPresent(String text){
    final String t = text;
    return new Predicate<WebDriver>(){
        public boolean apply(WebDriver driver){
            return isTextPresent(t);
        }
    };
}

protected boolean isTextPresent(String text){
    return driver.getPageSource().contains(text);
}

Embora isso pareça muito, ele cuida da verificação repetidamente para você e o intervalo de quantas vezes a verificação pode ser definido juntamente com o tempo de espera máximo antes do tempo limite. Além disso, você reutilizará esses métodos.

Neste exemplo, a classe pai definiu e iniciou oe WebDriver driverthe WebDriverWait driverWait.

Eu espero que isso ajude.

Jack Mason
fonte
Isso me ajuda! Obrigado por esta excelente amostra. Eu o adiciono no meu SeleniumHelper; cf. javabox
boly38
4

A melhor maneira de aguardar o carregamento da página ao usar as ligações Java para o WebDriver é usar o padrão de design do Objeto de Página com o PageFactory. Isso permite que você utilize o AjaxElementLocatorFactoryque colocar, simplesmente age como uma espera global para todos os seus elementos. Possui limitações em elementos como caixas de seleção ou transições complexas de javascript, mas reduz drasticamente a quantidade de código necessária e acelera os tempos de teste. Um bom exemplo pode ser encontrado neste post do blog. O entendimento básico do Core Java é assumido.

http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html

sonhu
fonte
4

Solução NodeJS:

No Nodejs você pode obtê-lo através de promessas ...

Se você escrever esse código, pode ter certeza de que a página está totalmente carregada quando chegar ao ...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Se você escrever esse código, navegará e o selênio aguardará 3 segundos ...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

Da documentação do Selenium:

this.get (url) → Regenerável

Agenda um comando para navegar para o URL fornecido.

Retorna uma promessa que será resolvida quando o documento terminar de carregar .

Documentação do Selenium (Nodejs)

sidanmor
fonte
4

Aqui está uma versão do Java 8 da resposta mais votada atualmente :

WebDriverWait wait = new WebDriverWait(myDriver, 15);
wait.until(webDriver -> ((JavascriptExecutor) myDriver).executeScript("return document.readyState").toString().equals("complete"));

Onde myDriverestá um WebDriverobjeto (declarado anteriormente).

Nota : Esteja ciente de que este método ( document.readyState) verifica apenas o DOM.

BelovedFool
fonte
4

Ligue abaixo Função no seu script, isso irá esperar até que a página não seja carregada usando javascript

public static boolean isloadComplete(WebDriver driver)
{
    return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
            || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
}
Shubham Jain
fonte
Mudei o boolean para vazio, mas não está a funcionar no Chrome
nosequeweaponer
3
/**
 * Call this method before an event that will change the page.
 */
private void beforePageLoad() {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeScript("document.mpPageReloaded='notYet';");
}

/**
 * Call this method after an event that will change the page.
 * 
 * @see #beforePageLoad
 * 
 *      Waits for the previous page to disappear.
 */
private void afterPageLoad() throws Exception {
    (new WebDriverWait(driver, 10)).until(new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver driver) {
            JavascriptExecutor js = (JavascriptExecutor) driver;
            Object obj = js.executeScript("return document.mpPageReloaded;");
            if (obj == null) {
                return true;
            }
            String str = (String) obj;
            if (!str.equals("notYet")) {
                return true;
            }
            return false;
        }
    });
}

Você pode mudar do documento para um elemento, no caso em que apenas parte de um documento está sendo alterada.

Esta técnica foi inspirada na resposta de sincebasic.

Marc
fonte
3

SeleniumWaiter :

import com.google.common.base.Function;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

public class SeleniumWaiter {

      private WebDriver driver;

      public SeleniumWaiter(WebDriver driver) {
           this.driver = driver;
      }

      public WebElement waitForMe(By locatorname, int timeout){
           WebDriverWait wait = new WebDriverWait(driver, timeout);
           return wait.until(SeleniumWaiter.presenceOfElementLocated(locatorname));
      }

      public static Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
            // TODO Auto-generated method stub
            return new Function<WebDriver, WebElement>() {
                 @Override
                 public WebElement apply(WebDriver driver) {
                      return driver.findElement(locator);
                 }
            };
      }
 }

E para você usá-lo :

_waiter = new SeleniumWaiter(_driver);

try {
   _waiter.waitForMe(By.xpath("//..."), 10);
} 
catch (Exception e) {
   // Error
}
tux23
fonte
3

Você pode usar o método existente abaixo para definir o tempo para o pageeLoadTimeout no exemplo abaixo, se a página estiver demorando mais de 20 segundos para carregar, em seguida, haverá uma exceção do recarregamento da página

 WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)
Arpan Saini
fonte
2

Você pode esperar explicitamente que um elemento seja exibido na página da web antes de executar qualquer ação (como element.click ())

driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(new ExpectedCondition<WebElement>(){
        @Override
        public WebElement apply(WebDriver d) {
        return d.findElement(By.id("myDynamicElement"));
}});

Isto é o que eu usei para um cenário semelhante e funciona bem.

anirus
fonte
eu acho que driver.get aguarda a função onload ao fim antes de controle de retorno para o código, a menos que a página tem um monte de ajax
goh
2

Meu jeito simples:

long timeOut = 5000;
    long end = System.currentTimeMillis() + timeOut;

        while (System.currentTimeMillis() < end) {

            if (String.valueOf(
                    ((JavascriptExecutor) driver)
                            .executeScript("return document.readyState"))
                    .equals("complete")) {
                break;
            }
        }
RichardK
fonte
2

A melhor maneira que eu vi é utilizar o stalenessOfExpectedCondition, para aguardar a página antiga ficar obsoleta.

Exemplo:

WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 10);

WebElement oldHtml = driver.findElement(By.tagName("html"));
wait.until(ExpectedConditions.stalenessOf(oldHtml));

Esperará dez segundos até que a tag HTML antiga fique obsoleta e, em seguida, lançará uma exceção se isso não acontecer.

forresthopkinsa
fonte
1
um WebElement ficando obsoleto não implica que uma nova página seja carregada.
Corey Goldberg
Claro, mas isso significa que a página antiga terminou de descarregar. Na minha experiência, é igualmente importante saber quando a página antiga foi descarregada ou se foi interrompida por algum motivo.
forresthopkinsa
Obviamente, eu normalmente uso stalenessOf em conjunto com outros testes para obter o processo completo de descarregamento / carregamento.
forresthopkinsa
2

Eu uso o node + selenium-webdriver (que é a versão 3.5.0 agora). o que eu faço para isso é:

var webdriver = require('selenium-webdriver'),
    driver = new webdriver.Builder().forBrowser('chrome').build();
;
driver.wait(driver.executeScript("return document.readyState").then(state => {
  return state === 'complete';
}))
yuwanlin
fonte
2

Você pode esperar. existem basicamente 2 tipos de espera em selênio

  • Espera implícita
  • Espera explícita

- espera implícita

Isso é muito simples, veja a sintaxe abaixo:

driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

- Espera explícita

Aguarde explicitamente ou espera condicional nessa espera até que uma determinada condição ocorra.

WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

Você pode usar outras propriedades como visblityOf(),visblityOfElement()

iamsankalp89
fonte
2

No meu caso, usei o seguinte para conhecer o status de carregamento da página. Em nosso aplicativo, os gifs de carregamento estão presentes e os ouço da seguinte maneira para eliminar o tempo de espera indesejado no script.

public static void processing(){ 
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
    wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//div[@id='Msgpanel']/div/div/img")));
}

Onde o xpath localiza o gif no HTML DOM. Depois disso, você também pode implementar seus métodos de ação Clique em.

public static void click(WebElement elementToBeClicked){
    WebDriverWait wait = new WebDriverWait(driver, 45);
    wait.until(ExpectedConditions.visibilityOf(element));
    wait.until(ExpectedConditions.elementToBeClickable(element)); 
    wait.ignoring(NoSuchElementException.class).ignoring(StaleElementReferenceException.class); elementToBeClicked.click(); 
 }
Praveen
fonte
2

Cara, todas essas respostas requerem muito código. Isso deve ser uma coisa simples, pois é bastante comum.

Por que não injetar um javascript simples com o driver da web e verificar. Este é o método que eu uso na minha classe de webscraper. O javascript é bastante básico, mesmo se você não conhece js.

    def js_get_page_state(self):        
    """
    Javascript for getting document.readyState
    :return: Pages state.

    More Info: https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState
    """
    ready_state = self.driver.execute_script('return document.readyState')
    if ready_state == 'loading':
        self.logger.info("Loading Page...")
    elif ready_state == 'interactive':
        self.logger.info("Page is interactive")
    elif ready_state == 'complete':
        self.logger.info("The page is fully loaded!")
    return ready_state
Bruce Wayne
fonte
1

Como fazer com que o Selenium aguarde o carregamento da página após um clique fornece a seguinte abordagem interessante:

  1. Armazene uma referência a a WebElementpartir da página antiga.
  2. Clique no link.
  3. Continue invocando operações WebElementaté que StaleElementReferenceExceptionseja lançada.

Código de amostra:

WebElement link = ...;
link.click();
new WebDriverWait(webDriver, timeout).until((org.openqa.selenium.WebDriver input) ->
{
    try
    {
        link.isDisplayed();
        return false;
    }
    catch (StaleElementReferenceException unused)
    {
        return true;
    }
});
Gili
fonte
Boa ideia! Nunca pensei em resolver essa situação verificando o oposto de um carregamento de página bem-sucedido, um descarregamento de página bem-sucedido (por falta de um termo melhor). Embora essa seja a melhor opção, se StaleElementReferenceException leva menos tempo etc. do que esperar por uma carga bem-sucedida. No entanto, outra boa maneira de fazê-lo.
Joseph Orlando
4
Isso não informa se a página atual está carregada, mas se a última página (especificamente um elemento) está descarregada . Você ainda precisará aguardar o carregamento da página atual. BTW, você pode substituir seu código acima por new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(element)).
JeffC