Tunggu pemuatan halaman di Selenium

240

Bagaimana Anda membuat Selenium 2.0 menunggu halaman dimuat?

karthick kumar
sumber
7
Bagi saya hanya jawaban Paul yang kelihatan benar, sebagian besar jawaban yang sangat tinggi berbicara tentang menunggu unsur tertentu.
xyz

Jawaban:

138

Anda juga dapat memeriksa pageload menggunakan kode berikut

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
sumber
22
Anda akan berpikir sesuatu seperti ini akan dibangun. Menunggu memuat halaman adalah hal yang cukup umum di web.
PRMan
19
apakah ini benar-benar berfungsi sepanjang waktu? Mungkin saya kehilangan sesuatu dari kode Anda tetapi Anda menunggu dom dalam keadaan siap. Tetapi pertimbangkan bahwa jika kode Anda dieksekusi terlalu cepat, halaman sebelumnya mungkin belum diturunkan dan itu akan kembali benar meskipun Anda masih di halaman lama. Yang perlu Anda lakukan adalah menunggu halaman saat ini diturunkan dan panggil kode Anda di atas. Cara untuk mendeteksi pembongkaran halaman adalah dengan mendapatkan elemen web pada halaman saat ini dan menunggu sampai basi. obeythetestinggoat.com/...
George
6
FYI - Bahkan masih di atas tidak menjamin bahwa halaman selesai - hanya bahwa dom sudah siap. Dojo / jquery apa pun mungkin masih secara dinamis membangun elemen pada halaman sehingga Anda mungkin perlu menunggu dulu elemen dinamis sebelum berinteraksi dengan mereka.
George
3
Sadarilah bahwa metode ini hanya memeriksa DOM. Jika Anda menggunakan Ajax atau AngularJS, ini tidak akan berfungsi karena akan ada beberapa panggilan tidak sinkron yang tidak dapat dideteksi oleh dokumen.readyState.
Homewrecker
3
Ini adalah kode C #. Ini tidak berfungsi dengan Java, dan pertanyaan yang diajukan tentang Java .
Kingamere
89

Gunakan kelas WebDriverWait

Lihat juga di sini

Anda dapat menampilkan beberapa elemen. sesuatu seperti di 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
sumber
Ini bekerja dengan baik. Ini adalah cara modern yang sangat bagus untuk menyelesaikan masalah.
CrazyDart
3
@ EmmanuelAngelo.R TimeSpan adalah struktur data .Net.
rjzii
12
bagaimana jika saya tidak tahu elemen mana yang akan ada di halaman?
JustGoscha
3
Ini akan berfungsi untuk menunggu pemuatan elemen tertentu dan bukan untuk seluruh halaman.
xyz
1
Ini tidak menjamin sama sekali bahwa suatu elemen akan dimuat penuh tidak menjawab pertanyaan. Bagaimana orang bisa menyukai ini?
Boris D. Teoharov
36

Jika Anda mengatur tunggu driver, kemudian memanggil findElementmetode pada elemen yang Anda harapkan berada di halaman yang dimuat, WebDriver akan polling untuk elemen itu sampai menemukan elemen atau mencapai nilai batas waktu.

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

sumber: implisit-menunggu

Sam
sumber
3
Itu tidak akan membantu dalam menunggu pemuatan halaman.
xyz
Ini berarti bahwa ia akan mencoba sesuatu selama 10 detik, sebelum menimbulkan pengecualian. jadi tidak bisa memastikan bahwa akan membutuhkan waktu 10 detik penundaan.
skysign
1
@xyz - mengapa itu tidak membantu?
MasterJoe2
@ testerjoe2 menunggu hingga elemen tertentu ditemukan, pertanyaannya adalah tentang bagaimana menunggu pemuatan halaman.
xyz
35

Secara umum, dengan Selenium 2.0 driver web hanya boleh mengembalikan kontrol ke kode panggilan setelah ditentukan bahwa halaman telah dimuat. Jika tidak, Anda dapat menelepon waitforelemement, yang memanggil siklus putaran findelementsampai ditemukan atau waktu habis (batas waktu dapat diatur).

