J'aime votre idée d'interroger le HTML jusqu'à ce qu'il soit stable. Je peux ajouter cela à ma propre solution. L'approche suivante est en C # et nécessite jQuery.
Je suis le développeur d'un projet de test SuccessFactors (SaaS) où nous n'avons aucune influence sur les développeurs ou les caractéristiques du DOM derrière la page Web. Le produit SaaS peut potentiellement changer sa conception DOM sous-jacente 4 fois par an, de sorte que la recherche est en permanence de moyens robustes et performants de tester avec Selenium (y compris NE PAS tester avec Selenium lorsque cela est possible!)
Voici ce que j'utilise pour «page prête». Cela fonctionne dans tous mes propres tests actuellement. La même approche a également fonctionné pour une grande application Web Java interne il y a quelques années, et avait été robuste pendant plus d'un an au moment où j'ai quitté le projet.
Driver
est l'instance WebDriver qui communique avec le navigateur
DefaultPageLoadTimeout
est une valeur de timeout en ticks (100ns par 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();
Dans ce qui suit, notez l'ordre des attentes dans la méthode PageReady
(document Selenium prêt, Ajax, animations), ce qui a du sens si vous y réfléchissez:
- charger la page contenant le code
- utilisez le code pour charger les données de quelque part via Ajax
- présenter les données, éventuellement avec des animations
Quelque chose comme votre approche de comparaison DOM pourrait être utilisé entre 1 et 2 pour ajouter une autre couche de robustesse.
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");
}