Selenium menunggu hingga dokumen siap

133

Adakah yang bisa membiarkan saya bagaimana saya bisa membuat selenium menunggu sampai waktu halaman dimuat sepenuhnya? Saya ingin sesuatu yang generik, saya tahu saya bisa mengkonfigurasi WebDriverWait dan memanggil sesuatu seperti 'temukan' untuk membuatnya menunggu tetapi saya tidak melangkah sejauh itu. Saya hanya perlu menguji bahwa halaman berhasil dimuat dan beralih ke halaman berikutnya untuk menguji.

Saya menemukan sesuatu di .net tetapi tidak dapat membuatnya bekerja di 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"));

Adakah yang berpikir?

Girish
sumber
Mengapa Anda tidak ingin menggunakan tunggu?
Amey
7
Maksud Anda tunggu eksplisit? Ini memakan waktu, saya menguji beberapa halaman 10k.
Girish
2
Maksud saya, menambahkan fix fix mungkin bukan ide yang bagus jika saya menguji sejumlah besar tautan, bukan?
Girish
10
Menunggu beberapa detik tidak berguna. Itu hanya menebak.
Anders Lindén
Mengingat bahwa javascript halaman dapat menjalankan kode generik apa pun, menulis program untuk menunggu penyelesaiannya tidak mungkin. Ini adalah bentuk dari Masalah Pemutusan Hubungan ( en.wikipedia.org/wiki/Halting_problem ). Solusi apa pun di sini perlu membuat kompromi atau didasarkan pada asumsi halaman web yang mendasarinya.
speedplane

Jawaban:

83

Coba kode ini:

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

Kode di atas akan menunggu hingga 10 detik untuk memuat halaman. Jika memuat halaman melebihi waktu itu akan membuang TimeoutException. Anda menangkap pengecualian dan melakukan kebutuhan Anda. Saya tidak yakin apakah itu berhenti memuat halaman setelah pengecualian dilemparkan. saya belum mencoba kode ini. Mau coba saja.

Ini adalah penantian implisit. Jika Anda menetapkan ini sekali, ia akan memiliki ruang lingkup sampai contoh Driver Web menghancurkan.

Lihat dokumentasi untukWebDriver.Timeouts informasi lebih lanjut.

Manigandan
sumber
3
Terima kasih, jadi apa yang terjadi di sini jika halaman dimuat sebelum 10 detik, apakah masih menunggu 10 detik untuk menjalankan baris berikutnya setelah memuat?
Girish
Tidak jika halaman Anda dimuat sebelum 10 detik berarti itu akan menghentikan kondisi tunggu dan menjalankan baris sebelumnya.
Manigandan
3
Ini digunakan untuk saat Anda mengharapkan pemuatan halaman yang terlalu lama untuk kehabisan waktu dan membuang pengecualian, itu tidak langsung menunggu pemuatan halaman atau menetapkan kebijakan pemuatan yang lebih baik. Ini default ke waktu yang tak terbatas, sehingga halaman Anda tidak pernah membuang pengecualian dan Selenium selalu mencoba untuk menunggu mereka memuat sepenuhnya.
Petr Janeček
19
Masalah dengan metode ini adalah kemungkinan DOM tidak sepenuhnya dapat diakses meskipun tunggu implisit sebelumnya berhasil mengembalikan objek WebElement. Kemudian, jika Anda mencoba mengklik elemen Anda akan mendapatkan pengecualian elemen basi. Jadi, jawaban ini tidak sepenuhnya aman.
djangofan
3
Bagaimana batas waktu ini terkait dengan menunggu dokumen dimuat?
Anders Lindén
90

Solusi yang Anda sarankan hanya menunggu sinyal DOMreadyStatecomplete . Tapi Selenium secara default mencoba menunggu mereka (dan sedikit lebih banyak) pada halaman dimuat melalui metode driver.get()dan element.click(). Mereka sudah memblokir, mereka menunggu halaman untuk memuat penuh dan itu harus berfungsi ok.