Paul Hadfield
sumber
2
Menambah jawaban Paul. Silakan periksa ini juga stackoverflow.com/questions/5858743/… .
9ikhan
27
Sayangnya, Selenium 2 tidak menunggu dalam semua kasus untuk memuat halaman. Misalnya WebElement: klik () tidak menunggu dan ini secara eksplisit dikatakan di Javadoc milik. Namun, mereka tidak memberi tahu bagaimana saya dapat memeriksa halaman baru untuk dimuat. 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
Dari doc ..dan metodenya akan diblok sampai muatannya selesai ...
xyz
2
@ Karna: Ya, secara teori seharusnya selalu dan dalam praktiknya hal itu sering terjadi. Menggunakan Selenium pada waktu itu menggarisbawahi bahwa ada saat-saat ketika ia berpikir bahwa halaman telah selesai dimuat tetapi tidak. Saya belum pernah menggunakan selenium baru-baru ini jadi ini mungkin atau mungkin masih belum terjadi.
Paul Hadfield
3
Saya setuju: terutama driver internet explorer buggy dan segera mengembalikan kontrol dalam beberapa kasus meskipun halaman masih memuat. Ini kasus saya, saya menambahkan menunggu menggunakan JavascriptExecutor, menunggu dokumen. SudahState menjadi "lengkap". Karena perjalanan pulang-pergi dari selenium ke peramban, kurasa kondisi balap dikurangi, dan ini "selalu" bekerja untuk saya. Setelah "klik ()" ketika saya mengharapkan halaman dimuat, saya secara eksplisit menunggu (menggunakan WebDriverWait) untuk readystate. ]
dmansfield
22

Implementasi Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until {
    @driver.execute_script("return document.readyState;") == "complete" 
}
allenhwkim
sumber
17
Setara dengan Python: WebDriverWait (driver, 10) .until (lambda d: d.execute_script ('return document.readyState') == 'lengkap')
blaze
2
Python menggunakan kode di atas tetapi jangan lupa ke baris ini .. | dari selenium.webdriver.support.ui import WebDriverWait
t3dodson
Saya punya masalah mengklik elemen ketika halaman tidak dimuat sepenuhnya. Dalam Python saya mencoba time.sleep (30). Itu berhasil. Akan selalu menunggu hingga 30 detik. Saya kemudian mencoba kode berikut dan lebih efisien sekarang, lebih cepat. WebDriverWait (driver, 10) .until (lambda d: driver.find_element_by_xpath ("// div [. = 'Administration']"). Klik ())
Riaz Ladhani
20

Anda dapat menghapus System.outgaris. Itu ditambahkan untuk keperluan debug.

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
sumber
Terima kasih untuk tips ini. Saya menambahkannya di SeleniumHelper saya; lih. javabox
boly38
17

Semua solusi ini OK untuk kasus-kasus tertentu, tetapi mereka menderita setidaknya satu dari beberapa masalah yang mungkin terjadi:

  1. Mereka tidak cukup umum - mereka ingin Anda tahu, sebelumnya, bahwa beberapa kondisi tertentu akan benar dari halaman yang Anda tuju (misalnya beberapa elemen akan ditampilkan)

  2. Mereka terbuka untuk kondisi balapan di mana Anda menggunakan elemen yang sebenarnya ada di halaman lama dan juga halaman baru.

Inilah upaya saya pada solusi umum yang menghindari masalah ini (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 lebih banyak Pythonic, reusable, helper generik, 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
Saya membaca halaman web Anda sebelum mencari lagi secara lebih spesifik untuk kode java yang mengimplementasikan solusi Anda. Sejauh ini tidak ada ...
andrew lorien
11

Anda juga dapat menggunakan kelas: ExpectedConditionsuntuk secara eksplisit menunggu elemen muncul di halaman web sebelum Anda dapat mengambil tindakan tindakan selanjutnya

Anda bisa menggunakan ExpectedConditionskelas untuk menentukan apakah suatu elemen terlihat:

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

Lihat ExpectedConditions class Javadocdaftar semua kondisi yang dapat Anda periksa.

TedEd
sumber
11

Jawaban Imran diulang untuk 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");
        }
    });
Sirip
sumber
10

Ini tampaknya menjadi batasan serius WebDriver. Jelas menunggu suatu elemen tidak akan menyiratkan halaman yang sedang dimuat, khususnya DOM dapat sepenuhnya membangun (keadaan sudah) dimana JS masih mengeksekusi dan CSS dan gambar masih memuat.

Saya percaya solusi paling sederhana adalah dengan menetapkan variabel JS pada acara onload setelah semuanya diinisialisasi dan periksa dan tunggu variabel JS ini di Selenium.

sibidiba
sumber
Sederhana saja jika situs itu milik Anda untuk diubah!
reinierpost
Yap, cukup gunakan JavascriptExecutor untuk menjalankan jQuery.js dan kemudian Anda memiliki akses ke jQuery memuat acara. Ini adalah kasus yang jarang terjadi saat ini diperlukan. Webdriver standar memiliki kekuatan yang cukup untuk melakukan 98% dari menunggu yang tepat.
djangofan
@ Djangofan akan luar biasa untuk melihat contoh itu ... Saya seorang pria front-end jadi tidak yakin di mana atau bagaimana JavascriptExecutor digunakan.
BradGreens
@BradGreens - Ok, lihat proyek saya di sini: github.com/djangofan/jquery-growl-selenium-example . Jika Anda memiliki bandwidth untuk menyelesaikan contoh itu, saya tidak bisa cukup mendapatkan jGrowl untuk bekerja di proyek pengujian itu, meskipun jQuery berfungsi dengan baik.
Djangofan
1
@BradGreens Selain komentar djangofan, lihat jawaban saya di sini: stackoverflow.com/a/24638792/730326
jmathew
9

