Selenium

Tutorial Selenium: Fundamentos WebDriver

Aprende a realizar pruebas de software de UI utilizando Selenium WebDriver para controlar el navegador y realizar testing de la interfaz de usuario.

Aprende Selenium GRATIS y certifícate

Qué es WebDriver y qué drivers existen

WebDriver es una interfaz de programación que permite controlar navegadores web de manera automatizada. Actúa como un puente entre el código de prueba y el navegador, facilitando la simulación de acciones que un usuario realizaría manualmente, como hacer clic en botones, llenar formularios o navegar entre páginas. WebDriver proporciona métodos y funciones para interactuar directamente con el navegador, lo que lo convierte en una herramienta esencial para la automatización de pruebas en aplicaciones web.

Para lograr esta comunicación, es necesario utilizar un driver específico para cada navegador. Estos drivers son responsables de traducir las instrucciones de WebDriver en comandos que el navegador entiende y ejecuta. A continuación, se describen los drivers más comunes y su propósito:

  • ChromeDriver: Utilizado para automatizar Google Chrome. Es mantenido por el equipo de Chromium y permite controlar instancias de Chrome con WebDriver. Desde Selenium 4.6, la gestión del driver se realiza de forma automática, eliminando la necesidad de descargar y configurar manualmente el ejecutable.
  • GeckoDriver: Es el driver para Mozilla Firefox. Permite que WebDriver interactúe con Firefox utilizando el protocolo W3C WebDriver estándar. Al igual que con ChromeDriver, Selenium gestiona automáticamente su configuración en versiones recientes.
  • EdgeDriver: Diseñado para Microsoft Edge. Facilita la automatización de Edge mediante WebDriver. Con las actualizaciones de Selenium, la detección y configuración de EdgeDriver también es automática.
  • SafariDriver: Exclusivo para el navegador Safari en macOS. SafariDriver viene integrado con el navegador y no requiere una descarga adicional. Sin embargo, es necesario habilitar la opción de Permitir automatización remota en las preferencias de Safari.
  • OperaDriver: Aunque menos común, OperaDriver permite controlar el navegador Opera. Dado que Opera está basado en Chromium, en muchos casos se puede utilizar ChromeDriver como alternativa.

Además de estos drivers para navegadores de escritorio, existen drivers destinados a la automatización móvil:

  • Appium: Es una herramienta que permite automatizar aplicaciones móviles nativas, híbridas y web en iOS y Android. Utiliza WebDriver bajo el capó y es ideal para pruebas en dispositivos móviles o emuladores.
  • Selendroid: Enfocado en la automatización de aplicaciones y sitios web en dispositivos Android. También utiliza el protocolo WebDriver para interactuar con el navegador o la aplicación.

Es crucial asegurarse de que el driver sea compatible con la versión del navegador que se va a automatizar. Aunque Selenium ha mejorado la gestión automática de drivers, en entornos específicos o con navegadores menos comunes puede ser necesario manejar manualmente esta configuración.

Un ejemplo básico de cómo iniciar un navegador utilizando WebDriver en Java es el siguiente:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class EjemploWebDriver {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();
        
        driver.get("https://www.ejemplo.com");
        // Interacciones con la página

        driver.quit();
    }
}

En este código, se crea una instancia de ChromeDriver, que inicializa una nueva ventana de Chrome. El método get navega a la URL especificada. Finalmente, driver.quit() cierra el navegador y libera los recursos utilizados.

Con la llegada de Selenium 4.26, se han introducido mejoras significativas en la gestión de drivers y en la compatibilidad con los navegadores más recientes. Esto simplifica el proceso de configuración y permite centrar los esfuerzos en el desarrollo de las pruebas automatizadas.

Operaciones básicas con WebDriver

Una vez configurado WebDriver, es fundamental conocer las operaciones básicas para interactuar con el navegador y las páginas web. Estas operaciones permiten realizar acciones como navegar entre páginas, obtener información y manejar elementos esenciales durante las pruebas automatizadas.

