Selenio attendere che il documento sia pronto


133

Qualcuno può farmi sapere come posso aspettare il selenio fino al completo caricamento della pagina? Voglio qualcosa di generico, so di poter configurare WebDriverWait e chiamare qualcosa come 'find' per farlo aspettare ma non vado così lontano. Ho solo bisogno di testare che la pagina si carica correttamente e passare alla pagina successiva per testare.

Ho trovato qualcosa in .net ma non riuscivo a farlo funzionare in 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"));

Qualche pensiero qualcuno?


Perché non vuoi usare wait?
Amey,

7
Intendi aspettare esplicitamente? Richiede tempo, sto testando circa 10k pagine.
Girish,

2
Voglio dire, aggiungere un'attesa di correzione potrebbe non essere una buona idea se sto testando un gran numero di collegamenti, giusto?
Girish,

10
Aspettare un numero fisso di secondi è inutile. Questo è indovinare.
Anders Lindén,

Dato che il javascript di una pagina può eseguire qualsiasi codice generico, è impossibile scrivere un programma in attesa del suo completamento. È una forma del problema di Halting ( en.wikipedia.org/wiki/Halting_problem ). Qualsiasi soluzione qui dovrà scendere a compromessi o basarsi su ipotesi della pagina Web sottostante.
speedplane il

Risposte:


83

Prova questo codice:

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

Il codice sopra attenderà fino a 10 secondi per il caricamento della pagina. Se il caricamento della pagina supera il tempo che genererà TimeoutException. Prendi l'eccezione e fai le tue esigenze. Non sono sicuro che esca dal caricamento della pagina dopo l'eccezione generata. non ho ancora provato questo codice. Vuoi solo provarlo.

Questa è un'attesa implicita. Se lo imposti una volta, avrà l'ambito fino alla distruzione dell'istanza del driver Web.

Vedere la documentazioneWebDriver.Timeouts per ulteriori informazioni.


3
Grazie, quindi cosa succede qui se la pagina viene caricata prima di 10 secondi, aspetteranno comunque 10 secondi per eseguire la riga successiva dopo il caricamento?
Girish,

No se la tua pagina viene caricata prima di 10 secondi significa che terminerà la condizione di attesa ed eseguirà la riga precedente.
Manigandan,

3
Viene utilizzato quando si prevedono carichi di pagina troppo lunghi per il timeout e genera eccezioni, non attende immediatamente il caricamento della pagina o imposta una migliore politica di caricamento. Il tempo di default è infinito, quindi i tuoi caricamenti di pagine non generano mai eccezioni e Selenium cerca sempre di aspettare che si carichino completamente.
Petr Janeček,

19
Il problema con questo metodo è che è possibile che il DOM non sia completamente accessibile anche se l'attesa implicita ha precedentemente restituito correttamente un oggetto WebElement. Quindi, se provi a fare clic sull'elemento otterrai un'eccezione di elemento non aggiornato. Quindi, questa risposta non è del tutto sicura.
Djangofan,

3
In che modo questo timeout è legato all'attesa per il caricamento di un documento?
Anders Lindén,

90