Masalahnya, jelasnya, pengalihan melalui permintaan AJAX dan menjalankan skrip - yang tidak bisa ditangkap oleh Selenium, tidak menunggu sampai selesai. Selain itu, Anda tidak dapat menangkapnya dengan andal readyState- ia menunggu sebentar, yang dapat berguna, tetapi akan memberi sinyal completejauh sebelum semua konten AJAX diunduh.

Tidak ada solusi umum yang akan bekerja di mana-mana dan untuk semua orang, itu sebabnya sulit dan semua orang menggunakan sesuatu yang sedikit berbeda.

Aturan umumnya adalah bergantung pada WebDriver untuk melakukan bagiannya, kemudian gunakan tunggu implisit, lalu gunakan tunggu eksplisit untuk elemen yang ingin Anda nyatakan pada halaman, tetapi ada banyak lagi teknik yang bisa dilakukan. Anda harus memilih salah satu (atau kombinasi beberapa di antaranya) yang paling sesuai untuk kasus Anda, pada halaman yang Anda uji.

Lihat dua jawaban saya tentang ini untuk informasi lebih lanjut:

Petr Janeček
sumber
20
Itu tidak akurat, Selenium tidak menunggu atau memblokir element.click()panggilan.
hwjp
3
@hwjp Peduli untuk menguraikan lebih lanjut? JavaDocs mengatakan sebaliknya : "Jika ini menyebabkan halaman baru dimuat, metode ini akan mencoba untuk memblokir sampai halaman telah dimuat."
Petr Janeček
5
cf beberapa percakapan saya di milis sepertinya itu tidak akurat. selenium mungkin mencekal. dapatkan panggilan di mana Anda secara eksplisit meminta URL, tetapi tidak ada yang istimewa pada panggilan klik, karena itu tidak dapat memastikan apakah Anda mengklik hyperlink "asli" atau pada tautan yang akan dicegat oleh javascript. ..
hwjp
4
Saya menautkan ke bug di awal diskusi milis. Bahkan docs dalih: "Jika klik () [...] dilakukan dengan mengirimkan acara asli maka metode ini * tidak * menunggu"
hwjp
4
Jadi semuanya menyala apakah browser menggunakan "acara asli". Dan sepertinya sebagian besar dari mereka akan, secara default: code.google.com/p/selenium/wiki/… (jadi saya katakan dokumen-dokumen itu paling menyesatkan. Akan melakukan ping ke milis).
hwjp
61

Ini adalah versi Java yang berfungsi dari contoh yang Anda berikan:

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

Contoh untuk 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");
}
Ben Dyer
sumber
1
Bung, saya salin / tempel ini. Cuplikan ini hanya brilian. Kenapa aku tidak memikirkan ini? Kebenaran bahwa lebih dari satu pasang bola mata selalu mengarah ke solusi yang baik. Terima kasih.
luis.espinal
2
Bisakah Anda meletakkan ini dalam versi java yang kompatibel dengan ekspresi lambda yang tidak mendukung
vkrams
3
Versi Java 1.7: wait.until (Predikat baru <WebDriver> () {berlaku boolean publik (driver WebDriver) {kembali (driver JavascriptExecutor)) .executeScript ("return document.readyState"). Equals ("complete");} });
luQ
1
Jika seseorang ingin menggunakan solusi oleh @IuQ, Predicate telah mengimporimport com.google.common.base.Predicate
Knu8
Saya mencoba ide ini di aplikasi uji VB. Bekerja sebagian besar waktu. Kadang-kadang saya mendapatkan kesalahan ini: System.InvalidOperationException: Kesalahan JavaScript (UnexpectedJavaScriptError) di OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError (Respons errorResponse) Klik aplikasi uji pada tautan menu level 2, kemudian memanggil WaitObj.Until (Fungsi (Langsung)) D, InternetExplorerDriver) .ExecuteScript ("return document.readyState") = "complete"). Saya pikir kesalahan disebabkan karena browser membongkar halaman saat ini dan tidak ada objek dokumen. Mungkin menunggu 1/2 detik sebelum melakukan "return document.readystate? Ideas?
CoolBreeze
12

Inilah upaya saya untuk solusi yang sepenuhnya generik, dengan Python:

Pertama, fungsi "tunggu" generik (gunakan WebDriverWait jika Anda suka, saya menganggapnya jelek):

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

Selanjutnya, solusinya bergantung pada fakta bahwa selenium mencatat nomor id (internal) untuk semua elemen pada halaman, termasuk <html>elemen level atas . Saat halaman disegarkan atau dimuat, ia mendapat elemen html baru dengan ID baru.

Jadi, anggap Anda ingin mengeklik tautan dengan teks "tautan saya" misalnya:

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)

Untuk bantuan Pythonic, reusable, generic yang lebih banyak, Anda dapat membuat manajer konteks:

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)

Dan kemudian Anda dapat menggunakannya di hampir semua interaksi selenium:

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

Saya rasa itu antipeluru! Bagaimana menurut anda?

Info lebih lanjut di posting blog tentang itu di sini

hwjp
sumber
Pendekatan yang sangat menarik. Satu tantangan adalah apakah ini bisa berfungsi pada pemuatan halaman awal, setelah browser pertama kali diluncurkan. Tidak ada jaminan bahwa keadaan awal browser memuat halaman. Juga, di Jawa, saya tidak melihat bahwa kita memiliki 'id' pada objek - saya berasumsi Anda tidak bermaksud bahwa selenium memasukkan atribut html id. Saya akan menambahkan lebih banyak ke respons ini setelah saya menjelajahi opsi ini lebih banyak. Terima kasih untuk kirimannya!
Lukus
@ hwjp Saya menggunakan solusi ini berkali-kali dengan hasil yang sangat baik, tetapi sepertinya itu tidak berhasil dalam satu kasus. Penjelasan lengkap tentang masalah stackoverflow.com/q/31985739/4249707
El Ruso
7

Saya punya masalah serupa. Saya perlu menunggu sampai dokumen saya siap tetapi juga sampai semua panggilan Ajax selesai. Kondisi kedua terbukti sulit dideteksi. Pada akhirnya saya memeriksa panggilan Ajax aktif dan berhasil.

Javascript:

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

Metode C # lengkap:

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);
}
Rubanov
sumber
Apakah ada sesuatu seperti document.readyState == 'complete' && jQuery.active == 0untuk Bereaksi?
Rain9333
7
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));
Ram Bharath
sumber
4

Untuk C # NUnit, Anda perlu mengonversi WebDriver ke JSExecuter dan kemudian menjalankan skrip untuk memeriksa apakah dokumen sudah menyatakan lengkap atau tidak. Periksa kode di bawah ini untuk referensi:

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

Ini akan menunggu sampai kondisinya puas atau habis.

S.Akruwala
sumber
3

Untuk pemuatan halaman awal, saya perhatikan bahwa "Memaksimalkan" jendela browser praktis menunggu sampai pemuatan halaman selesai (termasuk sumber)

Menggantikan:

AppDriver.Navigate().GoToUrl(url);

Dengan:

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

daripada menggunakan:

OpenURL(myDriver, myUrl);

Ini akan memuat halaman, tunggu sampai selesai, maksimalkan dan fokus padanya. Saya tidak tahu mengapa seperti ini tetapi berfungsi.

Jika Anda ingin menunggu pemuatan halaman setelah mengklik berikutnya atau pemicu navigasi halaman lain selain "Navigasi ()", jawaban Ben Dyer (di utas ini) akan melakukan pekerjaannya.

Roei Sabag
sumber
1

Lihatlah kerangka kerja permadani . Anda dapat mengunduh kode sumber di sana.

