web-dev-qa-db-fra.com

Recherchez un élément par le texte et obtenez xpath - Selenium webdriver junit

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);
                        }
                    }`
9
Nandini Joshi

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!

0
coding_idiot

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;
}
17
Scott Izu

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 !

7
Abhishek Singh

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.

6
Robbie Wareham

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");
1
Yash

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.

0
joostschouten

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) {}
                } 
          }
0
dred17

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.

0
Pat Meeker

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/

0
Scott Izu

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.

0
Atif Hussain