La soluzione suggerita attende solo il segnale DOMreadyStatecomplete . Ma il selenio di default cerca di attendere quelli (e un po 'di più) sulla pagina caricata tramite i metodi driver.get()e element.click(). Stanno già bloccando, aspettano che la pagina si carichi completamente e quelli dovrebbero funzionare bene.

Il problema, ovviamente, sono i reindirizzamenti tramite richieste AJAX e script in esecuzione: questi non possono essere colti da Selenium, non aspetta che finiscano. Inoltre, non è possibile catturarli in modo affidabile tramite readyState: attende un po ', il che può essere utile, ma segnalerà completemolto prima che venga scaricato tutto il contenuto AJAX.

Non esiste una soluzione generale che funzioni ovunque e per tutti, ecco perché è difficile e tutti usano qualcosa di leggermente diverso.

La regola generale è fare affidamento su WebDriver per fare la sua parte, quindi utilizzare le attese implicite, quindi usare le attese esplicite per gli elementi che si desidera affermare sulla pagina, ma ci sono molte più tecniche che possono essere fatte. Dovresti scegliere quello (o una combinazione di più di essi) che funziona meglio nel tuo caso, sulla tua pagina di test.

Vedi le mie due risposte a riguardo per ulteriori informazioni:


20
È inaccurato, il selenio non aspetta o blocca le element.click()chiamate.
hwjp,

3
@hwjp Cura di elaborare di più? JavaDocs dice diversamente : "Se questo provoca il caricamento di una nuova pagina, questo metodo tenterà di bloccare fino al caricamento della pagina."
Petr Janeček,

5
cf alcune conversazioni che ho avuto sulla mailing list sembra che sia inaccurato. il selenio potrebbe bloccare le chiamate .get dove richiedi esplicitamente un URL, ma non fa nulla di speciale sulle chiamate click, perché non può dire se hai fatto clic su un hyperlink "reale" o su uno che verrà intercettato da javascript. ..
hwjp,

4
Collegamento a un bug all'inizio della discussione sulla mailing list. Anche i documenti si equivalgono: "Se click () [...] viene eseguito inviando un evento nativo, il metodo * non * attenderà"
hwjp

4
Quindi tutto si accende se il browser utilizza "eventi nativi". E sembra che la maggior parte di loro, per impostazione predefinita: code.google.com/p/selenium/wiki/… (quindi direi che quei documenti sono fuorvianti nella migliore delle ipotesi. Eseguiranno il ping della mailing list).
hwjp,

61

Questa è una versione Java funzionante dell'esempio che hai fornito:

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

Esempio per 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
Amico, lo sto copiando / incollando. Questo frammento è semplicemente geniale. Perché non ci ho pensato? La verità che più di un paio di bulbi oculari portano sempre a una buona soluzione. Grazie.
luis.espinal

2
Puoi metterlo in versione java 1.7 compatibile perché le espressioni lambda non supportano
vkrams

3
Versione Java 1.7: wait.until (nuovo Predicate <WebDriver> () {public boolean apply (driver WebDriver) {return ((JavascriptExecutor) driver) .executeScript ("return document.readyState"). Equals ("complete");} });
LuQ

1
Se qualcuno vuole usare la soluzione di @IuQ, Predicate ha importatoimport com.google.common.base.Predicate
Knu8

Ho provato questa idea in un'app di test VB. Funziona la maggior parte del tempo. Ricevo questo errore a volte: System.InvalidOperationException: errore JavaScript (UnexpectedJavaScriptError) su OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError (Response errorResponse) Test app fa clic sul collegamento del menu di livello 2, quindi chiama WaitObj.Until (Funzione (DirectC) D, InternetExplorerDriver) .ExecuteScript ("return document.readyState") = "complete"). Penso che l'errore sia causato perché il browser scarica la pagina corrente e non è un oggetto documento. Forse attendere 1/2 sec prima di fare "return document.readystate? Idee?
CoolBreeze

12

Ecco il mio tentativo di una soluzione completamente generica, in Python:

Innanzitutto, una generica funzione "wait" (usa un WebDriverWait se vuoi, li trovo brutti):

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__))

Successivamente, la soluzione si basa sul fatto che il selenio registra un numero ID (interno) per tutti gli elementi di una pagina, incluso il livello superiore <html> elemento di . Quando una pagina si aggiorna o si carica, ottiene un nuovo elemento HTML con un nuovo ID.

Quindi, supponendo che si desideri fare clic su un collegamento con il testo "il mio collegamento", ad esempio:

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)

Per ulteriori helper Pythonic, riutilizzabili e generici, puoi creare un gestore di contesto:

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 poi puoi usarlo praticamente su qualsiasi interazione di selenio:

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

Credo sia a prova di proiettile! Cosa ne pensi?

Maggiori informazioni in un post sul blog qui


