Selênio aguarde até que o documento esteja pronto


133

Alguém pode me deixar como posso fazer selênio esperar até o tempo em que a página carrega completamente? Quero algo genérico, sei que posso configurar o WebDriverWait e chamar algo como 'find' para fazê-lo esperar, mas não vou tão longe. Eu só preciso testar se a página carrega com sucesso e passar para a próxima página para testar.

Encontrei algo no .net, mas não consegui fazê-lo funcionar em java ...

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"));

Alguma idéia de alguém?


Por que você não quer esperar?
Amey

7
Você quer dizer espera explícita? É demorado, estou testando algumas páginas de 10k.
Girish

2
Quero dizer, adicionar uma espera de correção pode não ser uma boa ideia se estou testando um grande número de links, certo?
Girish

10
Esperar um número fixo de segundos é inútil. Isso é adivinhação.
Anders Lindén

Dado que o javascript de uma página pode executar qualquer código genérico, é impossível escrever um programa para aguardar sua conclusão. É uma forma do problema de parada ( en.wikipedia.org/wiki/Halting_problem ). Qualquer solução aqui precisará fazer compromissos ou se basear em suposições da página da Web subjacente.
speedplane 21/10

Respostas:


83

Tente este código:

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

O código acima irá esperar até 10 segundos para carregar a página. Se o carregamento da página exceder o tempo, ele lançará o TimeoutException. Você captura a exceção e faz suas necessidades. Não tenho certeza se ele sai do carregamento da página após a exceção lançada. ainda não tentei esse código. Quer apenas tentar.

Esta é uma espera implícita. Se você definir isso uma vez, ele terá o escopo até a instância do Driver da Web ser destruída.

Consulte a documentação paraWebDriver.Timeouts obter mais informações.


3
Obrigado, então o que acontece aqui se a página for carregada antes de 10 segundos, ainda vai esperar 10 segundos para executar a próxima linha após o carregamento?
Girish

Não, se a sua página carregar antes de 10 segundos significa que ela encerrará a condição de espera e executará a linha anterior.
Manigandan

3
Isso é usado para quando você espera que os carregamentos de páginas demorem muito tempo para exceder o tempo limite e gerem exceções, ele não espera imediatamente um carregamento de página ou define uma política de carregamento melhor. Como o tempo é infinito, o carregamento da página nunca gera exceções e o Selenium sempre tenta esperar o carregamento completo.
Petr Janeček

19
O problema com esse método é que é possível que o DOM não esteja totalmente acessível, mesmo que a espera implícita tenha retornado com êxito um objeto WebElement anteriormente. Então, se você tentar clicar no elemento, receberá uma exceção do elemento obsoleto. Portanto, essa resposta não é totalmente segura.
djangofan

3
Como esse tempo limite está relacionado à espera do carregamento de um documento?
Anders Lindén

90

Sua solução sugerida aguarda apenas que o DOMreadyState sinalize complete. No entanto, o Selenium, por padrão, tenta aguardar o carregamento das páginas (e um pouco mais) na página através dos métodos driver.get()e element.click(). Eles já estão bloqueando, aguardam o carregamento completo da página e eles devem estar funcionando bem.

Os problemas, obviamente, são os redirecionamentos por meio de solicitações AJAX e scripts em execução - aqueles não podem ser capturados pelo Selenium, não espera que eles terminem. Além disso, você não pode pegá-los de maneira confiável readyState- ele espera um pouco, o que pode ser útil, mas sinalizará completemuito antes de todo o conteúdo AJAX ser baixado.

Não existe uma solução geral que funcione em todos os lugares e para todos, é por isso que é difícil e todo mundo usa algo um pouco diferente.

A regra geral é confiar no WebDriver para fazer sua parte, usar esperas implícitas e depois esperas explícitas para os elementos que você deseja afirmar na página, mas há muito mais técnicas que podem ser feitas. Você deve escolher aquele (ou uma combinação de vários deles) que funciona melhor no seu caso, na sua página testada.

Veja minhas duas respostas sobre isso para obter mais informações:


20
Isso é impreciso, o Selenium não espera nem bloqueia as element.click()chamadas.
hwjp 3/09/14

3
@hwjp Gostaria de elaborar mais? Os JavaDocs dizem o contrário : "Se isso fizer com que uma nova página seja carregada, esse método tentará bloquear até que a página seja carregada."
Petr Janeček

5
Veja algumas conversas que tive na lista de endereços que parecem imprecisas. o selenium pode bloquear as chamadas .get nas quais você solicita explicitamente uma URL, mas não faz nada de especial nas chamadas de clique, porque não pode dizer se você clicou em um hiperlink "real" ou em um que será interceptado por javascript. ..
hwjp 3/09/14

4
Eu vinculo a um bug no início da discussão da lista de discussão. Até os documentos equivocam: "Se click () for [...] feito enviando um evento nativo, o método * não * esperará"
hwjp

4
Portanto, tudo indica se o navegador está usando "eventos nativos". E parece que a maioria deles, por padrão: code.google.com/p/selenium/wiki/… (então eu diria que esses documentos são enganosos, na melhor das hipóteses. Irá executar ping na lista de discussão).
hwjp 4/09/14

61

Esta é uma versão Java funcional do exemplo que você deu:

void waitForLoad(WebDriver driver) {
    new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

Exemplo para c #:

public static void WaitForLoad(IWebDriver driver, int timeoutSec = 15)
{
  IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
  WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
  wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}

1
Cara, eu estou copiando / colando isso. Este trecho é simplesmente brilhante. Por que eu não pensei nisso? Verdade que mais de um par de globos oculares sempre levam a uma boa solução. Obrigado.
Luis.espinal

2
Você pode colocar isso em java 1.7 versão compatível como expressões lambda não suporta
vkrams

3
Versão Java 1.7: wait.until (novo Predicado <WebDriver> () {aplicação pública booleana (driver WebDriver) {retorno (driver (JavascriptExecutor)) .executeScript ("return document.readyState"). Equals ("complete");} });
luQ 29/09

1
Se alguém quiser usar a solução por @IuQ então, predicado tem de importaçãoimport com.google.common.base.Predicate
Knu8

Eu tentei essa idéia em um aplicativo de teste VB. Funciona na maioria das vezes. Às vezes, recebo esse erro: System.InvalidOperationException: erro de JavaScript (UnexpectedJavaScriptError) no OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError (Response errorResponse) O aplicativo de teste clica no link de menu do nível 2 e chama WaitObj.Until (DirectCast de função (D) ( D, InternetExplorerDriver) .ExecuteScript ("return document.readyState") = "complete"). Acho que o erro é causado porque o navegador descarrega a página atual e não é um objeto de documento. Talvez espere 1/2 segundo antes de fazer "devolver document.readystate? Ideas? #
CoolBreeze

12

Aqui está minha tentativa de uma solução completamente genérica, 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 conta com o fato de que o selênio registra um número de identificação (interno) para todos os elementos em uma página, incluindo o <html>elemento de nível superior . 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 do blog aqui


Abordagem muito interessante. Um desafio é se isso pode funcionar no carregamento inicial da página, depois que o navegador é iniciado. Não há garantia de que o estado inicial do navegador tenha qualquer página carregada. Além disso, em Java, não estou vendo que temos um 'id' no objeto - suponho que você não queira dizer que o selênio insere um atributo de html id. Acrescentarei mais a essa resposta depois de explorar mais essa opção. Obrigado pelo post!
Lukus 7/03

@hwjp Eu uso essa solução muitas vezes com excelentes resultados, mas parece que ela não funciona em um caso. Explicação completa do problema stackoverflow.com/q/31985739/4249707
El Ruso

7

Eu tive um problema parecido. Eu precisava esperar até que meu documento estivesse pronto, mas também até que todas as chamadas do Ajax terminassem. A segunda condição mostrou-se difícil de detectar. No final, verifiquei as chamadas ativas do Ajax e funcionou.

Javascript:

return (document.readyState == 'complete' && jQuery.active == 0)

Método C # completo:

private void WaitUntilDocumentIsReady(TimeSpan timeout)
{
    var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
    var wait = new WebDriverWait(WebDriver, timeout);            

    // Check if document is ready
    Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
        .ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
    wait.Until(readyCondition);
}

Existe algo parecido document.readyState == 'complete' && jQuery.active == 0com React?
Rain9333

7
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));

