Selectores XPath

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

XPath básico

XPath (XML Path Language) es un lenguaje de consulta que permite navegar y seleccionar nodos en documentos HTML y XML. En el contexto de Selenium WebDriver, XPath se convierte en una herramienta fundamental para localizar elementos web de manera precisa y flexible.

La sintaxis XPath utiliza una estructura similar a las rutas de archivos en sistemas operativos, donde cada nivel del DOM se representa mediante barras inclinadas. Esta aproximación permite construir expresiones que describen la ubicación exacta de un elemento dentro de la estructura jerárquica del documento.

Diferencias entre XPath absoluto y relativo

XPath absoluto define la ruta completa desde la raíz del documento hasta el elemento objetivo. Esta aproximación comienza siempre con una barra inclinada simple (/) y especifica cada nivel del DOM:

@Test
void ejemploXPathAbsoluto() {
    WebElement elemento = driver.findElement(By.xpath("/html/body/div[1]/form/input[2]"));
    elemento.sendKeys("Texto de prueba");
}

Sin embargo, esta técnica presenta limitaciones significativas en entornos de desarrollo ágiles. Cualquier modificación en la estructura HTML invalida completamente el selector, generando pruebas frágiles y difíciles de mantener.

XPath relativo ofrece una alternativa más robusta mediante el uso de doble barra inclinada (//). Esta sintaxis permite localizar elementos independientemente de su posición exacta en el DOM:

@Test
void ejemploXPathRelativo() {
    WebElement elemento = driver.findElement(By.xpath("//input[@type='email']"));
    elemento.click();
}

Navegación básica con barras inclinadas

La navegación descendente utiliza la barra inclinizada simple (/) para seleccionar hijos directos de un nodo:

@Test
void navegacionDescendente() {
    // Selecciona el primer párrafo dentro de un div específico
    WebElement parrafo = driver.findElement(By.xpath("//div[@class='content']/p"));
    
    String texto = parrafo.getText();
    assertThat(texto).isNotEmpty();
}

La navegación en cualquier descendiente emplea la doble barra (//) para buscar elementos en cualquier nivel de profundidad:

@Test
void navegacionCualquierDescendiente() {
    // Localiza un botón en cualquier lugar dentro de un formulario
    WebElement boton = driver.findElement(By.xpath("//form//button[@type='submit']"));
    boton.click();
}

Selección por atributos

Los corchetes ([]) permiten aplicar filtros basados en atributos o posición. La sintaxis @atributo accede directamente a las propiedades de los elementos:

@Test
void seleccionPorAtributos() {
    // Localiza por ID
    WebElement porId = driver.findElement(By.xpath("//input[@id='usuario']"));
    
    // Localiza por clase CSS  
    WebElement porClase = driver.findElement(By.xpath("//div[@class='mensaje-error']"));
    
    // Localiza por atributo personalizado
    WebElement porDataAttr = driver.findElement(By.xpath("//button[@data-action='guardar']"));
}

Funciones de texto básicas

La función **text()** permite localizar elementos basándose en su contenido textual exacto:

@Test
void localizacionPorTexto() {
    // Localiza un enlace por su texto exacto
    WebElement enlace = driver.findElement(By.xpath("//a[text()='Iniciar sesión']"));
    enlace.click();
    
    // Localiza un encabezado específico
    WebElement titulo = driver.findElement(By.xpath("//h2[text()='Panel de control']"));
    assertThat(titulo.isDisplayed()).isTrue();
}

La función **contains()** ofrece mayor flexibilidad al permitir coincidencias parciales en texto y atributos:

@Test
void localizacionConContains() {
    // Busca elementos que contengan texto parcial
    WebElement boton = driver.findElement(By.xpath("//button[contains(text(), 'Confirmar')]"));
    
    // Filtra por clases CSS que contengan una palabra específica
    WebElement elemento = driver.findElement(By.xpath("//div[contains(@class, 'activo')]"));
    
    // Combina múltiples condiciones
    WebElement input = driver.findElement(
        By.xpath("//input[contains(@placeholder, 'correo') and @type='email']")
    );
}

Selección por posición

Los índices numéricos dentro de los corchetes permiten seleccionar elementos específicos cuando existen múltiples coincidencias:

@Test
void seleccionPorPosicion() {
    // Selecciona el primer elemento de una lista
    WebElement primerItem = driver.findElement(By.xpath("//ul/li[1]"));
    
    // Selecciona el tercer párrafo de un artículo
    WebElement tercerParrafo = driver.findElement(By.xpath("//article/p[3]"));
    
    // Obtiene todos los elementos y selecciona uno específico
    List<WebElement> opciones = driver.findElements(By.xpath("//select/option"));
    WebElement segundaOpcion = opciones.get(1); // Índice basado en 0
}

Combinación de criterios

La versatilidad de XPath permite combinar múltiples criterios de selección para localizar elementos con mayor precisión:

@Test
void criteriosCombinados() {
    // Combina atributo y posición
    WebElement elemento = driver.findElement(
        By.xpath("//table[@id='datos']/tbody/tr[2]/td[@class='precio']")
    );
    
    // Utiliza múltiples condiciones con operadores lógicos
    WebElement input = driver.findElement(
        By.xpath("//input[@type='text' and @required and contains(@name, 'usuario')]")
    );
    
    // Selecciona elementos hermanos específicos
    WebElement hermano = driver.findElement(
        By.xpath("//label[text()='Email']/following-sibling::input")
    );
}

Esta sintaxis fundamental de XPath proporciona las herramientas necesarias para localizar elementos web de manera efectiva. La comprensión de estos conceptos básicos establece la base sólida para técnicas más avanzadas de selección y navegación en el DOM.

XPath avanzado

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 sintaxis avanzada de XPath extiende las capacidades básicas de localización mediante técnicas sofisticadas que permiten navegar con precisión por estructuras DOM complejas. Estas técnicas resultan especialmente valiosas cuando los selectores básicos no proporcionan la especificidad necesaria para identificar elementos únicos.

Ejes de navegación (Axes)

Los ejes XPath definen la dirección de navegación desde un nodo de contexto hacia otros nodos relacionados en el árbol DOM. Esta funcionalidad permite localizar elementos basándose en su relación estructural rather than en su posición absoluta.

El eje **parent** navega hacia el elemento contenedor directo:

@Test
void navegacionPadre() {
    // Localiza el formulario que contiene un input específico
    WebElement formulario = driver.findElement(
        By.xpath("//input[@id='email']/parent::form")
    );
    
    // Verifica que el formulario tenga la clase correcta
    assertThat(formulario.getAttribute("class")).contains("login-form");
}

El eje **child** selecciona elementos hijos directos, ofreciendo mayor precisión que la barra inclinada simple:

@Test
void navegacionHijo() {
    // Selecciona solo los párrafos que son hijos directos
    List<WebElement> parrafosDirectos = driver.findElements(
        By.xpath("//article/child::p")
    );
    
    // Localiza el primer botón hijo de un div específico
    WebElement primerBoton = driver.findElement(
        By.xpath("//div[@class='actions']/child::button[1]")
    );
}

Los ejes **following-sibling** y **preceding-sibling** navegan entre elementos hermanos:

@Test
void navegacionHermanos() {
    // Localiza el input que sigue a una etiqueta específica
    WebElement inputPassword = driver.findElement(
        By.xpath("//label[text()='Contraseña']/following-sibling::input")
    );
    
    // Encuentra el elemento anterior a un botón específico
    WebElement elementoPrevio = driver.findElement(
        By.xpath("//button[@type='submit']/preceding-sibling::input")
    );
    
    inputPassword.sendKeys("password123");
}

Los ejes **following** y **preceding** extienden la búsqueda a todos los elementos que aparecen después o antes en el documento:

@Test
void navegacionDocumento() {
    // Localiza el primer enlace que aparece después de un encabezado
    WebElement enlaceSiguiente = driver.findElement(
        By.xpath("//h2[text()='Productos']/following::a[1]")
    );
    
    // Encuentra un elemento de error que precede a un formulario
    WebElement mensajeError = driver.findElement(
        By.xpath("//form[@id='registro']/preceding::div[@class='error'][1]")
    );
}

Operadores lógicos avanzados

Los operadores lógicos permiten construir expresiones XPath complejas combinando múltiples condiciones de manera eficiente.

El operador **and** requiere que todas las condiciones se cumplan simultáneamente:

@Test
void operadorAnd() {
    // Localiza inputs que cumplan múltiples criterios
    WebElement inputComplejo = driver.findElement(
        By.xpath("//input[@type='text' and @required and contains(@class, 'validate')]")
    );
    
    // Combina condiciones de texto y atributos
    WebElement botonEspecifico = driver.findElement(
        By.xpath("//button[contains(text(), 'Enviar') and @disabled='false']")
    );
}

El operador **or** permite que cualquiera de las condiciones sea verdadera:

@Test
void operadorOr() {
    // Localiza elementos con diferentes tipos de input
    WebElement campoTexto = driver.findElement(
        By.xpath("//input[@type='email' or @type='text' or @type='tel']")
    );
    
    // Busca botones con diferentes textos posibles
    WebElement botonAccion = driver.findElement(
        By.xpath("//button[text()='Guardar' or text()='Actualizar' or text()='Crear']")
    );
}

El operador **not** excluye elementos que coincidan con la condición especificada:

@Test
void operadorNot() {
    // Selecciona inputs que no estén deshabilitados
    List<WebElement> inputsActivos = driver.findElements(
        By.xpath("//input[not(@disabled)]")
    );
    
    // Localiza divs que no contengan una clase específica
    WebElement divSinClase = driver.findElement(
        By.xpath("//div[not(contains(@class, 'hidden'))]")
    );
    
    assertThat(inputsActivos).hasSizeGreaterThan(0);
}

Funciones de posición avanzadas

Las funciones de posición proporcionan capacidades sofisticadas para seleccionar elementos basándose en su ubicación relativa dentro de conjuntos de elementos similares.

La función **position()** devuelve la posición numérica de un elemento dentro de su contexto:

@Test
void funcionPosition() {
    // Selecciona elementos en posiciones pares
    List<WebElement> filasPares = driver.findElements(
        By.xpath("//table/tbody/tr[position() mod 2 = 0]")
    );
    
    // Localiza elementos después de la tercera posición
    WebElement cuartoElemento = driver.findElement(
        By.xpath("//ul/li[position() > 3][1]")
    );
    
    assertThat(filasPares).isNotEmpty();
}

La función **last()** identifica el último elemento de un conjunto:

@Test
void funcionLast() {
    // Selecciona el último elemento de una lista
    WebElement ultimoItem = driver.findElement(
        By.xpath("//nav/ul/li[last()]")
    );
    
    // Localiza el penúltimo párrafo de un artículo
    WebElement penultimoParrafo = driver.findElement(
        By.xpath("//article/p[last()-1]")
    );
    
    ultimoItem.click();
}

Combinación de funciones de posición para selecciones precisas:

@Test
void posicionesComplejas() {
    // Selecciona los tres primeros elementos de cada sección
    List<WebElement> primerosTres = driver.findElements(
        By.xpath("//section//li[position() <= 3]")
    );
    
    // Localiza elementos en el rango central
    WebElement elementoCentral = driver.findElement(
        By.xpath("//table/tbody/tr[position() > 2 and position() < last()-1]")
    );
}

XPath dinámico con variables

El XPath dinámico permite construir selectores adaptables que responden a condiciones cambiantes durante la ejecución de las pruebas.

Construcción de XPath con concatenación de cadenas:

@Test
void xpathDinamico() {
    String tipoInput = "email";
    String valorPlaceholder = "usuario@ejemplo.com";
    
    // Construye XPath dinámicamente
    String xpathDinamico = String.format(
        "//input[@type='%s' and contains(@placeholder, '%s')]", 
        tipoInput, valorPlaceholder
    );
    
    WebElement inputDinamico = driver.findElement(By.xpath(xpathDinamico));
    inputDinamico.clear();
}

Uso de variables para selección condicional:

@Test
void seleccionCondicional() {
    boolean modoOscuro = true;
    String claseEsperada = modoOscuro ? "dark-theme" : "light-theme";
    
    WebElement contenedor = driver.findElement(
        By.xpath("//div[contains(@class, '" + claseEsperada + "')]")
    );
    
    // Adapta la selección según el estado de la aplicación
    String estadoBoton = contenedor.getAttribute("data-state");
    String xpathCondicional = estadoBoton.equals("active") 
        ? "//button[@data-action='pause']"
        : "//button[@data-action='play']";
        
    WebElement botonControl = driver.findElement(By.xpath(xpathCondicional));
    botonControl.click();
}

Optimización y consideraciones de rendimiento

El rendimiento de XPath puede impactar significativamente en la velocidad de ejecución de las pruebas, especialmente en aplicaciones con DOM complejos.

Técnicas de optimización:

  • Evita expresiones que comiencen con **//** cuando sea posible, utilizando selectores más específicos:
@Test
void optimizacionRendimiento() {
    // Menos eficiente: búsqueda en todo el documento
    // WebElement elemento = driver.findElement(By.xpath("//input[@type='email']"));
    
    // Más eficiente: limita el alcance de búsqueda
    WebElement formulario = driver.findElement(By.xpath("//form[@id='login']"));
    WebElement input = formulario.findElement(By.xpath(".//input[@type='email']"));
}
  • Utiliza índices específicos en lugar de funciones cuando la posición es conocida:
@Test
void indicesEspecificos() {
    // Más eficiente para elementos en posiciones conocidas
    WebElement segundoItem = driver.findElement(By.xpath("//ul/li[2]"));
    
    // Reserva last() para casos donde la posición final es incierta
    WebElement ultimoItem = driver.findElement(By.xpath("//ul/li[last()]"));
}
  • Combina XPath con otros localizadores para maximizar la eficiencia:
@Test
void combinacionLocalizadores() {
    // Localiza el contenedor por ID (más rápido)
    WebElement contenedor = driver.findElement(By.id("productos"));
    
    // Utiliza XPath relativo dentro del contenedor
    WebElement producto = contenedor.findElement(
        By.xpath(".//div[@data-price > 100]/button[contains(text(), 'Comprar')]")
    );
}

Estas técnicas avanzadas de XPath proporcionan un arsenal completo para abordar los desafíos más complejos de localización de elementos en aplicaciones web modernas. La combinación estratégica de ejes, operadores lógicos y funciones de posición permite crear selectores robustos y mantenibles que se adaptan a las necesidades específicas de cada escenario de prueba.

Web Inspector

Si tenemos problemas a la hora de crear un xpath, podemos utilizar herramientas como Web Inspector de IntelliJ IDEA ayudan a validar la sintaxis xpath contra interfaces de usuario concretas>

Incluso la propia terminal del navegador permite el uso de selectores xpath y es capaz de indicarnos cuántos elementos ha detectado para nuestra sintaxis xpath.

Aprendizajes de esta lección de Selenium

  • Comprender la diferencia entre XPath absoluto y relativo y su impacto en la robustez de las pruebas.
  • Aprender a navegar por el DOM utilizando barras inclinadas y ejes XPath para seleccionar nodos específicos.
  • Utilizar funciones y operadores lógicos para construir expresiones XPath complejas y precisas.
  • Aplicar técnicas avanzadas como funciones de posición y XPath dinámico para adaptarse a estructuras DOM complejas.
  • Conocer buenas prácticas y estrategias de optimización para mejorar el rendimiento en la localización de elementos con XPath.

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