Selenium 4 y Chrome DevTools: Integración Avanzada para Automatización

Fundamentos de Chrome DevTools

Chrome DevTools es un conjunto de herramientas integradas en navegadores basados en Chromium, como Google Chrome, que permite a los desarrolladores depurar, analizar y optimizar sitios web. Entre sus capacidades destacan la inspección del DOM, la edición en vivo de estilos, el monitoreo de rendimiento, la emulación de ubicaciones geográficas y condiciones de red, así como la ejecución de código JavaScript.

API de Selenium 4 para Chrome DevTools

Con Selenium 4, se introdujo soporte nativo para las API de Chrome DevTools mediante el protocolo CDP (Chrome DevTools Protocol). Esto permite extender la automatización para capturar tráfico de red, emular entornos geográficos, modificar métricas de dispositivos y más. Las clases como ChromiumDriver ahora exponen métodos como getDevTools() y executeCdpCommand() para interactuar directamente con DevTools.

Emulación de Modo de Dispositivo

Para probar la responsividad de una aplicación web en diferentes vistas, podemos simular dimensiones específicas de dispositivo. Utilizamos el comando CDP Emulation.setDeviceMetricsOverride. En el siguiente ejemplo, se configuran parámetros esenciales como ancho, alto y factor de escala, usando executeCdpCommand() para mayor simplicidad.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import java.util.HashMap;
import java.util.Map;

public class EmularVistaDispositivo {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "ruta/chromedriver");
        ChromeDriver controlador = new ChromeDriver();
        DevTools herramientas = controlador.getDevTools();
        herramientas.createSession();
        
        Map<String, Object> ajustes = new HashMap<>();
        ajustes.put("width", 480);
        ajustes.put("height", 800);
        ajustes.put("mobile", true);
        ajustes.put("deviceScaleFactor", 2);
        
        controlador.executeCdpCommand("Emulation.setDeviceMetricsOverride", ajustes);
        controlador.get("https://ejemplo.com");
        controlador.quit();
    }
}

Emulación de Geolocalización

Para verificar funcionalidades basadas en la ubicación del usuario, como contenido regional o precios específicos, podemos simular coordenadas geográficas. Usamos el método send() con el comando integrado Emulation.setGeolocationOverride, proporcionando latitud, longitud y precisión.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.emulation.Emulation;
import java.util.Optional;

public class SimularUbicacion {
    public static void main(String[] args) {
        ChromeDriver nav = new ChromeDriver();
        DevTools devTools = nav.getDevTools();
        devTools.createSession();
        
        devTools.send(Emulation.setGeolocationOverride(
            Optional.of(34.0522), // Latitud (Los Ángeles)
            Optional.of(-118.2437), // Longitud
            Optional.of(150) // Precisión en metros
        ));
        nav.get("https://sitiodeprueba.com/ubicacion");
        nav.quit();
    }
}

Simulación de Condiciones de Red

Probar el comportamiento de una aplicación bajo conexiones lentas o inestables es crucial. Mediante el comando Network.emulateNetworkConditions, podemos imitar velocidades como 2G. Primero habilitamos la red con Network.enable, luego aplicamos las condiciones simuladas.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.ConnectionType;
import java.util.Optional;

public class EmularRedLenta {
    public static void main(String[] args) {
        ChromeDriver controlador = new ChromeDriver();
        DevTools herramientas = controlador.getDevTools();
        herramientas.createSession();
        
        herramientas.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        herramientas.send(Network.emulateNetworkConditions(
            false, // Sin pérdida de conexión
            100,   // Latencia (ms)
            50,    // Tasa de transferencia entrante (kbps)
            100,   // Tasa de transferencia saliente (kbps)
            Optional.of(ConnectionType.CELLULAR2G)
        ));
        controlador.get("https://ejemplo.com");
        controlador.quit();
    }
}

Captura de Tráfico de Red

Para inspeccionar solicitudes HTTP realizadas por la aplicación, utilizamos eventos de red. Activamos la red con Network.enable y añadimos un listener para Network.requestWillBeSent, donde extraemos detalles como URL y método de cada solicitud.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import java.util.Optional;

public class MonitorearSolicitudes {
    public static void main(String[] args) {
        ChromeDriver driver = new ChromeDriver();
        DevTools devTools = driver.getDevTools();
        devTools.createSession();
        
        devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        devTools.addListener(Network.requestWillBeSent(), solicitud -> {
            String url = solicitud.getRequest().getUrl();
            String metodo = solicitud.getRequest().getMethod();
            System.out.println("Solicitud capturada: " + metodo + " -> " + url);
        });
        driver.get("https://ejemplo.com");
        driver.quit();
    }
}