4

Para C # NUnit, você precisa converter o WebDriver em JSExecuter e, em seguida, executar o script para verificar se o estado document.ready está completo ou não. Verifique o código abaixo para referência:

 public static void WaitForLoad(IWebDriver driver)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        int timeoutSec = 15;
        WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
        wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
    }

Isso aguardará até que a condição seja atendida ou o tempo limite.


3

Para o carregamento inicial da página, notei que "Maximizar" a janela do navegador praticamente espera até que o carregamento da página seja concluído (incluindo fontes)

Substituir:

AppDriver.Navigate().GoToUrl(url);

Com:

public void OpenURL(IWebDriver AppDriver, string Url)
            {
                try
                {
                    AppDriver.Navigate().GoToUrl(Url);
                    AppDriver.Manage().Window.Maximize();
                    AppDriver.SwitchTo().ActiveElement();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
                    throw;
                }
            }

do que usar:

OpenURL(myDriver, myUrl);

Isso carregará a página, espere até a conclusão, maximize e foque nela. Não sei por que é assim, mas funciona.

Se você quiser aguardar o carregamento da página após clicar no próximo ou em qualquer outro gatilho de navegação da página que não seja "Navigate ()", a resposta de Ben Dyer (neste tópico) fará o trabalho.


1

Dê uma olhada na estrutura da Web para tapeçaria . Você pode baixar o código fonte lá.

A idéia é sinalizar que a página está pronta pelo atributo html do corpo. Você pode usar essa idéia para ignorar casos de processos complicados.

<html>
<head>
</head>
<body data-page-initialized="false">
    <p>Write you page here</p>

    <script>
    $(document).ready(function () {
        $(document.body).attr('data-page-initialized', 'true');
    });
    </script>  
</body>
</html>

E então crie a extensão do Selenium webdriver (de acordo com a estrutura da tapeçaria)

public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
    //wait a bit for the page to start loading
    Thread.Sleep(100);

    //// In a limited number of cases, a "page" is an container error page or raw HTML content
    // that does not include the body element and data-page-initialized element. In those cases,
    // there will never be page initialization in the Tapestry sense and we return immediately.
    if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
    {                
        return;
    }

    Stopwatch stopwatch = Stopwatch.StartNew();

    int sleepTime = 20;

    while(true)
    {
        if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
        {
            return;
        }

        if (stopwatch.ElapsedMilliseconds > 30000)
        {
            throw new Exception("Page did not finish initializing after 30 seconds.");
        }

        Thread.Sleep(sleepTime);
        sleepTime *= 2; // geometric row of sleep time
    }          
}

Use a extensão ElementIsDisplayed, escrita por Alister Scott .

public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
    try
    {
        return driver.FindElement(By.XPath(xpath)).Displayed;
    }
    catch(NoSuchElementException)
    {
        return false;
    }
}

E, finalmente, crie o teste:

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();

1

A resposta de Ben Dryer não foi compilada na minha máquina ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait").

Versão de trabalho do Java 8:

Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
        "return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);

Versão Java 7:

Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver input) {
            return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
        }

};
new FluentWait<WebDriver>(driver).until(pageLoaded);

1

Eu tentei esse código e funciona para mim. Eu chamo essa função toda vez que mudo para outra página

public static void waitForPageToBeReady() 
{
    JavascriptExecutor js = (JavascriptExecutor)driver;

    //This loop will rotate for 100 times to check If page Is ready after every 1 second.
    //You can replace your if you wants to Increase or decrease wait time.
    for (int i=0; i<400; i++)
    { 
        try 
        {
            Thread.sleep(1000);
        }catch (InterruptedException e) {} 
        //To check page ready state.

        if (js.executeScript("return document.readyState").toString().equals("complete"))
        { 
            break; 
        }   
      }
 }