Approccio molto interessante. Una sfida è se questo può funzionare al caricamento della pagina iniziale, dopo il primo avvio del browser. Non esiste alcuna garanzia che lo stato iniziale del browser abbia una pagina caricata. Inoltre, in Java, non vedo che abbiamo un 'id' sull'oggetto - suppongo che tu non voglia dire che il selenio inserisce un attributo html id. Aggiungerò altro a questa risposta dopo aver esplorato di più questa opzione. Grazie per il post!
Lukus

@hwjp Uso questa soluzione molte volte con risultati eccellenti, ma sembra che non funzioni in un caso. Spiegazione completa del problema stackoverflow.com/q/31985739/4249707
El Ruso

7

Ho avuto un problema simile. Dovevo aspettare che il mio documento fosse pronto, ma anche che tutte le chiamate Ajax fossero terminate. La seconda condizione si è rivelata difficile da rilevare. Alla fine ho controllato le chiamate Ajax attive e ha funzionato.

Javascript:

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

Metodo 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);
}

C'è qualcosa come document.readyState == 'complete' && jQuery.active == 0React?
Rain9333,

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

4

Per C # NUnit, è necessario convertire WebDriver in JSExecuter e quindi eseguire lo script per verificare se lo stato document.ready è completo o meno. Controlla sotto il codice per riferimento:

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

Questo attenderà fino a quando la condizione è soddisfatta o timeout.


3

Per il caricamento iniziale della pagina ho notato che "Massimizzare" la finestra del browser praticamente aspetta fino al completamento del caricamento della pagina (comprese le fonti)

Sostituire:

AppDriver.Navigate().GoToUrl(url);

Con:

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;
                }
            }

che usare:

OpenURL(myDriver, myUrl);

Questo caricherà la pagina, attenderà il completamento, massimizzerà e si concentrerà su di essa. Non so perché sia ​​così ma funziona.

Se vuoi attendere il caricamento della pagina dopo aver fatto clic sul successivo o qualsiasi altro trigger di navigazione della pagina diverso da "Naviga ()", la risposta di Ben Dyer (in questo thread) farà il lavoro.


1

Dai un'occhiata al framework web degli arazzi . Puoi scaricare il codice sorgente lì.

L'idea è di segnalare che la pagina è pronta per l'attributo html di body. È possibile utilizzare questa idea ignorare casi di causa complicati.

<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 quindi creare l'estensione del webdriver Selenium (secondo il framework degli arazzi)

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
    }          
}

Usa l'estensione ElementIsDisplayed scritta da Alister Scott .

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

E infine crea il test:

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

1

La risposta di Ben Dryer non è stata compilata sulla mia macchina ("The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait" ).

Versione funzionante di Java 8:

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

Versione 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

Ho provato questo codice e funziona per me. Chiamo questa funzione ogni volta che mi sposto in un'altra pagina

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

In Nodejs puoi ottenerlo tramite le promesse ...

Se scrivi questo codice, puoi essere sicuro che la pagina è completamente caricata quando arrivi a ...

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

Se scrivi questo codice, navigherai e il selenio attenderà 3 secondi ...

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...

Dalla documentazione del selenio:

this.get (url) → Thenable

Pianifica un comando per passare all'URL specificato.

Restituisce una promessa che verrà risolta al termine del caricamento del documento .

Documentazione sul selenio (Nodejs)


1

L'attesa per l'evento document.ready non è l'intera soluzione a questo problema, perché questo codice è ancora in una condizione di competizione: a volte questo codice viene generato prima che l'evento click venga elaborato in modo che ritorni direttamente, poiché il browser non è stato avviato caricamento della nuova pagina ancora.

Dopo alcune ricerche ho trovato un post su Obay, la capra test , che ha una soluzione per questo problema. Il codice c # per quella soluzione è qualcosa del genere:

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

}