Intercepción de Respuestas HTTP

Para analizar respuestas del servidor, escuchamos el evento Network.responseReceived. Esto permite obtener código de estado, encabezados y cuerpo de la respuesta usando Network.getResponseBody.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.RequestId;
import java.util.Optional;

public class AnalizarRespuestas {
    public static void main(String[] args) {
        ChromeDriver nav = new ChromeDriver();
        DevTools herramientas = nav.getDevTools();
        herramientas.createSession();
        herramientas.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        
        herramientas.addListener(Network.responseReceived(), respuesta -> {
            String url = respuesta.getResponse().getUrl();
            int estado = respuesta.getResponse().getStatus();
            if (url.contains("api.ejemplo.com")) {
                System.out.println("Respuesta de: " + url + " | Estado: " + estado);
                RequestId id = respuesta.getRequestId();
                String cuerpo = herramientas.send(Network.getResponseBody(id)).getBody();
                System.out.println("Cuerpo: " + cuerpo);
            }
        });
        nav.get("https://ejemplo.com/datos");
        nav.quit();
    }
}

Acceso a Logs de Consola

Los logs de consola son esenciales para depuración. Usando el comando Log.enable y un listener para Log.entryAdded, podemos capturar mensajes y niveles de log generados por la aplicación.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.log.Log;

public class CapturarLogs {
    public static void main(String[] args) {
        ChromeDriver controlador = new ChromeDriver();
        DevTools devTools = controlador.getDevTools();
        devTools.createSession();
        
        devTools.send(Log.enable());
        devTools.addListener(Log.entryAdded(), entrada -> {
            String mensaje = entrada.getText();
            String nivel = entrada.getLevel().toString();
            System.out.println("Log [" + nivel + "]: " + mensaje);
        });
        controlador.get("https://ejemplo.com/app");
        controlador.quit();
    }
}

Extracción de Métricas de Rendimiento

Para evaluar el rendimiento de carga y uso de recursos, habilitamos la captura con Performance.enable y luego obtenemos métricas como tiempo de carga, número de nodos y eventos JavaScript. Esto permite integrar verificaciones de rendimiento en suites de pruebas.

import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.performance.Performance;
import org.openqa.selenium.devtools.performance.model.Metric;
import java.util.List;

public class MedirRendimiento {
    public static void main(String[] args) {
        ChromeDriver driver = new ChromeDriver();
        DevTools herramientas = driver.getDevTools();
        herramientas.createSession();
        herramientas.send(Performance.enable());
        
        driver.get("https://ejemplo.com");
        List<Metric> metricas = herramientas.send(Performance.getMetrics());
        metricas.forEach(m -> System.out.println(m.getName() + ": " + m.getValue()));
        
        herramientas.send(Performance.disable());
        driver.quit();
    }
}

Autenticación Básica sin Pop-ups

Los diálogos de autenticación nativos no son accesibles vía Selenium DOM. Para evadir esto, establecemos encabezados HTTP de autorización con Network.setExtraHTTPHeaders después de habilitar la red. Esto permite autenticación directa sin ventannas emergentes.

import org.apache.commons.codec.binary.Base64;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.network.Network;
import org.openqa.selenium.devtools.network.model.Headers;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class AutenticarDirectamente {
    private static final String USUARIO = "admin";
    private static final String CLAVE = "secreto";

    public static void main(String[] args) {
        ChromeDriver nav = new ChromeDriver();
        DevTools devTools = nav.getDevTools();
        devTools.createSession();
        devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
        nav.get("https://ejemplo.com/seguro");
        
        Map<String, String> encabezados = new HashMap<>();
        String credenciales = USUARIO + ":" + CLAVE;
        String autenticacion = "Basic " + new String(Base64.encodeBase64(credenciales.getBytes()));
        encabezados.put("Authorization", autenticacion);
        
        devTools.send(Network.setExtraHTTPHeaders(new Headers(encabezados)));
        nav.findElement(By.linkText("Área protegida")).click();
        String contenido = nav.findElement(By.tagName("body")).getText();
        if (contenido.contains("Bienvenido")) {
            System.out.println("Autenticación exitosa.");
        }
        nav.quit();
    }
}

Estas técnicas permiten pruebas más completas y robustas al interactuar con aspectos no visibles del navegador.

Etiquetas: Selenium 4 Chrome DevTools CDP automatización web pruebas de red

Publicado el 6-11 03:00