Idenya adalah untuk menandakan bahwa halaman siap dengan atribut html tubuh. Anda dapat menggunakan ide ini untuk mengabaikan kasus-kasus tuntutan yang rumit.

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

Dan kemudian membuat ekstensi webdriver Selenium (sesuai dengan kerangka permadani)

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

Gunakan ekstensi ElementIsDisplayed yang ditulis oleh Alister Scott .

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

Dan akhirnya buat tes:

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();
Tomas Kubes
sumber
1

Jawaban Ben Dryer tidak dikompilasi pada mesin saya ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait").

Versi Java 8 yang berfungsi:

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

Versi 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);
Hazel Troost
sumber
1

Saya mencoba kode ini dan berhasil untuk saya. Saya memanggil fungsi ini setiap kali saya pindah ke halaman lain

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; 
        }   
      }
 }
Algoritma
sumber
1

Di Nodejs Anda bisa mendapatkannya melalui janji ...

Jika Anda menulis kode ini, Anda dapat memastikan bahwa halaman tersebut dimuat penuh ketika Anda sampai ke ...

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

Jika Anda menulis kode ini, Anda akan menavigasi, dan selenium akan menunggu 3 detik ...

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

Dari dokumentasi Selenium:

this.get (url) → Thenable

Jadwalkan perintah untuk menavigasi ke URL yang diberikan.

Mengembalikan janji yang akan diselesaikan saat dokumen selesai dimuat .

Dokumentasi Selenium (Nodejs)

sidanmor
sumber
1

Menunggu dokumen. Acara yang sudah ada belum menyelesaikan seluruh masalah ini, karena kode ini masih dalam kondisi balapan: Terkadang kode ini dipecat sebelum acara klik diproses sehingga ini langsung kembali, karena browser belum memulai memuat halaman baru.

Setelah beberapa pencarian saya menemukan posting di Obay kambing pengujian , yang memiliki solusi untuk masalah ini. Kode c # untuk solusi itu adalah seperti ini:

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

}