`Attiro questo metodo direttamente dopo il driver.navigate.gotourl, in modo che ottenga un riferimento della pagina il più presto possibile. Divertiti con esso!


1

normalmente quando il selenio apre una nuova pagina da un clic o invia o ottiene metodi, attenderà fino a quando la pagina non viene caricata ma il problema è quando la pagina ha una chiamata xhr (ajax) non aspetterà mai che la xhr venga caricata, quindi creare un nuovo metodo per monitorare un xhr e aspettare che sia buono.

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 == 0quindi non è una chiamata xhrs attiva (che funziona solo con jQuery). per javascript ajax call devi creare una variabile nel tuo progetto e simularla.


0

Puoi scrivere un po 'di logica per gestirlo. Ho scritto un metodo che restituirà il WebElemente questo metodo verrà chiamato tre volte oppure è possibile aumentare il tempo e aggiungere un controllo null per WebElementEcco un esempio

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

Ho eseguito un codice JavaScript per verificare se il documento è pronto. Mi ha risparmiato molto tempo nel debug dei test al selenio per i siti con rendering lato client.

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

Come ha scritto Rubanov per C #, lo scrivo per Java, ed è:

    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

In Java piacerà di seguito: -

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

1
Sarebbe meglio combinare i comandi JS in uno in modo da non dover return document.readyState == 'loaded' || return document.readyState == 'complete'
toccare

0

Il seguente codice dovrebbe probabilmente funzionare:

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

0

Se hai una pagina lenta o una connessione di rete, è probabile che nessuna delle precedenti funzioni. Li ho provati tutti e l'unica cosa che ha funzionato per me è aspettare l'ultimo elemento visibile su quella pagina. Prendi ad esempio la pagina web di Bing. Hanno posizionato un'icona CAMERA (ricerca per pulsante immagine) accanto al pulsante di ricerca principale che è visibile solo dopo il caricamento della pagina completa. Se lo facessero tutti, tutto ciò che dobbiamo fare è usare un'attesa esplicita come negli esempi sopra.


-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

Ecco qualcosa di simile, in Ruby:

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

Il tuo codice non funziona per me. Come cambio do iframe e aspetto onload = "javascript: pageload (); funzionalePageLoad ();" ricaricare la pagina in Ruby? Mi ritrovo ad aprire l'iframe all'interno di una pagina, ho accesso ad esso, quindi la pagina si ricarica e non riesco più ad accedere al frame. Ho letto molte risposte riguardo l'attesa, il sonno, il tempo, passa al frame e poi al genitore, tuttavia non riesco a raggiungere il mio obiettivo.
Amanda Cavallaro,

1
Sembra che la tua domanda sia principalmente su come passare a iFrame, non sull'attesa del caricamento del documento. Potrebbe essere meglio iniziare una nuova domanda se non riesci a trovare la soluzione in una domanda su come lavorare con iFrames.
smeriglio

-1

Puoi fare in modo che il thread sia inattivo fino a quando la pagina non viene ricaricata. Questa non è la soluzione migliore, perché è necessario disporre di una stima del tempo necessario per caricare la pagina.

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

Trovo che Thread.sleep (5000) sia spesso l'unico metodo che fa funzionare un test, nonostante tutte le raccomandazioni contro l'uso. Nessuna combinazione di wait for element funziona per me, soprattutto perché molti elementi non possono essere identificati fino a quando non sono stati effettivamente trovati.
Steve Staple,

-1

Ho verificato il caricamento della pagina completato, lavoro in 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

Per le persone che devono attendere la visualizzazione di un elemento specifico. (usato c #)

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

Quindi se vuoi aspettare, ad esempio, se nel DOM esiste un class = "messaggio di errore", devi semplicemente:

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

Per id, sarà quindi

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


-3

Stai usando Angular? In tal caso, è possibile che il webdriver non riconosca che le chiamate asincrone sono terminate.

Consiglio di guardare Paul Hammants ngWebDriver . Il metodo waitForAngularRequestsToFinish () potrebbe tornare utile.


Non usava molto Angular. Questa risposta è stata annullata perché sembra che tu non abbia letto attentamente la domanda originale.
zelusp,

Ma non deludere i voti che ti piegano fuori forma. Le persone qui intendono bene. E la critica è in realtà una forma di amore (perché se qualcuno si prende il tempo di correggere qualcuno è perché a loro importa). Checkout Come porre domande in modo intelligente : queste idee si applicano anche alle risposte in modo intelligente.
zelusp,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.