Inicialización del navegador

Para comenzar, creamos una instancia del navegador que deseamos utilizar. Por ejemplo, para abrir una ventana de Chrome:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class OperacionesBasicas {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        // Operaciones con WebDriver

        driver.quit();
    }
}

Este código inicia una nueva ventana de Chrome y asigna el control a la variable driver, que utilizaremos para interactuar con el navegador.

Navegación a una URL

La acción más elemental es cargar una página web utilizando el método get():

driver.get("https://www.ejemplo.com");

Con esto, el navegador accede a la URL especificada. Es importante que la dirección comience con http:// o https:// para evitar errores.

Obtener información de la página

Podemos obtener detalles relevantes de la página actual, como el título, la URL y el código fuente:

String titulo = driver.getTitle();
System.out.println("Título de la página: " + titulo);

String urlActual = driver.getCurrentUrl();
System.out.println("URL actual: " + urlActual);

String codigoFuente = driver.getPageSource();
// Procesar el código fuente si es necesario

El título y la URL son útiles para verificar que hemos accedido a la página correcta durante una prueba.

Control de la ventana del navegador

Es posible manipular el tamaño y la posición de la ventana del navegador:

driver.manage().window().maximize();   // Maximiza la ventana
driver.manage().window().minimize();   // Minimiza la ventana
driver.manage().window().fullscreen(); // Pantalla completa

Para establecer un tamaño específico:

import org.openqa.selenium.Dimension;

driver.manage().window().setSize(new Dimension(1280, 720)); // Define el tamaño de la ventana

Controlar la ventana del navegador es útil para pruebas responsive o cuando necesitamos verificar cómo se comporta la página en diferentes resoluciones.

Navegación entre páginas

Podemos simular acciones de navegación como avanzar, retroceder y refrescar la página:

driver.navigate().to("https://www.ejemplo.com/pagina1");
driver.navigate().to("https://www.ejemplo.com/pagina2");

driver.navigate().back();    // Regresa a pagina1
driver.navigate().forward(); // Avanza a pagina2

driver.navigate().refresh(); // Refresca la página actual

Estas operaciones son esenciales para pruebas que requieren interactuar con el historial del navegador.

Gestión de cookies

Las cookies son fundamentales en las aplicaciones web modernas. Podemos manejarlas de la siguiente manera:

import org.openqa.selenium.Cookie;

// Añadir una cookie
Cookie cookie = new Cookie("usuario", "Juan");
driver.manage().addCookie(cookie);

// Obtener todas las cookies
Set<Cookie> cookies = driver.manage().getCookies();

// Eliminar una cookie específica
driver.manage().deleteCookieNamed("usuario");

// Eliminar todas las cookies
driver.manage().deleteAllCookies();

Gestionar las cookies permite simular sesiones de usuario y probar funcionalidades relacionadas con la autenticación y preferencias.

Tomar capturas de pantalla

Para capturar el estado actual de la página:

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.nio.file.Files;
import java.nio.file.Paths;

TakesScreenshot screenshot = (TakesScreenshot) driver;
byte[] imagenBytes = screenshot.getScreenshotAs(OutputType.BYTES);
Files.write(Paths.get("captura.png"), imagenBytes);

La captura de pantalla es útil para documentar el estado de la aplicación en un punto específico de la prueba o para diagnosticar fallos.

Cerrar el navegador

Al finalizar las operaciones, es importante cerrar el navegador para liberar recursos:

driver.quit(); // Cierra todas las ventanas y finaliza la sesión

Si deseamos cerrar solo la ventana actual:

driver.close(); // Cierra la ventana actual

Ejemplo completo de operaciones básicas

Integrando las operaciones anteriores:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Set;

public class OperacionesBasicas {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        // Navegar a una URL
        driver.get("https://www.ejemplo.com");

        // Obtener título y URL
        String titulo = driver.getTitle();
        System.out.println("Título: " + titulo);

        String url = driver.getCurrentUrl();
        System.out.println("URL: " + url);

