Lorsque l’on commence à automatiser des tests UI, l’un des premiers problèmes que l’on rencontre est le fait que le test veut s’exécuter alors même que la page n’a pas encore fini de charger. On se retrouve donc potentiellement à vouloir cliquer sur un bouton qui n’existe pas encore !
Comment faire dans ce cas pour s’assurer que cela n’arrive pas ?
Plusieurs techniques existent pour s’assurer qu’une page a fini de charger avant de laisser les tests automatiques interagir avec ladite page. Personnellement, je recommande d’utiliser toutes ces méthodes en complément les unes des autres.
S’assurer d’arriver sur la page que l’on souhaite charger
Assurez-vous que vous êtes bien arrivé-e sur la page que vous voulez charger. En effet, il ne sert à rien d’attendre qu’une page ait fini de charger si la page en question n’est pas celle que vous voulez.
Pour cela je vous conseille d’utiliser la commande « wait » combinée à un test d’URL.
Si vous écrivez votre test en Java + Selenium, vous aurez donc quelque chose comme ça :
WebDriverWait wait = wait(10);
wait.until(ExpectedConditions.urlContains(page));
Ici, on indique que l’on va attendre un maximum de 10 secondes pour que la page charge l’URL que nous attendons. Si au bout de ces 10 secondes, nous ne sommes pas sur la page attendue, le test échouera. (En revanche, si la page ne met que 2 secondes pour aller à l’URL attendue, nous n’attendrons pas l’intégralité des 10 secondes et le test continuera dès que l’URL voulue aura été chargée).
S’assurer de la bonne valeur du « document.readyState »
Assurez-vous que le « document.readyState » a pour valeur « complete ». Ce « document.readyState » est une propriété qui vous indique lorsque votre page a fini de charger. Attention toutefois, cela ne prend pas en compte de possibles modifications que pourraient faire des scripts.
Si vous écrivez vos tests en Java + Selenium, le code pour s’assurer de l’état de « document.readyState » devrait ressembler à ceci :
"WebDriverWait wait = wait(15);
wait.until(webDriver ->
((JavascriptExecutor) driver).executeScript("return document.readyState").
toString().equals("complete"));"
(Ici, on va donc attendre un maximum de 15 secondes et lever une erreur si la page met plus de temps que cela à charger).
Attendre la présence et visibilité de l’élément souhaité
Dans les étapes précédentes, nous nous assurons que nous sommes bien arrivé-e-s sur la page souhaitée et que ladite page ait fini de charger son contenu HTML. Néanmoins, si l’élément avec lequel nous souhaitons interagir est ajouté ou modifié par un script JavaScript, ledit élément pourrait ne pas encore être présent. Pour cette raison, il est conseillé d’attendre la présence (et visibilité) dudit élément avant de tenter d’interagir avec.
Si vous écrivez vos tests en Java + Selenium, le code pour s’assurer de cela devrait ressembler à ce qui suit :
WebDriverWait wait = wait(8);
wait.until(ExpectedConditions.visibilityOf
ElementLocated(By.id(prop.getProperty(id))));
(Ici, on attend donc un maximum de 8 secondes et si l’élément n’est toujours pas visible au bout de ces 8 secondes, une erreur est levée).
Pour finir : prendre en compte les « loaders maison » des différents sites
Vous êtes sur la bonne page, la page a fini de charger et l’élément avec lequel vous souhaitez interagir est bien présent. Vous vous dites donc que tout est bon et que vous pouvez cliquer sans soucis sur l’élément souhaité. Hélas ! Tout n’est pas forcément bon !
En effet, beaucoup de sites utilisent des « loaders maison ». Ces loaders sont généralement là pour rassurer le client sur le fait que « oui, le site met du temps à charger. Mais c’est normal ! s’il-vous-plait-ne-partez-pas ! ».
Afin de pouvoir automatiser les tests au mieux, il va donc falloir que vous preniez en compte ces « loaders maison » et que vous vous assuriez qu’ils ne sont plus là avant de commencer à interagir avec votre page.
Pour cela, deux possibilités. Si votre « loader maison » se contente de devenir invisible une fois son travail accompli, il va falloir tester sa visibilité. Par exemple, de la façon suivante (avec un exemple utilisant Java + Selenium) :
WebDriverWait wait = wait(10);
wait.until(ExpectedConditions.invisibilityOf
(driver.findElement(By.id("loadingModal"))));
Attention toutefois, si votre loader maison ne devient pas juste invisible, mais disparait complètement de la page, la technique ci-dessus pourrait provoquer une erreur. Dans ce cas de figure, il vaut mieux tester la présence ou non du loader maison.
Note : un élément invisible est considéré comme présent. C’est pour cela que l’on ne peut pas utiliser cette technique si le loader se contente de passer en invisible.
Si vous utilisez Java + Selenium, voici à quoi votre code pourrait ressembler :
WebDriverWait wait = new WebDriverWait(driver, 35);
wait.until(ExpectedConditions.not
(ExpectedConditions.presenceOfAll
ElementsLocatedBy(By.className
("loadingoverlay"))));
(Ici, on attend la disparition de tous les éléments appartenant à la classe « loadinoverlay »).
Conclusion partielle
Avec tout cela, vous serez désormais sûr-e que votre page et vos éléments ont fini de charger avant que vos tests n’interagissent avec. Vous ne devriez donc plus avoir d’erreurs liées à cela. Toutefois, d’autres circonstances peuvent provoquer l’échec de vos tests.