Jika Anda ingin menunggu elemen tertentu dimuat, Anda dapat menggunakan isDisplayed()metode ini pada 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;
    }
}

(Contoh dari Panduan Memulai 5 Menit )

Tristan
sumber
4
Setahun kemudian (versi Selenium saat ini 2.23.1), tidak ada RenderedWebElementdi API. Namun, isDisplayed()metode sekarang tersedia langsung di WebElement.
Petr Janeček
1
Polling itu mengerikan kalau bisa dihindari.
reinierpost
8

Menunggu secara eksplisit atau menunggu bersyarat dalam menunggu ini sampai diberikan kondisi ini.

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

Ini akan menunggu setiap elemen web selama 60 detik.

Gunakan menunggu secara implisit untuk menunggu setiap elemen pada halaman sampai waktu yang diberikan.

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

Ini akan menunggu setiap elemen web selama 60 detik.

Anuj Teotia
sumber
5

Gunakan tunggu secara implisit untuk menunggu setiap elemen pada halaman sampai waktu yang ditentukan.

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

tunggu ini untuk setiap elemen pada halaman selama 30 detik.

Penantian lainnya adalah Penantian secara eksplisit atau penantian bersyarat dalam penantian ini sampai kondisi yang ditentukan.

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

Dalam id, berikan id elemen statis yang ditampilkan secara berbeda pada halaman, segera setelah halaman dimuat.

Kuldeep Yadav
sumber
4

Saya terkejut bahwa predikat bukan pilihan pertama karena Anda biasanya tahu elemen apa yang akan Anda interaksi selanjutnya pada halaman yang Anda tunggu muat. Pendekatan saya selalu membangun predikat / fungsi seperti waitForElementByID(String id)dan waitForElemetVisibleByClass(String className), dll. Dan kemudian menggunakan dan menggunakan kembali ini di mana pun saya membutuhkannya, baik itu untuk memuat halaman atau perubahan konten halaman yang saya tunggu.

Sebagai contoh,

Di kelas ujian saya:

driverWait.until(textIsPresent("expectedText");

Di induk kelas uji saya:

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

Meskipun ini kelihatannya banyak, perlu memeriksa berulang kali untuk Anda dan interval seberapa sering untuk memeriksa dapat diatur bersama dengan waktu tunggu terakhir sebelum waktu habis. Anda juga akan menggunakan kembali metode tersebut.

Dalam contoh ini, kelas induk mendefinisikan dan memulai WebDriver driverdan WebDriverWait driverWait.

Saya harap ini membantu.

Jack Mason
sumber
Ini membantu saya! Terima kasih atas sampel yang luar biasa ini. Saya menambahkannya di SeleniumHelper saya; lih. javabox
boly38
4

Cara terbaik untuk menunggu pemuatan halaman saat menggunakan binding Java untuk WebDriver adalah dengan menggunakan pola desain Obyek Halaman dengan PageFactory. Ini memungkinkan Anda untuk memanfaatkanAjaxElementLocatorFactory yang membuatnya hanya bertindak sebagai penantian global untuk semua elemen Anda. Ini memiliki batasan pada elemen-elemen seperti drop-box atau transisi javascript kompleks tetapi secara drastis akan mengurangi jumlah kode yang dibutuhkan dan mempercepat waktu pengujian. Contoh yang baik dapat ditemukan di blogpost ini. Pemahaman dasar Core Java diasumsikan.

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

sonhu
sumber
4

Solusi NodeJS:

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
4

Ini adalah versi Java 8 dari jawaban yang paling banyak dipilih saat ini :

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

Di mana myDriveradalah WebDriverobjek (dinyatakan sebelumnya).

Catatan : Perlu diketahui bahwa metode ini ( document.readyState) hanya memeriksa DOM.

BelovedFool
sumber
4

Panggil fungsi di bawah ini dalam skrip Anda, ini akan menunggu sampai halaman tidak dimuat menggunakan 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
sumber
Saya mengubah boolean untuk batal, tetapi tidak berfungsi di 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;
        }
    });
}

Anda dapat mengubah dari dokumen ke elemen, dalam kasus di mana hanya bagian dari dokumen yang diubah.

