Saya suka ide Anda untuk melakukan polling terhadap HTML sampai stabil. Saya dapat menambahkannya ke solusi saya sendiri. Pendekatan berikut ada di C # dan membutuhkan jQuery.
Saya adalah pengembang untuk proyek uji SuccessFactors (SaaS) di mana kami tidak memiliki pengaruh sama sekali terhadap pengembang atau karakteristik DOM di balik laman web. Produk SaaS berpotensi mengubah desain DOM dasarnya 4 kali setahun, jadi perburuan secara permanen mencari cara yang kuat dan berkinerja untuk menguji dengan Selenium (termasuk BUKAN pengujian dengan Selenium jika memungkinkan!)
Inilah yang saya gunakan untuk "siap halaman". Ini bekerja di semua tes saya sendiri saat ini. Pendekatan yang sama juga berhasil untuk aplikasi web Java internal yang besar beberapa tahun yang lalu, dan telah kuat selama lebih dari setahun pada saat saya meninggalkan proyek.
Driver
adalah instance WebDriver yang berkomunikasi dengan browser
DefaultPageLoadTimeout
adalah nilai batas waktu dalam ticks (100ns per tick)
public IWebDriver Driver { get; private set; }
// ...
const int GlobalPageLoadTimeOutSecs = 10;
static readonly TimeSpan DefaultPageLoadTimeout =
new TimeSpan((long) (10_000_000 * GlobalPageLoadTimeOutSecs));
Driver = new FirefoxDriver();
Berikut ini, perhatikan urutan metode menunggu PageReady
(siap dokumen Selenium, Ajax, animasi), yang masuk akal jika Anda memikirkannya:
- memuat halaman yang berisi kode
- gunakan kode untuk memuat data dari suatu tempat melalui Ajax
- menyajikan data, mungkin dengan animasi
Sesuatu seperti pendekatan perbandingan DOM Anda dapat digunakan antara 1 dan 2 untuk menambahkan lapisan ketahanan lainnya.
public void PageReady()
{
DocumentReady();
AjaxReady();
AnimationsReady();
}
private void DocumentReady()
{
WaitForJavascript(script: "return document.readyState", result: "complete");
}
private void WaitForJavascript(string script, string result)
{
new WebDriverWait(Driver, DefaultPageLoadTimeout).Until(
d => ((IJavaScriptExecutor) d).ExecuteScript(script).Equals(result));
}
private void AjaxReady()
{
WaitForJavascript(script: "return jQuery.active.toString()", result: "0");
}
private void AnimationsReady()
{
WaitForJavascript(script: "return $(\"animated\").length.toString()", result: "0");
}