webdriver: получить xpath элемента? - PullRequest
5 голосов
/ 14 ноября 2010

возможно ли вернуть xpath WebElement?

Ответы [ 8 ]

8 голосов
/ 10 декабря 2010

Не напрямую из WebDriver, но вы можете подделать его, если вам действительно нужно:

public String getElementXPath(WebDriver driver, WebElement element) {
    return (String)((JavascriptExecutor)driver).executeScript("gPt=function(c){if(c.id!==''){return'id(\"'+c.id+'\")'}if(c===document.body){return c.tagName}var a=0;var e=c.parentNode.childNodes;for(var b=0;b<e.length;b++){var d=e[b];if(d===c){return gPt(c.parentNode)+'/'+c.tagName+'['+(a+1)+']'}if(d.nodeType===1&&d.tagName===c.tagName){a++}}};return gPt(arguments[0]).toLowerCase();", element);
}

Javascript из этого поста , уменьшен до одной строки. Это может быть не идеально, но может дать вам представление о том, куда идти. Большинство драйверов реализуют интерфейс JavascriptExecutor и имеют возможность выполнять Javascript в браузере. executeScript может возвращать любой примитивный тип JavaScript, элемент HTML или не вложенный список любого из предшествующих.

Не все браузеры поддерживают xpath одинаково , поэтому будьте осторожны при использовании этих xpath для выбора элементов. Кроме того, не все браузеры имеют встроенную поддержку xpath ( кашель IE кашель ), так что в этом случае он был поддельным.

5 голосов
/ 24 декабря 2014

Если WebElement был найден By.xpath: на Java:

public static String GetWebElementXpath(WebElement El) throws AssertionError{
        if ((El instanceof WebElement)){
            Object o = El;
            String text = o.toString();
        /* text is smth like this
        [[FirefoxDriver: firefox on WINDOWS (9170d4a5-1554-4018-adac-f3f6385370c0)] -> xpath: //div[contains(@class,'forum-topic-preview')]//div[contains(@class,'small-human')]]
        */
            text = text.substring( text.indexOf("xpath: ")+7,text.length()-1);
            return text;
        }else   {   Assert.fail("Argument is not an WebElement, his actual class is:"+El.getClass());       }
        return "";
    }
4 голосов
/ 22 февраля 2013

Оба приведенных выше ответа страдают от одной и той же проблемы. Возвращая завершенный XPath с вызванной функцией .toLowerCase(), любой XPath, содержащий идентификатор с заглавной буквой, не будет работать.

Пример: //div[@id="deviceblock-1111"] не будет работать с тегом <div id="deviceBlock-1111">

Однако вы можете просто удалить вызов .toLowerCase() из возврата, но в итоге XPath будет выглядеть так: //DIV[@id="deviceBlock-1111"]/DIV[2]/SELECT[1]/OPTION[5]

Чтобы решить эту проблему, используйте функцию ниже.

public String GetElementXPath(WebElement element, WebDriver driver)
{
    return (String) ((JavascriptExecutor) driver).executeScript(
    "getXPath=function(node)" +
    "{" +
        "if (node.id !== '')" +
        "{" +
            "return '//' + node.tagName.toLowerCase() + '[@id=\"' + node.id + '\"]'" +
        "}" +

        "if (node === document.body)" +
        "{" +
            "return node.tagName.toLowerCase()" +
        "}" +

        "var nodeCount = 0;" +
        "var childNodes = node.parentNode.childNodes;" +

        "for (var i=0; i<childNodes.length; i++)" +
        "{" +
            "var currentNode = childNodes[i];" +

            "if (currentNode === node)" +
            "{" +
                "return getXPath(node.parentNode) + 
                    '/' + node.tagName.toLowerCase() + 
                    '[' + (nodeCount+1) + ']'" +
            "}" +

            "if (currentNode.nodeType === 1 && " +
                "currentNode.tagName.toLowerCase() === node.tagName.toLowerCase())" +
            "{" +
                "nodeCount++" +
            "}" +
        "}" +
    "};" +

    "return getXPath(arguments[0]);", element);
}

Это вернет правильно отформатированный, уникальный XPath из вашего WebElement.

//div[@id="deviceBlock-1111"]/div[2]/select[1]/option[5]

