Podoba mi się twój pomysł przeszukiwania kodu HTML, aż będzie stabilny. Mogę dodać to do własnego rozwiązania. Poniższe podejście jest w C # i wymaga jQuery.
Jestem programistą projektu testowego SuccessFactors (SaaS), w którym nie mamy żadnego wpływu na programistów ani na cechy DOM za stroną internetową. Produkt SaaS może potencjalnie zmienić swój podstawowy projekt DOM 4 razy w roku, więc trwają poszukiwania solidnych, wydajnych sposobów testowania z Selenium (w tym NIE testowania z Selenium, jeśli to możliwe!)
Oto, czego używam do określenia „gotowa strona”. Obecnie działa we wszystkich moich własnych testach. To samo podejście działało również w przypadku dużej wewnętrznej aplikacji internetowej Java kilka lat temu i było solidne przez ponad rok, gdy opuściłem projekt.
Driver
to instancja WebDriver, która komunikuje się z przeglądarką
DefaultPageLoadTimeout
jest wartością limitu czasu w taktach (100ns na takt)
public IWebDriver Driver { get; private set; }
// ...
const int GlobalPageLoadTimeOutSecs = 10;
static readonly TimeSpan DefaultPageLoadTimeout =
new TimeSpan((long) (10_000_000 * GlobalPageLoadTimeOutSecs));
Driver = new FirefoxDriver();
W dalszej części zwróć uwagę na kolejność czekania w metodzie PageReady
(dokument Selenium gotowy, Ajax, animacje), co ma sens, jeśli się nad tym zastanowić:
- załaduj stronę zawierającą kod
- użyj kodu, aby załadować dane z dowolnego miejsca za pośrednictwem Ajax
- przedstaw dane, ewentualnie z animacjami
Coś takiego, jak podejście do porównywania DOM, może być użyte między 1 a 2, aby dodać kolejną warstwę niezawodności.
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");
}