Tôi thích ý tưởng của bạn về việc thăm dò HTML cho đến khi nó ổn định. Tôi có thể thêm điều đó vào giải pháp của riêng tôi. Cách tiếp cận sau đây là trong C # và yêu cầu jQuery.
Tôi là nhà phát triển cho dự án thử nghiệm SuccessFactors (SaaS), nơi chúng tôi không có ảnh hưởng nào đối với các nhà phát triển hoặc các đặc điểm của DOM đằng sau trang web. Sản phẩm SaaS có khả năng thay đổi thiết kế DOM cơ bản của nó 4 lần một năm, vì vậy, cuộc săn lùng sẽ diễn ra vĩnh viễn để tìm ra những cách hiệu quả và hiệu quả để kiểm tra với Selenium (bao gồm KHÔNG thử nghiệm với Selenium khi có thể!)
Đây là những gì tôi sử dụng cho "trang đã sẵn sàng". Nó hoạt động trong tất cả các thử nghiệm của riêng tôi hiện tại. Cách tiếp cận tương tự cũng đã hoạt động đối với một ứng dụng web Java nội bộ lớn cách đây vài năm và đã hoạt động mạnh mẽ trong hơn một năm tại thời điểm tôi rời dự án.
Driver
là phiên bản WebDriver giao tiếp với trình duyệt
DefaultPageLoadTimeout
là một giá trị thời gian chờ tính bằng tick (100ns mỗi 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();
Trong phần tiếp theo, hãy lưu ý thứ tự của các lần đợi trong phương thức PageReady
(tài liệu Selenium đã sẵn sàng, Ajax, hoạt ảnh), điều này có ý nghĩa nếu bạn nghĩ về nó:
- tải trang chứa mã
- sử dụng mã để tải dữ liệu từ một nơi nào đó thông qua Ajax
- trình bày dữ liệu, có thể bằng hình ảnh động
Một cái gì đó giống như phương pháp so sánh DOM của bạn có thể được sử dụng từ 1 đến 2 để thêm một lớp mạnh mẽ khác.
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");
}