BiDi API

Avanzado
Selenium
Selenium
Actualizado: 05/09/2025

¡Desbloquea el curso de Selenium completo!

IA
Ejercicios
Certificado
Entrar

Mira la lección en vídeo

Accede al vídeo completo de esta lección y a más contenido exclusivo con el Plan Plus.

Desbloquear Plan Plus

Logging: acceso a logs de consola con BiDi

La BiDi API (Bidirectional API) representa una evolución significativa en la arquitectura de Selenium WebDriver, introduciendo un protocolo de comunicación bidireccional entre el cliente y el navegador. A diferencia del protocolo tradicional basado en HTTP, BiDi permite que tanto el cliente como el navegador inicien comunicaciones, habilitando funcionalidades avanzadas como la monitorización en tiempo real de eventos del navegador.

Esta arquitectura bidireccional resulta especialmente valiosa para acceder a logs de consola, ya que permite recibir eventos de logging de forma asíncrona sin necesidad de realizar consultas periódicas al navegador. Los logs de consola incluyen mensajes generados por JavaScript, errores, advertencias y otra información de diagnóstico que resulta crucial para la depuración y el análisis de aplicaciones web.

Configuración inicial para BiDi

Para utilizar la funcionalidad de logging con BiDi, es necesario configurar el driver con las capacidades adecuadas. El navegador debe soportar el protocolo WebDriver BiDi, siendo Chrome y Firefox los navegadores que ofrecen mejor compatibilidad actualmente.

@Test
void configurarDriverParaBiDi() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    WebDriver driver = new ChromeDriver(options);
    
    // El driver está ahora configurado para BiDi
    driver.get("https://ejemplo.com");
    
    driver.quit();
}

La configuración establece la conexión WebSocket necesaria para la comunicación bidireccional, permitiendo que el navegador envíe eventos de logging de forma proactiva al cliente de Selenium.

Acceso a logs de consola con LogInspector

El LogInspector es la interfaz principal para trabajar con logs de consola en BiDi. Esta clase proporciona métodos para suscribirse a diferentes tipos de eventos de logging y procesar los mensajes de forma asíncrona.

@Test
void capturarLogsDeConsola() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        LogInspector logInspector = new LogInspector(driver);
        
        // Lista para almacenar los logs capturados
        List<ConsoleLogEntry> consoleLogs = new ArrayList<>();
        
        // Suscribirse a logs de consola
        logInspector.onConsoleEntry(consoleLogs::add);
        
        // Navegar a una página que genere logs
        driver.get("data:text/html,<script>console.log('Mensaje de prueba');</script>");
        
        // Verificar que se capturó el log
        assertThat(consoleLogs)
            .isNotEmpty()
            .extracting(ConsoleLogEntry::getText)
            .contains("Mensaje de prueba");
    }
}

Filtrado de logs por nivel

Los logs de consola se generan con diferentes niveles de severidad, desde información general hasta errores críticos. BiDi permite filtrar estos logs según su nivel, facilitando el enfoque en los mensajes más relevantes para cada escenario de prueba.

@Test
void filtrarLogsPorNivel() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        LogInspector logInspector = new LogInspector(driver);
        
        List<ConsoleLogEntry> errorLogs = new ArrayList<>();
        List<ConsoleLogEntry> warningLogs = new ArrayList<>();
        
        // Filtrar solo errores
        logInspector.onConsoleEntry(entry -> {
            if (entry.getLevel() == Level.SEVERE) {
                errorLogs.add(entry);
            } else if (entry.getLevel() == Level.WARNING) {
                warningLogs.add(entry);
            }
        });
        
        // Generar diferentes tipos de logs
        driver.get("""
            data:text/html,
            <script>
                console.error('Error crítico');
                console.warn('Advertencia importante');
                console.log('Información general');
            </script>
            """);
        
        // Verificar filtrado
        assertThat(errorLogs).hasSize(1);
        assertThat(warningLogs).hasSize(1);
    }
}

Procesamiento asíncrono de logs

Una de las principales ventajas de BiDi es la capacidad de procesar logs de forma asíncrona, permitiendo que las pruebas reaccionen inmediatamente a eventos de logging sin bloquear la ejecución del test.

@Test
void procesarLogsAsincrono() throws InterruptedException {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        LogInspector logInspector = new LogInspector(driver);
        CountDownLatch latch = new CountDownLatch(3);
        
        // Procesar logs de forma asíncrona
        logInspector.onConsoleEntry(entry -> {
            System.out.println("Log recibido: " + entry.getText());
            latch.countDown();
        });
        
        // Ejecutar JavaScript que genera múltiples logs
        driver.get("""
            data:text/html,
            <script>
                setTimeout(() => console.log('Log 1'), 100);
                setTimeout(() => console.log('Log 2'), 200);
                setTimeout(() => console.log('Log 3'), 300);
            </script>
            """);
        
        // Esperar a que se procesen todos los logs
        assertTrue(latch.await(5, TimeUnit.SECONDS));
    }
}

Análisis de logs para depuración

Los logs de consola capturados con BiDi proporcionan información valiosa para la depuración de aplicaciones web. Incluyen detalles como el momento exacto del evento, el contexto de ejecución y metadatos adicionales que facilitan el diagnóstico de problemas.

@Test
void analizarDetallesDelLog() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        LogInspector logInspector = new LogInspector(driver);
        
        List<ConsoleLogEntry> detailedLogs = new ArrayList<>();
        
        logInspector.onConsoleEntry(entry -> {
            // Capturar detalles completos del log
            detailedLogs.add(entry);
            
            // Mostrar información detallada
            System.out.printf("""
                Timestamp: %s
                Nivel: %s
                Mensaje: %s
                Fuente: %s
                """, 
                entry.getTimestamp(),
                entry.getLevel(),
                entry.getText(),
                entry.getSource()
            );
        });
        
        driver.get("data:text/html,<script>console.error('Error con contexto');</script>");
        
        // Verificar que se capturaron los detalles
        assertThat(detailedLogs)
            .hasSize(1)
            .first()
            .satisfies(entry -> {
                assertThat(entry.getTimestamp()).isNotNull();
                assertThat(entry.getLevel()).isEqualTo(Level.SEVERE);
                assertThat(entry.getText()).contains("Error con contexto");
            });
    }
}

El acceso a logs de consola mediante BiDi transforma la capacidad de monitorización y depuración en las pruebas automatizadas, proporcionando visibilidad en tiempo real sobre el comportamiento interno de las aplicaciones web y permitiendo una detección más temprana de problemas potenciales.

Interceptar peticiones de red

Guarda tu progreso

Inicia sesión para no perder tu progreso y accede a miles de tutoriales, ejercicios prácticos y nuestro asistente de IA.

Progreso guardado
Asistente IA
Ejercicios
Iniciar sesión gratis

Más de 25.000 desarrolladores ya confían en CertiDevs

La interceptación de peticiones de red mediante BiDi API permite monitorizar, modificar y controlar el tráfico HTTP entre la aplicación web y los servidores remotos. Esta funcionalidad resulta fundamental para validar comportamientos de red, simular condiciones específicas y verificar que las aplicaciones manejen correctamente las respuestas del servidor.

El NetworkInspector proporciona la interfaz principal para trabajar con eventos de red, permitiendo acceder a información detallada sobre requests, responses, y el estado de las conexiones de forma asíncrona.

Configuración del NetworkInspector

Para interceptar peticiones de red, es necesario inicializar el NetworkInspector con las capacidades BiDi habilitadas. Este componente se suscribe automáticamente a los eventos de red del navegador, proporcionando acceso completo al tráfico HTTP.

@Test
void configurarInterceptorDeRed() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        NetworkInspector networkInspector = new NetworkInspector(driver);
        
        // Lista para almacenar peticiones interceptadas
        List<HttpRequest> requests = new ArrayList<>();
        List<HttpResponse> responses = new ArrayList<>();
        
        // Suscribirse a eventos de red
        networkInspector.onRequestSent(requests::add);
        networkInspector.onResponseReceived(responses::add);
        
        // Navegar a una página que genere tráfico de red
        driver.get("https://httpbin.org/json");
        
        // Verificar que se interceptaron las peticiones
        assertThat(requests).isNotEmpty();
        assertThat(responses).isNotEmpty();
    }
}

Monitorización de peticiones HTTP

La monitorización de peticiones permite examinar todos los aspectos de las comunicaciones HTTP, incluyendo métodos, headers, URLs y payloads. Esta información resulta crucial para verificar que la aplicación realiza las peticiones esperadas con los parámetros correctos.

@Test
void monitorizarPeticionesHTTP() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        NetworkInspector networkInspector = new NetworkInspector(driver);
        
        List<HttpRequest> apiRequests = new ArrayList<>();
        
        // Filtrar solo peticiones a APIs
        networkInspector.onRequestSent(request -> {
            String url = request.getUrl();
            if (url.contains("/api/") || url.contains("httpbin.org")) {
                apiRequests.add(request);
                
                // Mostrar detalles de la petición
                System.out.printf("""
                    Método: %s
                    URL: %s
                    Headers: %s
                    """,
                    request.getMethod(),
                    request.getUrl(),
                    request.getHeaders()
                );
            }
        });
        
        // Ejecutar JavaScript que realiza peticiones AJAX
        driver.get("data:text/html,<script>fetch('https://httpbin.org/get?test=123');</script>");
        
        // Verificar características de la petición
        assertThat(apiRequests)
            .hasSize(1)
            .first()
            .satisfies(request -> {
                assertThat(request.getMethod()).isEqualTo("GET");
                assertThat(request.getUrl()).contains("test=123");
            });
    }
}

Análisis de respuestas HTTP

El análisis de respuestas HTTP proporciona acceso completo a los datos devueltos por el servidor, incluyendo códigos de estado, headers de respuesta y contenido del body. Esta información permite validar que la aplicación recibe y procesa correctamente las respuestas del servidor.

@Test
void analizarRespuestasHTTP() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        NetworkInspector networkInspector = new NetworkInspector(driver);
        
        List<HttpResponse> successResponses = new ArrayList<>();
        List<HttpResponse> errorResponses = new ArrayList<>();
        
        // Clasificar respuestas por código de estado
        networkInspector.onResponseReceived(response -> {
            int statusCode = response.getStatusCode();
            
            if (statusCode >= 200 && statusCode < 300) {
                successResponses.add(response);
            } else if (statusCode >= 400) {
                errorResponses.add(response);
            }
            
            // Log detallado de la respuesta
            System.out.printf("""
                Status: %d
                Content-Type: %s
                Response Time: %d ms
                """,
                response.getStatusCode(),
                response.getHeaders().get("content-type"),
                response.getTimestamp() - response.getRequest().getTimestamp()
            );
        });
        
        driver.get("https://httpbin.org/status/404");
        
        // Verificar clasificación de respuestas
        assertThat(errorResponses)
            .hasSize(1)
            .first()
            .satisfies(response -> {
                assertThat(response.getStatusCode()).isEqualTo(404);
            });
    }
}

Interceptación y modificación de peticiones

Una funcionalidad avanzada de BiDi es la capacidad de modificar peticiones en tiempo real antes de que alcancen el servidor. Esto permite simular diferentes escenarios, añadir headers de autenticación o modificar parámetros de consulta.

@Test
void modificarPeticionesEnTiempoReal() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        NetworkInspector networkInspector = new NetworkInspector(driver);
        
        // Interceptar y modificar peticiones
        networkInspector.onRequestWillBeSent((request, continueWith) -> {
            // Añadir header de autenticación
            Map<String, String> modifiedHeaders = new HashMap<>(request.getHeaders());
            modifiedHeaders.put("Authorization", "Bearer test-token");
            modifiedHeaders.put("X-Custom-Header", "Modified-Value");
            
            // Continuar con la petición modificada
            continueWith.with(request.toBuilder()
                .setHeaders(modifiedHeaders)
                .build());
        });
        
        List<HttpRequest> modifiedRequests = new ArrayList<>();
        networkInspector.onRequestSent(modifiedRequests::add);
        
        driver.get("https://httpbin.org/headers");
        
        // Verificar que se añadieron los headers
        assertThat(modifiedRequests)
            .hasSize(1)
            .first()
            .satisfies(request -> {
                assertThat(request.getHeaders())
                    .containsKey("Authorization")
                    .containsKey("X-Custom-Header");
            });
    }
}

Simulación de fallos de red

La simulación de fallos de red permite probar cómo la aplicación maneja condiciones adversas como timeouts, errores de conectividad o respuestas malformadas. BiDi facilita la creación de estos escenarios de prueba sin necesidad de herramientas externas.

@Test
void simularFallosDeRed() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        NetworkInspector networkInspector = new NetworkInspector(driver);
        
        List<String> failedRequests = new ArrayList<>();
        
        // Interceptar peticiones específicas y simular fallos
        networkInspector.onRequestWillBeSent((request, continueWith) -> {
            String url = request.getUrl();
            
            if (url.contains("/api/data")) {
                // Simular error de red
                failedRequests.add(url);
                continueWith.withError(NetworkError.CONNECTION_REFUSED);
            } else {
                // Permitir otras peticiones
                continueWith.proceed();
            }
        });
        
        // Ejecutar JavaScript que maneja errores de red
        driver.get("""
            data:text/html,
            <script>
                fetch('/api/data')
                    .catch(error => console.error('Network error:', error));
            </script>
            """);
        
        // Verificar que se simuló el fallo
        assertThat(failedRequests).contains("/api/data");
    }
}

Validación de performance de red

La interceptación de red también permite realizar análisis de performance, midiendo tiempos de respuesta, tamaños de payload y identificando cuellos de botella en las comunicaciones HTTP.

@Test
void validarPerformanceDeRed() {
    ChromeOptions options = new ChromeOptions();
    options.setCapability("webSocketUrl", true);
    
    try (WebDriver driver = new ChromeDriver(options)) {
        NetworkInspector networkInspector = new NetworkInspector(driver);
        
        Map<String, Long> responseTimes = new ConcurrentHashMap<>();
        Map<String, Integer> responseSizes = new ConcurrentHashMap<>();
        
        // Medir métricas de performance
        networkInspector.onResponseReceived(response -> {
            String url = response.getRequest().getUrl();
            long responseTime = response.getTimestamp() - response.getRequest().getTimestamp();
            int contentLength = response.getHeaders().containsKey("content-length") 
                ? Integer.parseInt(response.getHeaders().get("content-length")) 
                : 0;
            
            responseTimes.put(url, responseTime);
            responseSizes.put(url, contentLength);
        });
        
        driver.get("https://httpbin.org/delay/1");
        
        // Validar métricas de performance
        assertThat(responseTimes.values())
            .allSatisfy(time -> assertThat(time).isGreaterThan(1000)); // Mínimo 1 segundo por el delay
            
        assertThat(responseSizes.values())
            .allSatisfy(size -> assertThat(size).isGreaterThan(0));
    }
}

La interceptación de peticiones de red con BiDi API proporciona un control granular sobre las comunicaciones HTTP, permitiendo crear pruebas más robustas que validen tanto el comportamiento funcional como el rendimiento de las aplicaciones web en diferentes condiciones de red.

Aprendizajes de esta lección de Selenium

  • Comprender la arquitectura bidireccional de la BiDi API y su ventaja frente al protocolo HTTP tradicional.
  • Configurar el driver de Selenium para habilitar la comunicación BiDi mediante WebSocket.
  • Capturar, filtrar y procesar logs de consola de forma asíncrona usando LogInspector.
  • Interceptar, monitorizar y modificar peticiones y respuestas HTTP con NetworkInspector.
  • Simular fallos de red y analizar métricas de rendimiento para pruebas avanzadas de aplicaciones web.

Completa este curso de Selenium y certifícate

Únete a nuestra plataforma de cursos de programación y accede a miles de tutoriales, ejercicios prácticos, proyectos reales y nuestro asistente de IA personalizado para acelerar tu aprendizaje.

Asistente IA

Resuelve dudas al instante

Ejercicios

Practica con proyectos reales

Certificados

Valida tus conocimientos

Más de 25.000 desarrolladores ya se han certificado con CertiDevs

⭐⭐⭐⭐⭐
4.9/5 valoración