J'ai une table avec 9 lignes et 6 colonnes dans ma page Web. Je veux rechercher un texte "MakeGoodDisabled-Programwise_09_44_38_461 (n)" et obtenir le xpath de la cellule. J'ai utilisé ce qui suit mais cela échoue car il ne parvient pas à trouver le texte dans la page. Peux-tu aider s'il te plait? J'utilise Selenium Webdriver Junit pour coder ceci.
`List<WebElement> links = driver.findElements(By.tagName("td"));
Iterator<WebElement> itr = links.iterator();
while(itr.hasNext()){
String test = itr.next().getText();
if(test.equals("MakeGoodDisabled-Programwise_09_44_38_461(n)")){
String xpath = driver.findElement(By.name(test)).getAttribute("xpath");
System.out.println(xpath);
}
}`
Mon intention est de trouver un texte dans un tableau et d’obtenir la valeur de colonne suivante correspondante dans la même rangée. J'ai pensé que je vais remplacer le numéro de colonne trouvé en récupérant le xpath avec le numéro de colonne que je veux. y a-t-il une meilleure façon de le faire
Bien sûr, il y a un moyen. Voici une solution possible.
Obtenez toutes les lignes:
While (iterate over row)
While(Iterate over column)
if(column.Text=='YOUR_MATCH'){
int voila=column.Index
}
}
}
Maintenant, vous pouvez simplement passer à cet index particulier pour les autres lignes; ou vous pouvez utiliser xpath comme .../tr/td[voila]
pour récupérer toutes les cellules de cette colonne.
J'ai écrit une approche, s'il vous plaît, ne prenez pas pour un code de travail réel!
Vous pouvez également l'utiliser pour explorer et générer le xpath:
Appelez la méthode ci-dessous avec
generateXPATH(element, "");
La sortie sera quelque chose comme:
/html[1]/body[1]/div[5]/div[1]/div[2]/div[1]/div[1]/div[1]/div[1]/div[1]/div[1]/form[1]/div[2]/div[1]/input[2]
MÉTHODE
private String generateXPATH(WebElement childElement, String current) {
String childTag = childElement.getTagName();
if(childTag.equals("html")) {
return "/html[1]"+current;
}
WebElement parentElement = childElement.findElement(By.xpath(".."));
List<WebElement> childrenElements = parentElement.findElements(By.xpath("*"));
int count = 0;
for(int i=0;i<childrenElements.size(); i++) {
WebElement childrenElement = childrenElements.get(i);
String childrenElementTag = childrenElement.getTagName();
if(childTag.equals(childrenElementTag)) {
count++;
}
if(childElement.equals(childrenElement)) {
return generateXPATH(parentElement, "/" + childTag + "[" + count + "]"+current);
}
}
return null;
}
La question que vous avez posée n’a aucun sens pour moi. Je suppose qu'il y a peut-être une bonne raison pour que tu veuilles le faire!
Votre ligne de code
String xpath = driver.findElement(By.name(test)).getAttribute("xpath");
ne retournera rien car il n'y a pas d'attribut 'xpath' dans les éléments HTML. Merci de bien préciser vos bases sur la signification de xpath.
si j'ai un élément html comme indiqué ci-dessous
<input name = "username" value = "Name" readonly ="readonly">
je peux obtenir les valeurs d'attribut en utilisant
driver.findElement(By.name("username").getAttribute("value"); // returns 'Name'
Cela me donnera la valeur de l'attribut 'value'
ou
driver.findElement(By.name("username").getAttribute("readonly"); // returns 'readonly'
comme ci-dessus !
Le XPath d'un élément n'est pas une valeur définitive. Un élément peut être trouvé par plusieurs XPaths.
Vous ne pouvez pas utiliser Webdriver pour extraire un XPath et même si vous le pouviez, il est peu probable que ce soit le plus efficace ou le plus judicieux, qui ne peut être défini que par l'automate.
Fnction de JavaScript pour générer XPath
XPath / locator est un moyen d'adresser un élément en naviguant dans l'arborescence.
Absathute XPath (/):/html/body/div [5]/div [4]
WebElement XPath:
function WebElement_XPath(element) {
if (element.tagName == 'HTML') return '/html';
if (element===document.body) return '/html/body';
// calculate position among siblings
var position = 0;
// Gets all siblings of that element.
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
// Check Siblink with our element if match then recursively call for its parent element.
if (sibling === element) return WebElement_XPath(element.parentNode)+'/'+element.tagName+'['+(position+1)+']';
// if it is a siblink & element-node then only increments position.
var type = sibling.nodeType;
if (type === 1 && sibling.tagName === element.tagName) position++;
}
}
MouseEvent XPath:
var eventXPath = '';
function MouseEvent_XPath(e) {
event = e.target || e.srcElement ||e.originalTarget;
for ( var xpathEle = ''; event && event.nodeType == 1; event = event.parentNode ) {
if ( event.tagName == 'HTML' || event.tagName == 'html' ) {
eventXPath = '//html'+xpathEle; break;
}
if ( event.tagName == 'BODY' || event.tagName == 'body' ) {
eventXPath = '//html/body'+xpathEle; break;
}
// calculate position among siblings
var position = 0;
// Gets all siblings of that event.
var siblings = event.parentNode.children;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
// Check Sibling with our event if match then recursively call for its parent event.
if (sibling === event) xpathEle = "/"+event.tagName+'['+(position+1)+']'+xpathEle;
// if it is a sibling with same tagName then only increments position.
if (sibling.tagName === event.tagName) position++;
}
}
}
Xpath relatif (//):// div [@ id = ’social-media’]/ul/li [3]/a
//Element.TagName[@id="idvalue "et @ class =" classValue "et text () =" données innerHTML "]OR que vous pouvez utiliser. (Point) , est un alias pour text (), [. = "données innerHTML"] si vous savez que le contenu que vous recherchez se trouve quelque part dans la balise spécifiée, vous pouvez l'utiliser
Exemple exécuté en console:
var xpath = "//div[@id='answer-32201731' and @data-answerid='32201731']";
var element = document.evaluate(xpath, window.document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null ).singleNodeValue;
element.style.setProperty( 'outline', "3px solid blue","important");
En supposant que vous ayez un attribut sur votre élément avec le nom "xpath", vous pouvez procéder comme suit:
WebElement yourElement = driver.findElement(By.xpath("//td[contains(text(),'MakeGoodDisabled-Programwise_09_44_38_461(n)')]");
String xpathAttributeValue = targetButton.getAttribute("xpath");
Bien que par le son, vous essayez de réaliser quelque chose d’autre que vous n’avez pas encore partagé avec nous. Voulez-vous que Selenium crée un xpath pour vous? Ça ne peut pas.
Presque la même situation pour moi:
J'ai un élément dans la table, mais je ne sais pas dans quelle colonne il se trouve (comme un nom d'utilisateur dans tous les noms d'utilisateurs). Je dois trouver une chaîne particulière avec un nom d'utilisateur et cliquer sur le bouton "Activer" pour cet utilisateur uniquement. (le texte du nom d'utilisateur se situe dans la deuxième colonne, qui est td [2], et le bouton, dans la cinquième colonne, qui est td [5]). J'ai donc besoin d'exécuter toutes les colonnes une par une pour trouver l'utilisateur, puis cliquer sur son bouton:
for (int iter = 1;; iter++) {
try {
if (iter == 1) {
if ((username).equals(driver.findElement(By.xpath("/html/body/div[3]/div[4]/div/form/table/tbody/tr/td[2]/a")).getText())) {
driver.findElement(By.xpath("/html/body/div[3]/div[4]/div/form/table/tbody/tr/td[5]/a")).click();
break;
}
}
} catch (Error e) {}
try {
if (iter > 1) {
if ((username).equals(driver.findElement(By.xpath("/html/body/div[3]/div[4]/div/form/table/tbody/tr[" + iter + "]/td[2]/a")).getText())) {
driver.findElement(By.xpath("/html/body/div[3]/div[4]/div/form/table/tbody/tr[" + iter + "]/td[5]/a")).click();
break;
}
}
} catch (Error e) {}
}
}
Vous pouvez générer des xpath avec JavaScript:
function getPathTo(element) {
// only generate xpaths for elements which contain a particular text:
if (element.innerText == "MakeGoodDisabled-Programwise_09_44_38_461(n)") {
// use id to produce relative paths rather than absolute, whenever possible
if ((element.id !== '') && (element.id != 'undefined')) {
return 'id(\"' + element.id + '\")';
}
// stop looping when you get to the body tag
if (element === document.body) {
return element.tagName;
}
// calculate position among siblings
var ix = 0;
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
if (sibling === element) {
return getPathTo(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
}
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) {
ix++;
}
}
}
}
// put all matching xpaths in an array
var allXPaths = [];
// if you know the particular tag you are looking for, replace * below to optimize
var allTags = document.getElementsByTagName('*');
for (i = 0; i < allTags.length; i++) {
if ((getPathTo(allTags[i]).indexOf('/HEAD') == -1) && (getPathTo(allTags[i]).indexOf('undefined') == -1)) {
allXPaths.Push(getPathTo(allTags[i]));
console.log(getPathTo(allTags[i]));
}
}
return allXPaths;
Si vous placez ce code JavaScript dans une chaîne appelée getXPaths
, vous pouvez l'exécuter en Java de la manière suivante:
ArrayList<String> xpaths = (ArrayList<String>) js.executeScript(getXPaths);
Elle renvoie un tableau plutôt qu'une chaîne, car si votre page contient moins d'éléments ou plus d'éléments correspondant au nom de la variable/innerText, vous voudrez le savoir. Vous pouvez dire par la taille du tableau.
Avant d'itérer, utilisez cette classe. Ensuite, lorsque vous trouvezXPATHIDFromWebElement
import Java.util.LinkedHashMap;
import Java.util.List;
import Java.util.Map;
import org.openqa.Selenium.By;
import org.openqa.Selenium.WebDriver;
import org.openqa.Selenium.WebElement;
public class XPATHDriverWrapper {
Map xpathIDToWebElementMap = new LinkedHashMap();
Map webElementToXPATHIDMap = new LinkedHashMap();
public XPATHDriverWrapper(WebDriver driver){
WebElement htmlElement = driver.findElement(By.xpath("/html"));
iterateThroughChildren(htmlElement, "/html");
}
private void iterateThroughChildren(WebElement parentElement, String parentXPATH) {
Map siblingCountMap = new LinkedHashMap();
List childrenElements = parentElement.findElements(By.xpath(parentXPATH+"/*"));
for(int i=0;i<childrenElements.size(); i++) {
WebElement childElement = childrenElements.get(i);
String childTag = childElement.getTagName();
String childXPATH = constructXPATH(parentXPATH, siblingCountMap, childTag);
xpathIDToWebElementMap.put(childXPATH, childElement);
webElementToXPATHIDMap.put(childElement, childXPATH);
iterateThroughChildren(childElement, childXPATH);
// System.out.println("childXPATH:"+childXPATH);
}
}
public WebElement findWebElementFromXPATHID(String xpathID) {
return xpathIDToWebElementMap.get(xpathID);
}
public String findXPATHIDFromWebElement(WebElement webElement) {
return webElementToXPATHIDMap.get(webElement);
}
private String constructXPATH(String parentXPATH,
Map siblingCountMap, String childTag) {
Integer count = siblingCountMap.get(childTag);
if(count == null) {
count = 1;
} else {
count = count + 1;
}
siblingCountMap.put(childTag, count);
String childXPATH = parentXPATH + "/" + childTag + "[" + count + "]";
return childXPATH;
}
}
Une autre classe de wrapper permettant de générer des identifiants à partir de Document est publiée à l'adresse: http://scottizu.wordpress.com/2014/05/12/generating-unique-ids-for-webelements-via-xpath/
Je pense que ce n'est pas une fonction spéciale disponible pour obtenir le xpath de l'élément recherché. Pour cela, vous devez d'abord trouver l'élément manuellement, puis obtenir le chemin xpath via les fonctions getXpath.