1

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)


1

A espera pelo evento document.ready não é a correção completa para esse problema, porque esse código ainda está em uma condição de corrida: Às vezes, esse código é acionado antes que o evento click seja processado e, portanto, retorna diretamente, pois o navegador não foi iniciado carregando a nova página ainda.

Depois de algumas pesquisas, encontrei um post sobre Obay the bode test , que tem uma solução para esse problema. O código c # para essa solução é algo como isto:

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}

`Eu aciono esse método diretamente após o driver.navigate.gotourl, para que ele obtenha uma referência da página o mais rápido possível. Divirta-se com isso!


1

normalmente, quando o selênio abre uma nova página com um clique, envia ou obtém métodos, ele espera até que a página seja carregada, mas o problema é que, quando a página recebe uma chamada xhr (ajax), ele nunca espera que a xhr seja carregada, portanto criar um novo método para monitorar um xhr e esperar por eles será bom.

public boolean waitForJSandJQueryToLoad() {
    WebDriverWait wait = new WebDriverWait(webDriver, 30);
    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
            Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
            return r == 0;
        } catch (Exception e) {
            LOG.info("no jquery present");
            return true;
        }
      }
    };

    // wait for Javascript to load
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor)driver).executeScript("return document.readyState")
        .toString().equals("complete");
      }
    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);
}

if $.active == 0portanto, não há chamada xhrs ativa (que funciona apenas com jQuery). para a chamada de javascript ajax, você deve criar uma variável em seu projeto e simulá-la.


0

Você pode escrever alguma lógica para lidar com isso. Eu escrevi um método que retornará o WebElemente esse método será chamado três vezes ou você poderá aumentar o tempo e adicionar uma verificação nula. WebElementAqui está um exemplo

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.crowdanalytix.com/#home");
        WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
        int i = 1;
        while (webElement == null && i < 4) {
            webElement = getWebElement(driver, "homessssssssssss");
            System.out.println("calling");
            i++;
        }
        System.out.println(webElement.getTagName());
        System.out.println("End");
        driver.close();
    }

    public static WebElement getWebElement(WebDriver driver, String id) {
        WebElement myDynamicElement = null;
        try {
            myDynamicElement = (new WebDriverWait(driver, 10))
                    .until(ExpectedConditions.presenceOfElementLocated(By
                            .id(id)));
            return myDynamicElement;
        } catch (TimeoutException ex) {
            return null;
        }
    }

0

Eu executei um código javascript para verificar se o documento está pronto. Economizei muito tempo depurando testes de selênio para sites com renderização do lado do cliente.

public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
    Thread.sleep(100)
    def ready = isDOMReady(driver);
    if (ready) {
        break;
    }
}

}

public static boolean isDOMReady(WebDriver driver){
    return driver.executeScript("return document.readyState");
}

0
public boolean waitForElement(String zoneName, String element, int index, int timeout) {
        WebDriverWait wait = new WebDriverWait(appiumDriver, timeout/1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(element)));
        return true;
    }

0

Como Rubanov escreveu para C #, eu escrevo para Java, e é:

    public void waitForPageLoaded() {
    ExpectedCondition<Boolean> expectation = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return (((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete")&&((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")));
                }
            };
    try {
        Thread.sleep(100);
        WebDriverWait waitForLoad = new WebDriverWait(driver, 30);
        waitForLoad.until(expectation);
    } catch (Throwable error) {
        Assert.fail("Timeout waiting for Page Load Request to complete.");
    }
}

0

Em Java, ele será exibido abaixo: -

  private static boolean isloadComplete(WebDriver driver)
    {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    }

1
Seria melhor para combinar os comandos JS em um modo que você não tem que bater a página duas vezes, por exemploreturn document.readyState == 'loaded' || return document.readyState == 'complete'
JeffC

0

O código a seguir provavelmente deve funcionar:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfAllElementsLocated(By.xpath("//*")));

0

Se você tiver uma conexão de rede ou página lenta, é provável que nenhuma das opções acima funcione. Eu tentei todos eles e a única coisa que funcionou para mim é esperar o último elemento visível nessa página. Tomemos, por exemplo, a página da web do Bing. Eles colocaram um ícone CÂMERA (botão de pesquisa por imagem) ao lado do botão de pesquisa principal que fica visível somente após o carregamento da página completa. Se todos fizeram isso, tudo o que precisamos fazer é usar uma espera explícita, como nos exemplos acima.


-1
public void waitForPageToLoad()
  {
(new WebDriverWait(driver, DEFAULT_WAIT_TIME)).until(new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver d) {
        return (((org.openqa.selenium.JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
      }
    });//Here DEFAULT_WAIT_TIME is a integer correspond to wait time in seconds

-1

Aqui está algo semelhante, em Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }

Seu código não funciona para mim. Como alterno iframe e aguardo onload = "javascript: pageload (); functionalPageLoad ();" recarregar a página em Ruby? Encontro-me abrindo o iframe dentro de uma página, tenho acesso a ele, a página é recarregada e não consigo mais acessar o quadro. Eu li muitas respostas sobre espera, sono, tempo, mude para o frame e depois para o pai, mas não consigo alcançar meu objetivo.
Amanda Cavallaro

1
Parece que sua pergunta é principalmente sobre como mudar para o iFrame, não sobre aguardar o carregamento do documento. Talvez seja melhor iniciar uma nova pergunta se você não encontrar a solução em uma pergunta sobre como trabalhar com os iFrames.
esmeril

-1

Você pode manter o encadeamento até que a página seja recarregada. Esta não é a melhor solução, porque você precisa ter uma estimativa de quanto tempo a página leva para carregar.

driver.get(homeUrl); 
Thread.sleep(5000);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(userName);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(passWord);
driver.findElement(By.xpath("Your_Xpath_here")).click();

Acho Thread.sleep (5000) geralmente é o único método que faz um teste funcionar, apesar de todas as recomendações contra o uso. Nenhuma combinação de espera por elemento funciona para mim, especialmente porque muitos elementos não podem ser identificados até que eles tenham sido realmente encontrados.
Steve Staple

-1

Verifiquei o carregamento da página completo, trabalho no Selenium 3.14.0

    public static void UntilPageLoadComplete(IWebDriver driver, long timeoutInSeconds)
    {
        Until(driver, (d) =>
        {
            Boolean isPageLoaded = (Boolean)((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete");
            if (!isPageLoaded) Console.WriteLine("Document is loading");
            return isPageLoaded;
        }, timeoutInSeconds);
    }

    public static void Until(IWebDriver driver, Func<IWebDriver, Boolean> waitCondition, long timeoutInSeconds)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
        webDriverWait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
        try
        {
            webDriverWait.Until(waitCondition);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

-1

Para as pessoas que precisam esperar que um elemento específico apareça. (c # usado)

public static void WaitForElement(IWebDriver driver, By element)
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    wait.Until(ExpectedConditions.ElementIsVisible(element));
}

Então, se você quiser esperar, por exemplo, se uma classe = "mensagem de erro" existir no DOM, você simplesmente faz:

WaitForElement(driver, By.ClassName("error-message"));

Para id, será

WaitForElement(driver, By.Id("yourid"));


-3

Você está usando Angular? Se estiver, é possível que o webdriver não reconheça que as chamadas assíncronas foram concluídas.

Eu recomendo olhar para Paul Hammants ngWebDriver . O método waitForAngularRequestsToFinish () pode ser útil.


Ele não estava usando Angular. Esta resposta foi diminuída porque parece que você não leu cuidadosamente a pergunta original.
Zelusp

Mas não desaponte os votos o deixam fora de forma. As pessoas aqui querem dizer bem. E a crítica é realmente uma forma de amor (porque se alguém dedica tempo para corrigir alguém, é porque se importa). Caixa Como fazer perguntas da maneira inteligente - essas idéias também se aplicam a responder a perguntas da maneira inteligente.
Zelusp
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.