¿Alguien puede ayudarme a usar contains en mi xpath? Mi xpath cambia todo el tiempo cuando se agregan usuarios, por lo que no puedo encontrar el elemento utilizando xpath.
Este es mi xpath:
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[9]/td/table/tbody/tr/td[1]/strong[2]
Cambios cuando se agrega un nuevo usuario:
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[10]/td/table/tbody/tr/td[1]/strong[2]
Por favor, ayúdenme a hacerlo.
Comentarios
- Comparte tu HTML y el elemento que estás tratando de localizar.
Responder
He probado una aplicación ExtJS. La mayoría de los atributos de los elementos de la página son dinámicos. Cambian no solo cuando agregas un nuevo usuario o algo, cambian cada vez que abres la aplicación.
He encontrado las expresiones xpath que obtengo de las herramientas (Firebug, etc.) no son muy útiles. He aquí por qué:
- difícil de leer
- se rompe fácilmente
- difícil de depurar
Lo que hago en su lugar es dedicar tiempo a mirar el HTML e identificar posibles atributos únicos que no son dinámicos y generar mis propias expresiones. Si ninguna de las los atributos son stati c para un determinado elemento, use cualquier otro elemento en la página que tenga atributos estáticos con las relaciones padre / hijo / hermano para localizar.
A menudo uso «contiene», pero hay más. A continuación, se muestran algunos ejemplos:
- condición múltiple:
//div[@class="bubble-title" and contains(text(), "Cover")]
- coincidencia parcial:
//span[contains(text(), "Assign Rate")]
- empieza con:
//input[starts-with(@id,"reportcombo")]
- el valor tiene espacios:
//div[./div/div[normalize-space(.)="More Actions..."]]
- hermano:
//td[.="LoadType"]/following-sibling::td[1]/select"
- más complejo:
//td[contains(normalize-space(@class), "actualcell sajcell-row-lines saj-special x-grid-row-collapsed")]
Eche un vistazo a la página de Funciones XSL de W3C para obtener más ideas.
Editar: Enlace actualizado. Edición 2: XPATH cambiado
Comentarios
- ¡Excelentes ejemplos! ‘ uso métodos similares para automatizar una aplicación JSF con muchos formularios dinámicos. ‘ he encontrado la especificación W3C muy útil .
- Qué placer saber que ¡Alguien ha recorrido el mismo camino! ¡Gracias!
- El enlace de la especificación W3C anterior no funciona ahora. En su lugar, consulte esta página .
Respuesta
Debería dividir el xpath para buscar tablas individuales en aras de la claridad.
Sugiero lo siguiente:
// Get the content or container WebElement content = driver.findElement(By.id("contentText")); //Get the table of users WebElement tblUsers = content.findElement(By.xpath(".//table/tbody/tr[2]/td/table/tbody/tr/td[1]/table")); // Get the rows which change always as and when users are added WebElement allUsers = tblUsers.findElements(By.xpath(".//tbody/tr")); // Loop through each row of users table for(WebElement user : allUsers) { // Get the username WebElement username = user.findElement(By.xpath(".//td/table/tbody/tr/td[1]/strong[2]")); System.out.println("Username: " + username.getText()); }
Comentarios
- esto no ‘ realmente proporciona ningún ejemplo sobre cómo usar
contains
Respuesta
Podemos usar algo como
By.xpath("//td[contains(text(),"youruser")]") //here user text is case sensitive
By.xpath("//td[contains(lower-case(text()),"youruser")]") //to handle case sensitivity. Here user is not case sensitive
Responder
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr[10]/td/table/tbody/tr/td[1]/strong[2]
Ese XPath debería acortarse drásticamente. Es probable que falle si está probando en diferentes navegadores y si algo cambia en la página, podría arrojar un falso positivo debido a que está mirando el elemento incorrecto. Recomiendo buscar «XPath relativos» y también «Ejes XPath», pero podría demostrarle un XPath mejor si publicara una captura de pantalla del HTML y la página web.
Según lo que publicó, podría hacer algo como: //table[@id ="something"
o @class="Something that identifies this specific table"]//tr[contains(text(), "something to identify the row")
o ./text() = "Exact Text Match"]//strong[2]
Por lo general, con las filas de la tabla termino identificando la fila en función del texto de una celda dentro de la fila. //table[@id ="something"
o @class="Something that identifies this specific table"]//tr[.//td[contains(text(), "something to identify the row")
o ./text() = "Exact Text Match"]]//td//strong[2][contains(text(), "Partial Text Match")
o ./text() = "Exact Text Match"]
Respuesta
Pruebe el siguiente código:
public List<WebElement> getText(String xpath) throws Exception { return driver.findElements(By.xpath(xpath)).getText(); } if(tool.getText("//\*[@id="contentText"]//\*/table//\*/strong").contains("<yourtext>")) { system.out.println("Your text is available in the particular xpath"); } else { system.out.println("Your text is not available in the particular xpath"); }
Me está funcionando bien. Puedo encontrar cualquier texto en cualquier xpath usando el código anterior.
Respuesta
El 2 de su XPath cambia de tr[9]
a tr[10]
. Parece que el número de la 3ª «tr» significa número de usuario.
En mi práctica, eliminar ese número puede extraer todos los datos de los usuarios de HTML. (probado por RSelenium + rvest):
.//*[@id="contentText"]/table/tbody/tr[2]/td/table/tbody/tr/td[1]/table/tbody/tr/td/table/tbody/tr/td[1]/strong[2]
Respuesta
Aunque ya hay muchas respuestas, también puede consultar los siguientes enlaces:
Respuesta
XPATH
driver.findElement(By.xpath("/html/body/div/input[1]")).sendKeys("123"); driver.findElement(By.xpath("//input[1]")).click(); driver.findElement(By.xpath("(//input[1])[4])")).click(); driver.findElement(By.xpath("//tag[@AN="AV"]")).sendKeys("123"); driver.findElement(By.xpath("//tag[text()="AV"]")).sendKeys("123"); driver.findElement(By.xpath("//tag[@AN="AV" and @AN="AV"]")).click(); driver.findElement(By.xpath("//tag[contains(text(),"usrn")]").getText(); driver.findElement(By.xpath("//tag[contains(@AN,"usrn")]").getText(); driver.findElement(By.xpath("//tag[starts-with(text(),"usrn")]").getText(); driver.findElement(By.xpath("//tag[starts-with(@AN,"usrn")]").getText(); ex : //input[starts-with(@id,"reportcombo")]