Fondamentaux de Selenium
Selenium est un framework open-source incontournable pour l'automatisation des tests d'interface utilisateur (UI) Web. Il supporte une large gamme de langages de programmation tels que Java, Python, C# et JavaScript, et permet d'exécuter des scripts sur différents navigateurs (Chrome, Firefox, Safari, Edge).
Limitations techniques et périmètre
Contrairement à certains outils commerciaux, Selenium se concentre exclusivement sur les applications web. Il ne supporte pas nativement l'automatisation des applications de bureau (Desktop). Pour interagir avec des éléments Windows, il faut coupler Selenium avec d'autres outils comme WinAppDriver ou AutoIT.
De plus, Selenium ne possède pas de moteur d'exécution de tests intégré. Il délègue la gestion des cas de test, des suites et des rapports à des frameworks tiers tels que JUnit ou TestNG pour Java, et Pytest ou Unittest pour Python.
Composants de l'écosystème Selenium
- Selenium IDE : Une extension de navigateur permettant l'enregistrement et la lecture rapide de scripts, principalement utilisée pour le prototypage.
- Selenium Grid : Un outil permettant de distribuer l'exécution des tests sur plusieurs machines et navigateurs en parallèle, optimisant ainsi le temps d'exécution.
- Selenium WebDriver : Le composant central qui communique directement avec le navigateur via un pilote (driver) spécifique, offrant un contrôle précis sur les éléments DOM.
Stratégies de localisation des éléments
La précision des tests dépend de la robustesse des locateurs. Selenium propose plusieurs méthodes : ID, Name, ClassName, TagName, LinkText, PartialLinkText, XPath et CSS Selector. Pour les éléments dont les attributs sont dynamiques, l'utilisation de fonctions XPath comme contains() ou starts-with() est recommandée.
// Exemple de localisation dynamique en Java
WebElement boutonDynamique = driver.findElement(By.xpath("//button[contains(@id, 'auth-submit-')]"));
Gession des attentes (Waits)
La synchronisation est cruciale pour éviter les tests instables (flaky tests) :
- Implicit Wait : Définit un temps d'attente global pour toutes les recherches d'éléments durant la session du driver.
- Explicit Wait (WebDriverWait) : Attend qu'une condition spécifique soit remplie pour un élément précis (ex: visibilité, cliquabilité). C'est la méthode recommandée.
- Thread.sleep() : Une pause forcée du thread. À éviter car elle ralentit inutilement les tests.
Interacsion avec les éléments complexes
Pour manipuler les menus déroulnats standards (balises <select>), Selenium fournit la classe Select.
// Manipulation d'un menu déroulant
WebElement menuElt = driver.findElement(By.id("choix-langue"));
Select selecteurLangue = new Select(menuElt);
selecteurLangue.selectByValue("fr");
Pour vérifier l'état d'un élément (bouton radio, case à cocher), on utilise les méthodes suivantes :
isDisplayed(): Vérifie si l'élément est visible sur la page.isEnabled(): Vérifie si l'élément est actif (non grisé).isSelected(): Vérifie si l'option est cochée.
Gestion des fenêtres, frames et alertes
Selenium nécessite un changement de contexte explicite pour interagir avec des éléments hors du document principal :
- Frames :
driver.switchTo().frame("nom_ou_id"); - Alertes :
Alert alerte = driver.switchTo().alert(); alerte.accept(); - Fenêtres multiples : Utilisation de
getWindowHandles()pour récupérer les identifiants et basculer entre les onglets.
Le cas des éléments masqués (Hidden Elements)
Une question fréquente concerne les éléments ayant des attributs CSS tels que display: none ou type="hidden". Selenium peut localiser ces éléments dans le DOM via findElement(), mais toute tentative d'interaction directe (comme click() ou sendKeys()) lèvera une ElementNotVisibleException.
Pour interagir avec un élément masqué, il faut passer par l'exécution de JavaScript :
# Exemple Python pour cliquer sur un élément caché
action_js = "arguments[0].click();"
cible_cachee = driver.find_element_by_id("lien-invisible")
driver.execute_script(action_js, cible_cachee)
Optimisation et stabilité des scripts
Pour améliorer la fiabilité et la vitesse de vos suites de tests :
- Privilégiez les Explicit Waits pour ne pas attendre plus que nécessaire.
- Utilisez le pattern Page Object Model (POM) pour découpler la logique des tests de la structure des pages, facilitant ainsi la maintenance.
- Réduisez l'usage des XPath absolus au profit des CSS Selectors ou XPath relatifs, plus performants et moins fragiles.
- En cas d'échecs aléatoires, vérifiez si l'élément nécessite un défilement (scrolling) préalable ou si des requêtes AJAX sont encore en cours.
Différences entre Close() et Quit()
Il est important de distinguer ces deux méthodes de fermeture : close() ferme uniquement la fenêtre ou l'onglet actuellement focalisé par le WebDriver, tandis que quit() ferme toutes les fenêtres ouvertes et met fin proprement à la session du driver, libérant ainsi les ressources système.