| name | selenium |
| description | Automatisation de navigateur avec Selenium WebDriver — Java, Python, JS, WebDriverManager, Grid, Remote WebDriver, et bonnes pratiques. |
| version | 1.0.0 |
| author | EVA |
| license | MIT |
| metadata | {"hermes":{"tags":["selenium","webdriver","testing","browser","automation","java","python"],"related_skills":["playwright","cypress","e2e-testing"]}} |
Selenium WebDriver — Automation de Navigateur
Overview
Selenium est le standard historique d'automatisation de navigateur Web. Supporte Chrome, Firefox, Safari, Edge — et les environnements headless. Selenium 4 apporte le support natif du Chrome DevTools Protocol (CDP), les relative locators, et une meilleure gestion des fenêtres/tabs.
When to Use
- Tests E2E existants à maintenir (legacy)
- Grid distribuée multi-navigateur/multi-OS
- Environnements où Playwright/Cypress ne sont pas disponibles (IE11, anciens Safari)
- Scraping complexe nécessitant l'exécution de JS
- Ne pas utiliser pour : nouveaux projets greenfield — préférer Playwright (plus moderne, fiable, rapide)
Installation
Python (recommandé pour scraping/tests rapides)
pip install selenium webdriver-manager
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install())
)
Java (recommandé pour tests enterprise)
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.27.0</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>5.9.0</version>
</dependency>
JavaScript
npm install selenium-webdriver
npm install -D @types/selenium-webdriver
Configuration
Python — Options Chrome
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
options = Options()
options.add_argument('--headless=new')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1920,1080')
options.add_argument('--disable-notifications')
options.add_argument('--lang=fr')
prefs = {
'download.default_directory': '/tmp/downloads',
'download.prompt_for_download': False,
}
options.add_experimental_option('prefs', prefs)
options.add_argument('--proxy-server=http://proxy:8080')
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options,
)
Python — Firefox
from selenium import webdriver
from selenium.webdriver.firefox.service import Service
from webdriver_manager.firefox import GeckoDriverManager
options = webdriver.FirefoxOptions()
options.add_argument('--headless')
options.set_preference('intl.accept_languages', 'fr')
driver = webdriver.Firefox(
service=Service(GeckoDriverManager().install()),
options=options,
)
Selenium Grid (Remote)
from selenium import webdriver
from selenium.webdriver.common.options import Options
options = Options()
options.browser_version = 'latest'
options.platform_name = 'Linux'
driver = webdriver.Remote(
command_executor='http://selenium-hub:4444/wd/hub',
options=options,
)
API WebDriver — Commandes Essentielles
Navigation
driver.get('https://example.com')
driver.current_url
driver.title
driver.back()
driver.forward()
driver.refresh()
driver.close()
driver.quit()
Localisation d'Éléments
from selenium.webdriver.common.by import By
driver.find_element(By.ID, 'email')
driver.find_element(By.NAME, 'password')
driver.find_element(By.CLASS_NAME, 'btn-primary')
driver.find_element(By.TAG_NAME, 'h1')
driver.find_element(By.CSS_SELECTOR, '[data-test=submit]')
driver.find_element(By.XPATH, '//button[text()="Valider"]')
driver.find_element(By.LINK_TEXT, 'Cliquez ici')
driver.find_element(By.PARTIAL_LINK_TEXT, 'Cliquez')
elements = driver.find_elements(By.CLASS_NAME, 'item')
len(elements)
Actions sur les Éléments
element = driver.find_element(By.ID, 'email')
element.send_keys('user@example.com')
element.clear()
element.click()
element.submit()
element.get_attribute('href')
element.text
element.is_displayed()
element.is_enabled()
element.is_selected()
element.get_attribute('value')
Wait (Attentes)
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 10)
element = wait.until(
EC.presence_of_element_located((By.ID, 'monElement'))
)
element = wait.until(
EC.visibility_of_element_located((By.CLASS_NAME, 'result'))
)
element = wait.until(
EC.element_to_be_clickable((By.CSS_SELECTOR, '[data-test=submit]'))
)
wait.until(
EC.invisibility_of_element_located((By.ID, 'loading'))
)
wait.until(
EC.text_to_be_present_in_element((By.ID, 'status'), 'Terminé')
)
wait.until(EC.url_contains('/dashboard'))
wait.until(EC.alert_is_present())
driver.switch_to.alert.accept()
Interaction Formulaires
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element(By.ID, 'country'))
select.select_by_visible_text('France')
select.select_by_value('FR')
select.select_by_index(1)
checkbox = driver.find_element(By.ID, 'accept-terms')
if not checkbox.is_selected():
checkbox.click()
driver.find_element(By.NAME, 'file').send_keys('/home/user/document.pdf')
JavaScript Execution
driver.execute_script('window.scrollTo(0, document.body.scrollHeight)')
driver.execute_script('arguments[0].scrollIntoView(true);', element)
title = driver.execute_script('return document.title')
driver.execute_script("document.querySelector('#loading').remove()")
timings = driver.execute_script("""
return window.performance.getEntries().map(e => ({
name: e.name,
duration: e.duration
}))
""")
Navigation Multi-Onglets
driver.switch_to.new_window('tab')
driver.get('https://autre-site.com')
original_window = driver.current_window_handle
for window_handle in driver.window_handles:
if window_handle != original_window:
driver.switch_to.window(window_handle)
break
driver.close()
driver.switch_to.window(original_window)
wait.until(EC.number_of_windows_to_be(2))
driver.switch_to.window(driver.window_handles[-1])
Alertes et Popups
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 5)
alert = wait.until(EC.alert_is_present())
print(alert.text)
alert.accept()
driver.get('https://user:password@example.com')
Captures d'écran
driver.save_screenshot('/tmp/screenshot.png')
element.screenshot('/tmp/element.png')
pdf_data = driver.execute_cdp_cmd('Page.printToPDF', {
'printBackground': True,
'format': 'A4',
})
with open('/tmp/page.pdf', 'wb') as f:
import base64
f.write(base64.b64decode(pdf_data['data']))
Selenium 4 — Relative Locators
from selenium.webdriver.support.relative_locator import locate_with
password_field = driver.find_element(By.ID, 'password')
submit_button = driver.find_element(
locate_with(By.TAG_NAME, 'button').below(password_field)
)
login_form = driver.find_element(By.ID, 'login')
nearby = driver.find_element(
locate_with(By.CLASS_NAME, 'help-text').to_left_of(login_form)
)
Chrome DevTools Protocol (CDP) — Selenium 4
import trio
async def cdp_example():
async with driver.devtools() as devtools:
await devtools.send('Network.enable')
async with devtools.event_listener('Network.requestWillBeSent') as events:
async for event in events:
print(f"Requête: {event['request']['url']}")
driver.execute_cdp_cmd('Network.setBlockedURLs', {
'urls': ['*.jpg', '*.png', '*.gif']
})
driver.execute_cdp_cmd('Network.enable', {})
driver.execute_cdp_cmd('Emulation.setGeolocationOverride', {
'latitude': 48.8566,
'longitude': 2.3522,
'accuracy': 100,
})
driver.execute_cdp_cmd('Emulation.setUserAgentOverride', {
'userAgent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X)',
'platform': 'iPhone',
})
Page Object Model (POM)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
class LoginPage:
URL = 'https://example.com/login'
def __init__(self, driver):
self.driver = driver
self.wait = WebDriverWait(driver, 10)
EMAIL_INPUT = (By.ID, 'email')
PASSWORD_INPUT = (By.ID, 'password')
SUBMIT_BUTTON = (By.CSS_SELECTOR, '[data-test=submit]')
ERROR_MESSAGE = (By.CSS_SELECTOR, '[data-test=error]')
def open(self):
self.driver.get(self.URL)
return self
def login(self, email: str, password: str):
self.driver.find_element(*self.EMAIL_INPUT).send_keys(email)
self.driver.find_element(*self.PASSWORD_INPUT).send_keys(password)
self.driver.find_element(*self.SUBMIT_BUTTON).click()
return self
def get_error_message(self) -> :
.wait.until(
EC.visibility_of_element_located(.ERROR_MESSAGE)
).text
():
login_page = LoginPage(driver).()
login_page.login(, )
wait.until(EC.url_contains())
():
login_page = LoginPage(driver).()
login_page.login(, )
login_page.get_error_message()
Exécution avec Pytest
import pytest
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
@pytest.fixture
def driver():
options = webdriver.ChromeOptions()
options.add_argument('--headless=new')
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
options=options,
)
driver.implicitly_wait(5)
yield driver
driver.quit()
CI/CD
name: Selenium Tests
on: [push]
jobs:
selenium:
runs-on: ubuntu-latest
services:
selenium:
image: selenium/standalone-chrome:latest
ports: ['4444:4444']
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: '3.12' }
- run: pip install -r requirements-dev.txt
- run: pytest tests/ -v --headed --hub http://localhost:4444
Common Pitfalls
sleep() au lieu de WebDriverWait — toujours préférer les attentes explicites
StaleElementReferenceException — élément rafraîchi, re-chercher avant d'interagir
- Ne pas quitter le driver — toujours appeler
driver.quit() en fin de test (ou utiliser context manager)
- Sélecteurs XPath fragiles — préférer CSS/ID/data-attributes
- Fenêtres/popups non gérées — bien utiliser
switch_to.window() / switch_to.alert
- Browser driver incompatible — toujours utiliser WebDriverManager pour la gestion des versions
Verification Checklist