Saltar al contenido
SDETRole
SDETRole

Aprender / Hoja de referencia

Hoja de referencia de XPath y selectores CSS

XPath y CSS lado a lado, para Selenium, Playwright y las DevTools del navegador. Usa CSS cuando pueda expresar lo que necesitas, porque es más corto y es la sintaxis que conocen los desarrolladores. Recurre a XPath cuando necesites buscar por texto visible o subir por el árbol hasta un padre o un ancestro.

Revisada con XPath 1.0 (lo que implementan los navegadores), CSS Selectors Level 4 según lo admiten las versiones actuales de Chrome, Firefox y Safari

Lo básico

ObjetivoXPathCSS
Elemento por etiqueta (en cualquier sitio) //button button
Por id //*[@id='email'] #email
Por clase (una de varias) //*[contains(concat(' ', normalize-space(@class), ' '), ' active ')] .active
Hijo directo //ul/li ul > li
Cualquier descendiente //form//input form input
Varios selectores (OR) //h1 | //h2 h1, h2
Cualquier elemento //* *

Atributos

ObjetivoXPathCSS
Tiene el atributo //button[@disabled] button[disabled]
Igual a //input[@name='q'] input[name='q']
Contiene //a[contains(@href, 'orders')] a[href*='orders']
Empieza por //a[starts-with(@href, 'https')] a[href^='https']
Termina en //a[substring(@href, string-length(@href) - 3) = '.pdf'] a[href$='.pdf']
Dos condiciones (AND) //input[@type='text' and @required] input[type='text'][required]
Una u otra condición (OR) //input[@type='email' or @type='tel'] input[type='email'], input[type='tel']
Negación //input[not(@disabled)] input:not([disabled])
Test id //*[@data-testid='submit'] [data-testid='submit']

XPath 1.0 no tiene ends-with(): la forma con substring() es la alternativa portable.

Texto (solo XPath)

ObjetivoXPathCSS
Texto exacto, espacios normalizados //button[normalize-space()='Sign in'] no es posible
El texto contiene //p[contains(., 'expired')] no es posible
Contiene, sin distinguir mayúsculas //p[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'expired')] no es posible
Solo su propio nodo de texto //label[text()='Email'] no es posible

. (el valor de cadena) incluye el texto de los elementos hijos; text() solo coincide con los nodos de texto propios del elemento. Prefiere normalize-space() o .

Relaciones y ejes

ObjetivoXPathCSS
Padre //input[@id='email']/.. :has(> #email)
Fila ancestro de una celda //td[normalize-space()='#1043']/ancestor::tr tr:has(td[data-id='1043'])
Hermano siguiente //label[.='Password']/following-sibling::input[1] label + input
Todos los hermanos siguientes //h2/following-sibling::p h2 ~ p
Hermano anterior //button/preceding-sibling::input[1] no es posible
Celda junto a una celda de etiqueta //td[.='Diego Ramos']/following-sibling::td[1] no es posible (parte del texto)
Elemento que contiene un hijo //li[.//button[@aria-label='Remove']] li:has(button[aria-label='Remove'])

:has() funciona en las versiones actuales de Chrome, Edge, Safari y Firefox (121+). Los navegadores antiguos y algunas herramientas lo rechazan.

Posición

ObjetivoXPathCSS
Primera fila hija (empieza en 1) //tbody/tr[1] tbody tr:first-child
Fila n //tbody/tr[3] tbody tr:nth-child(3)
Última fila //tbody/tr[last()] tbody tr:last-child
Penúltima //tbody/tr[last()-1] tbody tr:nth-last-child(2)
Todas las filas pares //tbody/tr[position() mod 2 = 0] tbody tr:nth-child(even)
Primera coincidencia en toda la página (//button)[1] no es posible: usa first() de tu herramienta

//tr[1] significa "cada tr que es el primer tr dentro de su padre", no "el primer tr de la página". Para eso, usa (//tr)[1].

Pseudoclases de estado (CSS)

ObjetivoXPathCSS
Checkbox o radio marcado //input[@checked] (initial state only) input:checked
Deshabilitado //button[@disabled] button:disabled
Campo obligatorio //input[@required] input:required
Elemento vacío //td[not(node())] td:empty

XPath lee los atributos tal como están escritos en el HTML, así que @checked no cambia cuando el usuario marca la casilla. :checked de CSS sigue el estado en vivo.

Pruébalos en DevTools

TareaCódigo
CSS, todas las coincidencias (Console) $$('tbody tr')
XPath, todas las coincidencias (Console) $x("//td[.='Mei Lin']")
Buscar en el panel Elements Ctrl+F / Cmd+F, then type a selector or XPath
Contar coincidencias $$('tbody tr').length

Practica y profundiza

Más hojas de referencia

Escribe para buscar en todo SDETRole.

Búsqueda de texto completo con Pagefind · se ejecuta en tu navegador Abrir la página de búsqueda →