`Saya memecat metode ini langsung setelah driver.navigate.gotourl, sehingga mendapat referensi halaman sesegera mungkin. Bersenang-senanglah dengan itu!

Maarten Kieft
sumber
1

biasanya ketika selenium membuka halaman baru dari klik atau mengirim atau mendapatkan metode, itu akan menunggu sampai halaman dibuka tetapi masalahnya adalah ketika halaman memiliki panggilan xhr (ajax) dia tidak akan pernah menunggu xhr untuk dimuat, jadi membuat metode baru untuk memonitor xhr dan menunggu mereka itu akan menjadi yang baik.

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 == 0jadi tidak ada panggilan xhrs aktif (yang hanya berfungsi dengan jQuery). untuk panggilan ajax javascript Anda harus membuat variabel dalam proyek Anda dan mensimulasikannya.

Elazzam
sumber
0

Anda dapat menulis beberapa logika untuk menangani ini. Saya telah menulis metode yang akan mengembalikan WebElementdan metode ini akan dipanggil tiga kali atau Anda dapat menambah waktu dan menambahkan cek nol untuk WebElementBerikut adalah contohnya

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;
        }
    }
Vaibhav Pandey
sumber
0

Saya mengeksekusi kode javascript untuk memeriksa apakah dokumen sudah siap. Menghemat saya banyak waktu men-debug tes selenium untuk situs yang memiliki rendering sisi klien.

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");
}
bertanasco
sumber
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;
    }
akhilesh gulati
sumber
0

Seperti Rubanov menulis untuk C #, saya menulis untuk Java, dan itu adalah:

    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.");
    }
}
Krzysztof Walczewski
sumber
0

Di Jawa akan seperti di bawah ini: -

  private static boolean isloadComplete(WebDriver driver)
    {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    }
Shubham Jain
sumber
1
Akan lebih baik untuk menggabungkan perintah JS menjadi satu sehingga Anda tidak perlu menekan halaman dua kali, misalnyareturn document.readyState == 'loaded' || return document.readyState == 'complete'
JeffC
0

Kode berikut mungkin bekerja:

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

Jika Anda memiliki halaman yang lambat atau koneksi jaringan, kemungkinan semua hal di atas tidak akan berfungsi. Saya telah mencoba semuanya dan satu-satunya hal yang berhasil bagi saya adalah menunggu elemen terakhir yang terlihat pada halaman itu. Ambil contoh halaman web Bing. Mereka telah menempatkan ikon KAMERA (tombol pencarian berdasarkan gambar) di sebelah tombol pencarian utama yang hanya dapat dilihat setelah halaman lengkap dimuat. Jika semua orang melakukan itu, maka yang harus kita lakukan adalah menggunakan menunggu secara eksplisit seperti pada contoh di atas.

pengguna3988148
sumber
-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
Manjyot
sumber
-1

Ini sesuatu yang mirip, di Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }
amril
sumber
Kode Anda tidak berfungsi untuk saya. Bagaimana saya beralih, lakukan iframe dan tunggu onload = "javascript: pageload (); functionalPageLoad ();" untuk memuat ulang halaman di Ruby? Saya menemukan diri saya membuka iframe di dalam halaman, saya memiliki akses ke sana, kemudian halaman memuat ulang, dan saya tidak dapat mengakses frame lagi. Saya telah membaca banyak jawaban mengenai menunggu, tidur, waktu, beralih ke bingkai kemudian ke orang tua, namun saya tidak dapat mencapai tujuan saya.
Amanda Cavallaro
1
Kedengarannya pertanyaan Anda terutama tentang cara beralih ke iFrame, bukan tentang menunggu memuat dokumen. Mungkin lebih baik memulai pertanyaan baru jika Anda tidak dapat menemukan solusi dalam pertanyaan tentang bekerja dengan iFrames.
Ampelas
-1

Anda dapat membuat utas tidur sampai halaman dimuat ulang. Ini bukan solusi terbaik, karena Anda perlu memperkirakan berapa lama waktu yang diperlukan untuk memuat.

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();
Eric Fernandes
sumber
Saya menemukan Thread.sleep (5000) sering merupakan satu-satunya metode yang mendapat tes bekerja, meskipun semua rekomendasi menentang menggunakannya. Tidak ada kombinasi dari menunggu elemen bekerja untuk saya, terutama karena banyak elemen tidak dapat diidentifikasi sampai mereka benar-benar ditemukan.
Steve Staple
-1

Saya memeriksa pemuatan halaman, bekerja di 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);
        }
    }
Jundat95
sumber
-1

Untuk orang-orang yang perlu menunggu elemen tertentu muncul. (digunakan c #)

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

Kemudian jika Anda ingin menunggu misalnya jika kelas = "pesan kesalahan" ada di DOM yang Anda lakukan:

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

Untuk id, maka akan menjadi

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

Mo D Genesis
sumber
-3

Apakah Anda menggunakan Angular? Jika ya, ada kemungkinan webdriver tidak mengenali bahwa panggilan async telah selesai.

Saya sarankan melihat Paul Hammants ngWebDriver . Metode waitForAngularRequestsToFinish () dapat berguna.

Marlies
sumber
Dia sangat tidak menggunakan Angular. Jawaban ini dibatalkan karena tampaknya Anda tidak membaca pertanyaan awal dengan cermat.
zelusp
Tapi jangan biarkan orang memilih Anda dari bentuknya. Orang-orang di sini bermaksud baik. Dan kritik sebenarnya adalah bentuk cinta (karena jika seseorang mengambil waktu untuk memperbaiki siapa pun itu karena mereka peduli). Checkout Cara mengajukan pertanyaan dengan cara yang cerdas - ide-ide itu juga berlaku untuk menjawab pertanyaan dengan cara yang cerdas.
zelusp