Teknik ini terinspirasi oleh jawaban dari sincebasic.

Marc
sumber
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);
                 }
            };
      }
 }

Dan untuk Anda menggunakannya :

_waiter = new SeleniumWaiter(_driver);

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

Anda dapat menggunakan metode yang ada di bawah ini untuk mengatur waktu untuk pageeLoadTimeout dalam contoh di bawah ini jika halaman mengambil lebih dari 20 detik untuk memuat, maka itu akan membuang pengecualian dari memuat ulang halaman

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

Anda dapat secara eksplisit menunggu sebuah elemen muncul di halaman web sebelum Anda dapat mengambil tindakan apa pun (seperti 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"));
}});

Ini yang saya gunakan untuk skenario yang sama dan berfungsi dengan baik.

anirus
sumber
saya pikir driver.get menunggu fungsi onload selesai sebelum kembali kontrol ke kode, kecuali halaman memiliki banyak ajax
goh
2

Cara sederhana saya:

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

Cara terbaik yang saya lihat adalah memanfaatkan stalenessOfExpectedCondition, untuk menunggu halaman lama menjadi basi.

Contoh:

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

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

Ini akan menunggu selama sepuluh detik untuk tag HTML lama menjadi basi, dan kemudian melemparkan pengecualian jika itu tidak terjadi.

forresthopkinsa
sumber
1
WebElement menjadi basi tidak berarti halaman baru selesai dimuat.
Corey Goldberg
Tentu, tetapi itu berarti halaman lama selesai dibongkar. Dalam pengalaman saya, sama pentingnya untuk mengetahui kapan halaman lama telah dibongkar, atau jika telah berhenti karena suatu alasan.
forresthopkinsa
Tentu saja, saya biasanya menggunakan stalenessOf bersamaan dengan tes lain untuk mendapatkan proses pembongkaran / pemuatan penuh.
forresthopkinsa
2

Saya menggunakan node + selenium-webdriver (yang versi 3.5.0 sekarang). apa yang saya lakukan untuk ini adalah:

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

Anda bisa menggunakan wait. pada dasarnya ada 2 jenis menunggu dalam selenium

  • Tunggu implisit
  • Tunggu secara eksplisit

- Tunggu implisit

Ini sangat sederhana, silakan lihat sintaksis di bawah ini:

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

- Tunggu eksplisit

Menunggu secara eksplisit atau menunggu bersyarat dalam menunggu ini sampai kondisi yang diberikan terjadi.

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

Anda dapat menggunakan properti lain seperti visblityOf(),visblityOfElement()

iamsankalp89
sumber
2

Dalam kasus saya, saya menggunakan yang berikut ini untuk mengetahui status memuat halaman. Dalam aplikasi kami memuat gif (s) hadir dan, saya mendengarkan mereka sebagai berikut untuk menghilangkan waktu tunggu yang tidak diinginkan dalam skrip.

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

Di mana xpath menemukan gif di HTML DOM. Setelah ini, Anda juga dapat menerapkan metode tindakan Anda. Klik.

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

Man semua jawaban ini membutuhkan kode terlalu banyak. Ini harus menjadi hal yang sederhana karena cukup umum.

Mengapa tidak menyuntikkan beberapa javascript sederhana dengan webdriver dan periksa. Ini adalah metode yang saya gunakan di kelas webscraper saya. Javascript cukup mendasar bahkan jika Anda tidak tahu 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
sumber
1

Cara mendapatkan Selenium untuk menunggu pemuatan halaman setelah klik memberikan pendekatan menarik berikut:

  1. Simpan referensi ke WebElementdari dari halaman lama.
  2. Klik tautannya.
  3. Terus menjalankan operasi di atas WebElementsampai StaleElementReferenceExceptionterlempar.

Kode sampel:

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
sumber
Ide bagus! Saya tidak pernah berpikir untuk mengatasi situasi ini dengan memeriksa kebalikan dari pemuatan halaman yang sukses, pembongkaran halaman yang sukses (karena tidak ada istilah yang lebih baik). Meskipun apakah ini pilihan terbaik berdasarkan apakah StaleElementReferenceException membutuhkan waktu lebih sedikit, dll daripada menunggu pemuatan yang berhasil. Meskipun demikian, cara lain yang baik untuk melakukannya.
Joseph Orlando
4
Ini tidak akan memberi tahu Anda apakah halaman saat ini dimuat, itu akan memberi tahu Anda apakah halaman terakhir (khususnya satu elemen) diturunkan . Anda masih harus menunggu halaman yang sedang dimuat. BTW, Anda dapat mengganti kode di atas dengan new WebDriverWait(driver, 10).until(ExpectedConditions.stalenessOf(element)).
JeffC