Bagaimana anda membuat Selenium 2.0 menunggu untuk halaman untuk memuat?
Anda juga dapat memeriksa pageloaded 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"));
Menggunakan kelas WebDriverWait
Lihat juga di sini
Anda dapat mengharapkan untuk menunjukkan 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"));
Jika anda mengatur implisit menunggu pengemudi, kemudian memanggil findElement
metode pada elemen yang anda harapkan akan di-load halaman, WebDriver akan jajak pendapat untuk elemen itu sampai ia menemukan unsur atau mencapai waktu di luar nilai.
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
sumber: implisit-menunggu
Secara umum, dengan Selenium 2.0 web driver hanya harus kembali kontrol untuk memanggil kode setelah itu telah ditentukan bahwa halaman telah dimuat. Jika tidak, anda dapat memanggil waitforelemement
, yang siklus putaran memanggil findelement
sampai ditemukan atau waktu keluar (time out dapat diatur).
Anda dapat menghapus Sistem.di luar
garis. Hal ini ditambahkan untuk tujuan 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");
}
});
}
Semua solusi ini adalah OK untuk kasus-kasus tertentu, tetapi mereka menderita setidaknya satu dari beberapa kemungkinan masalah:
Mereka tidak generik cukup-mereka ingin kau tahu, dari waktu ke depan, bahwa beberapa kondisi tertentu akan menjadi kenyataan halaman anda akan (misalnya beberapa elemen akan ditampilkan)
Mereka terbuka untuk kondisi balapan di mana anda menggunakan elemen yang benar-benar hadir di halaman lama serta baru halaman.
Berikut ini's my upaya generik solusi yang menghindari masalah ini (Python):
Pertama, generik "tunggu" fungsi (menggunakan WebDriverWait jika anda suka, saya menemukan mereka 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, larutan bergantung pada kenyataan bahwa selenium catatan (internal) id-nomor untuk semua elemen pada sebuah halaman, termasuk top-level <html>
elemen. Ketika refresh halaman atau beban, hal itu akan baru elemen html dengan ID baru.
Jadi, dengan asumsi anda ingin klik pada link dengan teks "saya link" 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 Pythonic, dapat digunakan kembali, generic helper, anda dapat membuat sebuah konteks manager:
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 pada hampir semua interaksi selenium:
with wait_for_page_load(browser):
browser.find_element_by_link_text('my link').click()
Saya rasa itu's antipeluru! Apa yang anda pikirkan?
Info lebih lanjut di posting blog tentang hal itu here
Anda juga dapat menggunakan kelas: ExpectedConditions
untuk secara eksplisit menunggu untuk sebuah elemen yang muncul pada halaman web sebelum anda dapat mengambil tindakan apapun tindakan lebih lanjut
Anda dapat menggunakan ExpectedConditions
kelas untuk menentukan apakah suatu elemen yang terlihat:
WebElement element = (new WebDriverWait(getDriver(), 10)).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("input#houseName")));
Melihat ExpectedConditions kelas Javadoc
untuk daftar semua kondisi yang anda dapat memeriksa.
Hal ini tampaknya menjadi pembatasan yang serius WebDriver. Jelas menunggu untuk sebuah elemen tidak akan berarti halaman yang sedang dimuat, khususnya DOM dapat sepenuhnya membangun (onready negara) dimana JS masih melaksanakan dan CSS dan images yang masih loading.
Saya percaya solusi yang paling sederhana adalah untuk menetapkan JS variabel pada onload event setelah semuanya diinisialisasi dan memeriksa dan menunggu untuk ini JS variabel Selenium.
Imran's jawaban rehashed untuk Jawa 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");
}
});
Jika anda ingin menunggu untuk elemen tertentu untuk memuat, anda dapat menggunakan isDisplayed()
pada metode 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 Menit 5 Panduan Memulai)
Secara eksplisit menunggu atau bersyarat tunggu ini di tunggu sampai diberikan kondisi ini.
WebDriverWait wait = new WebDriverWait(wb, 60);
wait.until(ExpectedConditions.elementToBeClickable(By.name("value")));
Ini akan menunggu untuk setiap elemen web selama 60 detik.
Gunakan secara implisit tunggu tunggu dari setiap elemen pada halaman sampai waktu yang diberikan.
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
Ini akan menunggu untuk setiap elemen web selama 60 detik.
Gunakan secara implisit tunggu tunggu dari setiap elemen pada halaman sampai waktu tertentu.
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
ini menunggu untuk setiap elemen pada halaman selama 30 detik.
Yang lain menunggu secara Eksplisit menunggu atau bersyarat menunggu dalam menunggu sampai kondisi tertentu.
WebDriverWait wait = new WebDriverWait(driver, 40);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
Di id memberikan statis id elemen yang malu-malu menampilkan pada halaman, sesegera halaman ini memuat.
I'm terkejut bahwa predikat tidak't pilihan pertama karena biasanya anda tahu apa yang elemen(s) anda selanjutnya akan berinteraksi dengan pada halaman anda're menunggu untuk memuat. Pendekatan saya selalu untuk membangun predikat/fungsi seperti waitForElementByID(String id)
dan waitForElemetVisibleByClass(String className)
, dll. dan kemudian menggunakan dan menggunakan kembali ini di mana pun aku membutuhkan mereka, baik untuk halaman atau konten halaman perubahan I'm menunggu.
Misalnya,
Dalam tes saya kelas:
driverWait.until(textIsPresent("expectedText");
Dalam tes saya, kelas induk:
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 hal ini tampaknya seperti banyak, dibutuhkan perawatan memeriksa berulang kali untuk anda dan interval untuk seberapa sering untuk memeriksa dapat diatur bersama dengan ultimate menunggu waktu sebelum waktu keluar. Juga, anda akan menggunakan kembali metode tersebut.
Dalam contoh ini, orang tua kelas didefinisikan dan memulai WebDriver driver
dan WebDriverWait driverWait
.
Saya harap ini membantu.
NodeJS Solusi:
Di Indonesia anda bisa mendapatkannya melalui janji-janji...
Jika anda menuliskan kode ini, anda dapat yakin bahwa halaman tersebut sepenuhnya dimuat ketika anda mendapatkan ke maka...
driver.get('www.sidanmor.com').then(()=> {
// here the page is fully loaded!!!
// do your stuff...
}).catch(console.log.bind(console));
Jika anda menuliskan 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 Selenium dokumentasi:
ini.get( url ) → Thenable
Jadwal perintah untuk menavigasi ke URL yang diberikan.
Kembali janji yang akan diselesaikan ketika dokumen selesai loading.
Memanggil Fungsi di bawah ini pada script anda , ini akan tunggu 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");
}
/**
* 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 dengan suatu elemen, dalam kasus di mana hanya bagian dari dokumen yang sedang berubah.
Teknik ini terinspirasi oleh jawaban dari sincebasic.
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 gunakan:
_waiter = new SeleniumWaiter(_driver);
try {
_waiter.waitForMe(By.xpath("//..."), 10);
}
catch (Exception e) {
// Error
}
Cara terbaik untuk menunggu untuk halaman untuk memuat ketika menggunakan Java binding untuk WebDriver adalah dengan menggunakan Halaman Objek pola desain dengan PageFactory. Hal ini memungkinkan anda untuk memanfaatkan AjaxElementLocatorFactory
yang dimasukkan itu hanya bertindak sebagai global yang menunggu untuk semua elemen. Ini memiliki keterbatasan pada unsur-unsur seperti drop box atau kompleks transisi javascript tapi ini akan secara drastis mengurangi jumlah kode yang dibutuhkan dan kecepatan sampai kali tes. Sebuah contoh yang baik dapat ditemukan di blogpost ini. Pengertian dasar dari Java Inti diasumsikan.
http://startingwithseleniumwebdriver.blogspot.ro/2015/02/wait-in-page-factory.html
Anda dapat menggunakan kode di bawah ini ada cara untuk mengatur waktu untuk pageeLoadTimeout di bawah ini contoh jika halaman lebih dari 20 detik untuk memuat , maka ia akan melempar pengecualian reload halaman
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS)