Selenium: Localización de elementos
Aprende a localizar elementos en el DOM con Selenium para pruebas de software de interfaz de usuario UI en aplicaciones web
Aprende Selenium GRATIS y certifícateLa localización de elementos web es una habilidad fundamental en Selenium que determina en gran medida el éxito de tus pruebas automatizadas. Para interactuar con un elemento en una página web (hacer clic en un botón, ingresar texto en un campo, verificar texto visible), primero debes identificarlo de manera única y precisa.
Selenium WebDriver proporciona múltiples estrategias de localización que permiten encontrar elementos en función de sus atributos, posición en el DOM, contenido de texto y relaciones con otros elementos. La elección del método de localización adecuado es crucial para crear pruebas robustas y mantenibles.
El primer paso para localizar elementos es comprender la estructura del DOM (Document Object Model), que representa la página web como una estructura jerárquica de nodos. Cada elemento HTML en la página es un nodo con atributos, propiedades y contenido que pueden utilizarse para su identificación.
La interfaz principal para localizar elementos en Selenium es la clase By
, que encapsula las diferentes estrategias de localización disponibles:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class EstrategiasLocalizacionTests {
private WebDriver driver;
@BeforeEach
public void configurar() {
driver = new ChromeDriver();
driver.get("https://www.ejemplo.com/formulario");
}
@Test
public void demostrarEstrategiasBasicas() {
// Localizar por ID - la estrategia más eficiente
WebElement campoUsuario = driver.findElement(By.id("username"));
// Localizar por nombre - útil para campos de formulario
WebElement campoCorreo = driver.findElement(By.name("email"));
// Localizar por class name - útil para elementos con clases CSS
WebElement botonCancelar = driver.findElement(By.className("btn-cancel"));
// Verificar que los elementos fueron localizados correctamente
assertTrue(campoUsuario.isDisplayed());
assertTrue(campoCorreo.isDisplayed());
assertTrue(botonCancelar.isDisplayed());
}
@AfterEach
public void limpiar() {
if (driver != null) {
driver.quit();
}
}
}
El localizador más eficiente es generalmente By.id()
, ya que los IDs deberían ser únicos en un documento HTML bien estructurado. Sin embargo, no todos los elementos tienen IDs, y en aplicaciones generadas dinámicamente, los IDs podrían cambiar entre sesiones.
Para enlaces y elementos de texto, Selenium ofrece localizadores específicos como linkText
y partialLinkText
, que son particularmente útiles para elementos <a>
:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class LocalizacionEnlacesTests {
private WebDriver driver;
@BeforeEach
public void configurar() {
driver = new ChromeDriver();
driver.get("https://www.ejemplo.com/navegacion");
}
@Test
public void localizarEnlaces() {
// Localizar por texto exacto del enlace
WebElement enlaceContacto = driver.findElement(By.linkText("Contacto"));
enlaceContacto.click();
// Verificar navegación a la página de contacto
assertEquals("Página de Contacto", driver.getTitle());
// Volver a la página de navegación
driver.navigate().back();
// Localizar por texto parcial del enlace
WebElement enlacePolitica = driver.findElement(By.partialLinkText("Política de"));
enlacePolitica.click();
// Verificar navegación a la página de política
assertEquals("Política de Privacidad", driver.getTitle());
}
@AfterEach
public void limpiar() {
if (driver != null) {
driver.quit();
}
}
}
Los selectores CSS representan una estrategia de localización flexible que utiliza la misma sintaxis que las hojas de estilo CSS. Son más concisos que XPath y generalmente más rápidos:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class SelectoresCSSTests {
private WebDriver driver;
@BeforeEach
public void configurar() {
driver = new ChromeDriver();
driver.get("https://www.ejemplo.com/productos");
}
@Test
public void demostrarSelectoresCSS() {
// Selector básico por ID
WebElement producto = driver.findElement(By.cssSelector("#producto-destacado"));
// Selector por clase
WebElement precio = driver.findElement(By.cssSelector(".precio-oferta"));
// Combinación de selectores
WebElement botonComprar = driver.findElement(By.cssSelector("div.producto button.comprar"));
// Selector de atributos
WebElement enlaceExterno = driver.findElement(By.cssSelector("a[target='_blank']"));
// Selectores de combinación
WebElement primerLiHijo = driver.findElement(By.cssSelector("ul > li:first-child"));
WebElement tercerElemento = driver.findElement(By.cssSelector("li:nth-child(3)"));
// Verificar selectores
assertTrue(producto.isDisplayed());
assertTrue(precio.getText().contains("€"));
assertEquals("Comprar ahora", botonComprar.getText());
assertTrue(primerLiHijo.isDisplayed());
}
@AfterEach
public void limpiar() {
if (driver != null) {
driver.quit();
}
}
}
XPath es otra estrategia de localización potente que permite navegar por la estructura XML/HTML del documento. Es especialmente útil para elementos difíciles de localizar con otros métodos:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class XPathTests {
private WebDriver driver;
@BeforeEach
public void configurar() {
driver = new ChromeDriver();
driver.get("https://www.ejemplo.com/tablas");
}
@Test
public void demostrarXPath() {
// XPath absoluto (evitar en pruebas reales por fragilidad)
WebElement titulo = driver.findElement(By.xpath("/html/body/div/h1"));
// XPath relativo
WebElement tabla = driver.findElement(By.xpath("//table[@id='datos-usuarios']"));
// Localizar por contenido de texto
WebElement celdaJuan = driver.findElement(By.xpath("//td[text()='Juan García']"));
// Localizar por atributo parcial
WebElement enlace = driver.findElement(By.xpath("//a[contains(@href, 'perfil')]"));
// Localizar por relaciones de parentesco
WebElement padre = driver.findElement(By.xpath("//td[text()='Activo']/parent::tr"));
WebElement hermano = driver.findElement(By.xpath("//th[text()='Nombre']/following-sibling::th"));
// Localizar con funciones y operadores
WebElement elementoOculto = driver.findElement(By.xpath("//div[not(@class='visible')]"));
WebElement elementoConClasesMultiples = driver.findElement(
By.xpath("//div[contains(@class, 'info') and contains(@class, 'destacado')]"));
// Verificaciones
assertEquals("Tabla de Usuarios", titulo.getText());
assertTrue(tabla.isDisplayed());
assertEquals("Juan García", celdaJuan.getText());
assertEquals("Email", hermano.getText());
}
@AfterEach
public void limpiar() {
if (driver != null) {
driver.quit();
}
}
}
Una diferencia crucial en WebDriver es la distinción entre los métodos findElement()
y findElements()
. El primero devuelve el primer elemento que coincide con el localizador, mientras que el segundo devuelve una lista de todos los elementos coincidentes:
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class FindElementVsFindElementsTests {
private WebDriver driver;
@BeforeEach
public void configurar() {
driver = new ChromeDriver();
driver.get("https://www.ejemplo.com/lista");
}
@Test
public void demostrarDiferencias() {
// findElement devuelve el primer elemento que coincide
WebElement primerElemento = driver.findElement(By.cssSelector(".item"));
// findElem
Lecciones de este módulo de Selenium
Lecciones de programación del módulo Localización de elementos del curso de Selenium.