【问题标题】:WebDriver Selenium API: identifying a WebElement in XPathWebDriver Selenium API:在 XPath 中识别 WebElement
【发布时间】:2012-08-16 11:42:10
【问题描述】:

我最近开始使用 Selenium,我决定只使用 Selenium 2 / WebDriver。 在我的测试代码中,我经常到达WebElement,却不知道它在页面中的位置。

我想要代码,给定一个 WebElement,构造一个 XPath 表达式来唯一地选择它。

用于 Selenium 的 FireFox 记录器插件可以做到这一点;我想要的是在 Selenium 2 中执行此操作的代码。

我可以自己编写这样的代码,通过使用WebElementfindElementwalk up the treefindElements 来找到我们来自的孩子,但快速想出一些东西并不容易(反复调用By.xpath看起来很糟糕)并且完整(例如,由于命名空间)。

A related question 建议改用 CSS 选择器 - 这对我来说很好。)

有人帮我做过吗?最好的方法是什么?

【问题讨论】:

    标签: api selenium webdriver selenium-webdriver


    【解决方案1】:

    也许这会有所帮助:我正在测试一个网站,其中 id 是动态生成的,所以它们一直在变化。为了获得他们的 xpath 并使用它,我使用了这个函数:

        /**
     * Gets the absolute xPath for elements with dynamic ids.
     * 
     * @param driver - the current WebDriver instance
     * @param element - the element for which the xPath will be found
     * @return the absolute xPath for this element
     */
    public static String getElementXPath(WebDriver driver, WebElement element) {
        return (String)((JavascriptExecutor)driver).executeScript(
                "gPt=function(c)" +
                "{" +
                "if(c.id!=='')" +
                "{return c.tagName + '[@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]);", element);
    }
    

    【讨论】:

    • 当然,如果您将其扩展为在页面深处也可以找到元素,这将起作用,但是一旦您使用 JavaScript,我认为像我一样从元素向上移动到文档根目录会更有效描述。这个解决方案的便携性如何?
    • 这不会一直向上,直到找到一个具有 id 的元素。至于可移植性,我只在 Firefox 上进行了测试,如果你是这个意思的话。
    【解决方案2】:

    这很简单:顺便说一句,css 是要走的路; xpath 应仅用作最后手段。 http://sauceio.com/index.php/2010/01/selenium-totw-css-selectors-in-selenium-demystified/ 比我在此处提供的空间中更深入地解释了 css 定位器。

    最佳方法:如果您使用的是 firefox 下载 firebug,那会让您查看您的 html。按下 cmd+Shift+c,它会用元素荧光笔打开。找到你的 html 元素,也许它看起来像这样

    <input type="submit" tabindex="110" value="Post Your Answer" id="submit-button">
    

    然后你可以很简单地找到你的元素

    WebElement element = driver.findElement(By.cssSelector("input[id='submit-button']"))
    

    请注意,我们将标记名放在“input”前面,然后是括号“input[id='submit-button']”中的某种唯一标识符。在大多数情况下,这将涵盖您使用的所有 css 定位器的 75%。其他 25% 需要在我放置在页面顶部的链接中包含一些更棘手的内容。

    您可能会问“除了 id 之外我还可以使用哪种唯一标识符”,这在此处进行了介绍:http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/dotnet/Selenium.html

    祝你好运开始

    编辑

    祝你一开始就找到你的元素...如果你需要,你可以通过部分定位符文本搜索元素,如 input[id*='submit']。当您使用部分文本作为定位器的一部分时,使用它对动态生成的元素很有帮助,它不会因元素而异。

    您提到爬上 html 树,也许我在第一次阅读问题时没有看到这一点。我认为你遇到了手头的问题。不建议走上 html 树,因为它会使您的测试更容易受到 html 更改的影响。从长远来看,它还会使您的代码不可读。一般来说,如果您的 id 丢失或无法预测,我建议您与 proj 交谈。关于让开发人员编写实际上可以自动化的代码的管理(例如:在关键元素上实现标识符)。从长远来看,这实际上会为您和开发人员节省大量精力,而且还会提高测试的速度和可靠性。

    【讨论】:

    • 谢谢!不幸的是,这并没有真正帮助我,因为我元素上的大多数 id 都丢失或无法预测。
    【解决方案3】:

    我们可以使用 ID 找到提交按钮:

    1.driver.findElement(By.id("submit-button"))

    ID > 名称 > CSS > XPATH

    【讨论】:

    • 谢谢!不幸的是,这并没有真正帮助我,因为我元素上的大多数 id 都丢失或无法预测。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-05
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多