Que Es Selenium WebDriver?

Selenium WebDriver es la herramienta de automatizacion de navegadores mas establecida, utilizada por millones de testers. Proporciona una interfaz de programacion para controlar navegadores web a traves del protocolo W3C WebDriver.

Arquitectura de Selenium

Codigo de Test (Java/Python/JS/C#)
        ↓
   API WebDriver
        ↓
   Driver del Navegador (ChromeDriver, GeckoDriver)
        ↓
   Navegador (Chrome, Firefox, Safari, Edge)

Tu codigo llama a la API WebDriver, que envia comandos al driver especifico del navegador, que controla el navegador real.

Configuracion de Selenium

JavaScript (WebdriverIO)

npm init -y
npm install webdriverio @wdio/cli @wdio/mocha-framework
npx wdio config

Python

pip install selenium pytest

Escribiendo tu Primer Test

JavaScript (WebdriverIO)

describe('Pagina de Login', () => {
  it('deberia hacer login con credenciales validas', async () => {
    await browser.url('/login');
    await $('#email').setValue('admin@test.com');
    await $('#password').setValue('secret123');
    await $('button[type="submit"]').click();
    await expect(browser).toHaveUrl('/dashboard');
    await expect($('.welcome')).toHaveText('Welcome, Admin');
  });
});

Python

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

def test_valid_login():
    driver = webdriver.Chrome()
    driver.get("https://app.example.com/login")

    driver.find_element(By.ID, "email").send_keys("admin@test.com")
    driver.find_element(By.ID, "password").send_keys("secret123")
    driver.find_element(By.CSS_SELECTOR, "button[type='submit']").click()

    wait = WebDriverWait(driver, 10)
    wait.until(EC.url_contains("/dashboard"))

    welcome = driver.find_element(By.CLASS_NAME, "welcome").text
    assert welcome == "Welcome, Admin"
    driver.quit()

Estrategias de Localizacion

EstrategiaEjemploConfiabilidad
By.idBy.id("email")Alta (si es unico)
By.cssBy.css("[data-testid='email']")Alta
By.xpathBy.xpath("//input[@name='email']")Media
By.nameBy.name("email")Media
By.classNameBy.className("input-email")Baja

Mejores Practicas de Localizadores

  1. Preferir atributos data-testid: [data-testid="login-submit"]
  2. Usar selectores CSS sobre XPath cuando sea posible — son mas rapidos
  3. Evitar XPath absoluto: /html/body/div[3]/form/input[2] se rompe facilmente
  4. Evitar clases de estilo: .btn-primary puede cambiar en redisenos
  5. Usar XPath relativo cuando sea necesario: //button[contains(text(), 'Submit')]

Waits

Wait Implicito

driver.implicitly_wait(10)

Establece un timeout global para todas las busquedas de elementos. Simple pero puede enmascarar problemas de timing.

Wait Explicito (Recomendado)

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(driver, 10)

# Esperar a que el elemento sea visible
element = wait.until(EC.visibility_of_element_located((By.ID, "dashboard")))

# Esperar a que sea clickeable
wait.until(EC.element_to_be_clickable((By.ID, "submit")))

# Esperar a que aparezca texto
wait.until(EC.text_to_be_present_in_element((By.CLASS_NAME, "status"), "Complete"))

# Esperar cambio de URL
wait.until(EC.url_contains("/dashboard"))

Interacciones Avanzadas

API de Actions

from selenium.webdriver import ActionChains

actions = ActionChains(driver)

# Hover sobre elemento
actions.move_to_element(menu_item).perform()

# Drag and drop
actions.drag_and_drop(source, target).perform()

# Click derecho
actions.context_click(element).perform()

# Doble click
actions.double_click(element).perform()

Manejo de Dropdowns

from selenium.webdriver.support.ui import Select

dropdown = Select(driver.find_element(By.ID, "country"))
dropdown.select_by_visible_text("Mexico")
dropdown.select_by_value("MX")
dropdown.select_by_index(5)

Manejo de Alerts

alert = driver.switch_to.alert
alert_text = alert.text
alert.accept()    # Click OK
alert.dismiss()   # Click Cancel
alert.send_keys("texto de entrada")

Manejo de Frames y Ventanas

# Cambiar a iframe
driver.switch_to.frame("frame-name")
driver.switch_to.default_content()  # Volver a pagina principal

# Manejar nueva ventana/tab
original_window = driver.current_window_handle
# ... accion que abre nueva ventana
for handle in driver.window_handles:
    if handle != original_window:
        driver.switch_to.window(handle)
        break

Screenshots

driver.save_screenshot("screenshots/test-failure.png")

Ejecucion de JavaScript

driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
driver.execute_script("arguments[0].click()", hidden_button)
title = driver.execute_script("return document.title")

Mejores Practicas de Selenium

  1. Siempre usa waits explicitos — nunca Thread.sleep()
  2. Cierra el driver en teardown — prevenir procesos zombie del navegador
  3. Usa Page Object Model — separar logica de test de detalles de pagina
  4. Prefiere selectores CSS — mas rapidos y legibles que XPath
  5. Ejecuta en modo headless para CIoptions.add_argument("--headless")
  6. Establece timeouts razonables — 10-30 segundos para waits explicitos
  7. Maneja excepciones de stale element — relocaliza elementos cuando el DOM cambia

Ejercicio: Construye un Suite de Tests con Selenium

Crea un suite de tests Selenium:

  1. Configura un proyecto con Selenium + tu lenguaje preferido
  2. Escribe una clase BasePage con metodos comunes
  3. Crea page objects para Login, Dashboard y Settings
  4. Escribe 5 test cases cubriendo login, navegacion, envio de formulario, seleccion de dropdown y logout
  5. Agrega waits explicitos para todos los elementos dinamicos
  6. Ejecuta tests en modo con y sin interfaz grafica

Puntos Clave

  • Selenium WebDriver controla navegadores via protocolo W3C WebDriver
  • Usa waits explicitos (WebDriverWait) en vez de Thread.sleep()
  • Selectores CSS y data-testid son las mejores estrategias de localizacion
  • La API Actions maneja interacciones complejas (hover, drag, teclado)
  • Siempre usa Page Object Model para codigo mantenible
  • Selenium soporta Java, Python, JavaScript, C#, Ruby y Kotlin