1 голос
/ 13 сентября 2016

Я бы прокомментировал непосредственно dflems ' answer , но у меня нет репутации, чтобы сделать это.

Преобразование всего xpath в нижний регистр - это хорошоесли xpath не содержит значение id, которое не является строчными.Ниже приведена модифицированная версия Javascript dflems, но в Python вместо Java:

def get_xpath_from_element(driver, element):
    return driver.execute_script("gPt=function(c){if(c.id!==''){return'id(\"'+c.id+'\")'}if(c===document.body){return c.tagName}var a=0;var e=c.parentNode.childNodes;for(var b=0;b<e.length;b++){var d=e[b];if(d===c){return gPt(c.parentNode)+'/'+c.tagName.toLowerCase()+'['+(a+1)+']'}if(d.nodeType===1&&d.tagName===c.tagName){a++}}};return gPt(arguments[0]);", element)

1 голос
/ 26 марта 2012
public String getElementXPath(WebDriver driver, WebElement element) {

    String javaScript = "function getElementXPath(elt){" +
                            "var path = \"\";" +
                            "for (; elt && elt.nodeType == 1; elt = elt.parentNode){" +
                                "idx = getElementIdx(elt);" +
                                "xname = elt.tagName;" +
                                "if (idx > 1){" +
                                    "xname += \"[\" + idx + \"]\";" +
                                "}" +
                                "path = \"/\" + xname + path;" +
                            "}" + 
                            "return path;" +
                        "}" +
                        "function getElementIdx(elt){" +
                            "var count = 1;" +
                            "for (var sib = elt.previousSibling; sib ; sib = sib.previousSibling){" +
                                "if(sib.nodeType == 1 && sib.tagName == elt.tagName){" +
                                    "count++;" +
                                "}" +
                            "}" +
                            "return count;" + 
                        "}" +
                        "return getElementXPath(arguments[0]).toLowerCase();";      

    return (String)((JavascriptExecutor)driver).executeScript(javaScript, element);     

}
0 голосов
/ 28 апреля 2016
/**
 * This method return By reference for the WebElement passed to it as a parameter.
 * @param element
 * @return
 */
public static By convertWebElementToByReference(WebElement element) 
{
    By byLocator = null;
    String elementDescription = element.toString();
    String elementTypeAndValue[] = (elementDescription.substring(elementDescription.lastIndexOf("-> ") + 3, elementDescription.lastIndexOf("]"))).split(":");        

    switch (elementTypeAndValue[0].trim()) 
    {
        case "id": byLocator = By.id(elementTypeAndValue[1].trim());
           break;

        case "xpath": byLocator = By.xpath(elementTypeAndValue[1].trim());
           break;

        case "link text": byLocator = By.linkText(elementTypeAndValue[1].trim());
           break;

        case "tag name": byLocator = By.tagName(elementTypeAndValue[1].trim());
           break;

        case "class name": byLocator = By.className(elementTypeAndValue[1].trim());
           break;

        case "partial link text": byLocator = By.partialLinkText(elementTypeAndValue[1].trim());
           break;

        case "name": byLocator = By.name(elementTypeAndValue[1].trim());
           break;

        case "css selector": byLocator = By.cssSelector(elementTypeAndValue[1].trim());
           break;

        default:
            throw new RuntimeException("Invalid locator type: " + elementTypeAndValue[0].trim());
    }

    return byLocator;
}
0 голосов
/ 02 июля 2015
public static String getXPathFromElement(WebElement element) {
        String elementDescription = element.toString();
        return elementDescription.substring(elementDescription.lastIndexOf("-> ") + 3, elementDescription.lastIndexOf("]"));
}

Веб-элемент toString () выглядит так:

'[[FirefoxDriver: firefox на WINDOWS (ceb69f9f-bef4-455d-b626-ab439f195be6)] -> id: pageBeanfundDescription]'

Я просто извлекаю id / xpath.

0 голосов
/ 08 августа 2014

Есть способ получить элементы XPath без использования JavaScript.

  1. Определить начальную точку внешнего XPath, например тег body.
  2. Проверьте все возможные внутренние теги с селеном для NoSuchElementException.
  3. Проверьте getText для списков сгенерированных XPath.
  4. 1012 * выигрывать *
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...