        // Manipular la ventana
        driver.manage().window().setSize(new Dimension(1024, 768));

        // Navegación
        driver.navigate().to("https://www.ejemplo.com/contacto");
        driver.navigate().back();
        driver.navigate().refresh();

        // Manejo de cookies
        Cookie cookie = new Cookie("sesion", "abc123");
        driver.manage().addCookie(cookie);

        Set<Cookie> cookies = driver.manage().getCookies();
        System.out.println("Número de cookies: " + cookies.size());

        driver.manage().deleteCookieNamed("sesion");

        // Captura de pantalla
        TakesScreenshot screenshot = (TakesScreenshot) driver;
        byte[] imagen = screenshot.getScreenshotAs(OutputType.BYTES);
        try {
            Files.write(Paths.get("captura_pantalla.png"), imagen);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // Cerrar el navegador
        driver.quit();
    }
}

Este ejemplo muestra cómo realizar las operaciones básicas con WebDriver, permitiendo una interacción fluida con el navegador y las páginas web durante las pruebas automatizadas.

Notas adicionales

Es recomendable manejar posibles excepciones que puedan surgir durante la ejecución, como errores de tiempo de espera o problemas de conexión. Además, para asegurar que las operaciones se realizan de manera sincronizada con el estado de la página, es conveniente utilizar esperas explícitas, aunque este tema se abordará en profundidad en secciones posteriores.

Options y modo headless

En Selenium, las opciones de navegador son esenciales para configurar y personalizar el comportamiento del navegador antes de su inicialización. Estas opciones permiten ajustar características como el idioma, deshabilitar extensiones, establecer perfiles personalizados o ejecutar el navegador en modo headless, entre otros.

Para Google Chrome, se utiliza la clase ChromeOptions. Esta clase proporciona métodos para agregar argumentos y configuraciones específicas al navegador Chrome. Por ejemplo, para iniciar el navegador en modo headless, se puede hacer lo siguiente:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class EjemploHeadless {
    public static void main(String[] args) {
        var options = new ChromeOptions();
        options.addArguments("--headless"); // Ejecutar en modo headless
        options.addArguments("--disable-gpu"); // Deshabilitar GPU (opcional en Windows)

        WebDriver driver = new ChromeDriver(options);

        driver.get("https://www.ejemplo.com");
        System.out.println("Título de la página: " + driver.getTitle());

        driver.quit();
    }
}

En este ejemplo, se crea una instancia de ChromeOptions y se añaden argumentos con addArguments(). La opción --headless es fundamental para ejecutar el navegador sin interfaz gráfica. El argumento --disable-gpu es opcional y puede ser útil en algunos sistemas operativos para evitar problemas relacionados con la renderización gráfica.

Las opciones del navegador permiten también configurar otros aspectos. Por ejemplo, para iniciar Chrome en modo incógnito y maximizar la ventana:

options.addArguments("--incognito"); // Modo incógnito
options.addArguments("--start-maximized"); // Iniciar maximizado

Además, es posible deshabilitar las notificaciones emergentes que pueden interferir con las pruebas:

options.addArguments("--disable-notifications"); // Deshabilitar notificaciones

Para Mozilla Firefox, se utiliza la clase FirefoxOptions. De manera similar a Chrome, se pueden establecer opciones y preferencias específicas. Para ejecutar Firefox en modo headless:

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

public class EjemploFirefoxHeadless {
    public static void main(String[] args) {
        var options = new FirefoxOptions();
        options.addArguments("--headless"); // Ejecutar en modo headless

        WebDriver driver = new FirefoxDriver(options);

        driver.get("https://www.ejemplo.com");
        System.out.println("Título de la página: " + driver.getTitle());

        driver.quit();
    }
}

Con FirefoxOptions, también es posible establecer preferencias específicas usando el método setPreference(). Por ejemplo, para deshabilitar la cache y configurar el idioma:

options.setPreference("browser.cache.disk.enable", false); // Deshabilitar cache en disco
options.setPreference("intl.accept_languages", "es-ES"); // Establecer idioma

La configuración de preferencias es especialmente útil para ajustar el comportamiento del navegador y garantizar que las pruebas se ejecuten bajo las condiciones deseadas.

Para personalizar la carpeta de descargas y automatizar la descarga de archivos sin intervención del usuario, se pueden establecer las siguientes preferencias en Chrome:

Map<String, Object> prefs = new HashMap<>();
prefs.put("download.default_directory", "/ruta/descargas"); // Ruta de descargas
prefs.put("download.prompt_for_download", false); // No preguntar al descargar
prefs.put("download.directory_upgrade", true);
prefs.put("safebrowsing.enabled", true);

options.setExperimentalOption("prefs", prefs);

Y en Firefox:

options.setPreference("browser.download.folderList", 2);
options.setPreference("browser.download.dir", "/ruta/descargas");
options.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf"); // Tipo MIME

Las descargas automáticas son esenciales cuando se necesitan validar archivos descargados durante las pruebas.

Otra funcionalidad avanzada es la posibilidad de añadir extensiones al navegador durante las pruebas. En Chrome, se puede hacer de la siguiente forma:

options.addExtensions(new File("/ruta/a/extension.crx")); // Añadir extensión

Para Firefox:

options.addExtensions(new File("/ruta/a/extension.xpi")); // Añadir extensión

Incorporar extensiones personalizadas permite simular escenarios más complejos y ajustar el entorno de prueba a necesidades específicas.

El uso de perfiles de usuario es otra característica importante. En Chrome, se puede especificar un perfil existente:

options.addArguments("user-data-dir=/ruta/a/perfil"); // Usar perfil de usuario

Esto es útil cuando se requiere utilizar configuraciones o datos almacenados en un perfil determinado, como cookies o sesiones iniciadas.

En cuanto al modo headless, es importante mencionar que, aunque ofrece ventajas en términos de rendimiento y recursos, puede presentar diferencias en el comportamiento de algunas páginas web en comparación con el modo normal. Por ello, es recomendable verificar que las pruebas en modo headless reproducen correctamente los escenarios deseados.

Para capturar registros de desempeño y habilitar funcionalidades experimentales en Chrome, se puede utilizar:

options.setExperimentalOption("enableTracing", true);

Las opciones experimentales permiten acceder a características avanzadas y pueden ser útiles para diagnósticos o pruebas específicas.

Finalmente, es posible combinar múltiples opciones y preferencias para personalizar completamente el entorno de ejecución:

import java.util.Map;
import java.util.HashMap;

var options = new ChromeOptions();
options.addArguments("--headless");
options.addArguments("--disable-gpu");
options.addArguments("--incognito");
options.addArguments("--start-maximized");

Map<String, Object> prefs = new HashMap<>();
prefs.put("profile.default_content_settings.cookies", 2);
prefs.put("intl.accept_languages", "es");

options.setExperimentalOption("prefs", prefs);

La correcta configuración de las options y el modo headless en Selenium es fundamental para adaptar las pruebas automatizadas a diferentes entornos y requisitos, garantizando así su efectividad y fiabilidad.

Manejo de múltiples navegadores y versiones

Con Selenium 4.26, la gestión de drivers de navegador se ha simplificado significativamente gracias a la detección automática integrada de forma nativa. Esto elimina la necesidad de utilizar herramientas externas como WebDriverManager para manejar diferentes navegadores y sus versiones.

La inicialización del WebDriver adecuado para cada navegador se puede realizar configurando nuestro código para que seleccione el driver según nuestras necesidades. Esto nos permite manejar múltiples navegadores sin depender de soluciones adicionales. Por ejemplo, podemos crear una función que devuelve el WebDriver apropiado basándose en un parámetro:

public WebDriver crearWebDriver(String navegador) {
    return switch (navegador.toLowerCase()) {
        case "chrome" -> new ChromeDriver();
        case "firefox" -> new FirefoxDriver();
        case "edge" -> new EdgeDriver();
        default -> throw new IllegalArgumentException("Navegador no soportado: " + navegador);
    };
}

De esta forma, logramos inicializar dinámicamente el driver del navegador que deseemos. Es importante verificar que los navegadores estén correctamente instalados en el sistema y actualizados a versiones compatibles con Selenium.

Aprovechando las ventajas de Java 23, podemos gestionar nuestras pruebas de manera más elegante y concisa. Por ejemplo, al utilizar expresiones lambda y características del paradigma funcional, mejoramos la legibilidad y el mantenimiento del código.

Una manera efectiva de ejecutar pruebas en diferentes navegadores es parametrizar nuestras pruebas con JUnit 5, lo que permite ejecutar la misma prueba en distintos entornos. Por ejemplo:

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class PruebasMultiplesNavegadores {

    @ParameterizedTest
    @ValueSource(strings = {"chrome", "firefox", "edge"})
    void pruebaEnVariosNavegadores(String navegador) {
        WebDriver driver = crearWebDriver(navegador);
        driver.get("https://www.ejemplo.com");
        System.out.println("Título en " + navegador + ": " + driver.getTitle());
        driver.quit();
    }

    public WebDriver crearWebDriver(String navegador) {
        return switch (navegador.toLowerCase()) {
            case "chrome" -> new ChromeDriver();
            case "firefox" -> new FirefoxDriver();
            case "edge" -> new EdgeDriver();
            default -> throw new IllegalArgumentException("Navegador no soportado: " + navegador);
        };
    }
}

En este ejemplo, la prueba pruebaEnVariosNavegadores se ejecutará tres veces, una por cada navegador especificado en @ValueSource. Esto nos permite verificar que nuestra aplicación funciona correctamente en diferentes navegadores con un código eficiente y conciso.

Gracias a la gestión automática de drivers en Selenium 4.6 y posteriores, ya no es necesario descargar manualmente los drivers ejecutables. Simplemente instanciando el driver correspondiente, Selenium se encarga de gestionar la descarga y configuración necesarias. No obstante, debemos asegurarnos de que los navegadores estén instalados en el sistema y sean compatibles.

Si necesitamos especificar una versión particular del navegador o configurar opciones específicas, podemos utilizar las clases de opciones que proporciona Selenium. Por ejemplo, para configurar opciones en Chrome:

var opciones = new ChromeOptions();
opciones.setBinary("/ruta/a/chrome/version/específica");
opciones.addArguments("--incognito");

WebDriver driver = new ChromeDriver(opciones);

Y para Firefox:

var opciones = new FirefoxOptions();
opciones.setBinary("/ruta/a/firefox/version/específica");
opciones.addArguments("--private");

WebDriver driver = new FirefoxDriver(opciones);

Al especificar la ruta al binario del navegador, tenemos control sobre la versión exacta utilizada durante las pruebas. Esto es útil cuando necesitamos probar nuestra aplicación en versiones específicas o manejar múltiples instalaciones de un navegador.

Para gestionar configuraciones más complejas, podemos utilizar un archivo de propiedades o variables de entorno que definan el navegador y sus opciones. Esto permite modificar el comportamiento de las pruebas sin alterar el código fuente. Por ejemplo, podemos leer el navegador deseado desde una propiedad del sistema:

String navegador = System.getProperty("navegador", "chrome");
WebDriver driver = crearWebDriver(navegador);

Al ejecutar la prueba, especificamos el navegador mediante argumentos de línea de comandos:

mvn test -Dnavegador=firefox

Así, nuestro código es más flexible y adaptable a diferentes entornos y necesidades sin necesidad de cambios en el código fuente.

Aprende Selenium GRATIS online

Todas las lecciones de Selenium

Accede a todas las lecciones de Selenium y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Selenium y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Aprender qué es WebDriver en Selenium
  • Aprender qué tipos de navegadores hay
  • Aprender a usar distintos navegadores