不同浏览器的XPath是否不同?

6

我是一个有趣的问题。我正在使用xpath检索值。

例如:

System.out.print(driver.findElement(By.xpath("//*[@id='error-box']/ul/li")).getText().toString());

在 Firefox 和 Chrome 中,它们给出的文本是相同的,而在 IE 中则给出不同的文本。

各种浏览器之间的 xpath 是否有差异或者说存在其他问题我还没有理解清楚。


4
答案既不完全是“是”,也不完全是“否”。IE浏览器没有本地XPath引擎,因此Selenium使用基于JavaScript的XPath引擎作为替代品 - 称为“Wicked Good XPath”。因此,您可能会出现不一致性 - 毕竟它是一种JS实现,而大多数其他浏览器都具有本地支持。另一件事是浏览器对元素的支持不同。一个常见的例子是某些元素(HTML5)中的“placeholder”属性 - <IE9将这个属性呈现为一个单独的元素,而其他浏览器则不会。因此,您的XPath需要考虑到这种差异 - 需要更多信息!!! - Arran
getText() 应该根据文档(https://selenium.googlecode.com/svn/trunk/docs/api/java/org/openqa/selenium/WebElement.html)返回一个字符串。因此,您可能不需要在末尾使用 .toString()。 - Andrejs
5个回答

7

了解Selenium如何处理Xpath,请点击这里

在Chrome和Firefox中,我右键单击相同的DOM元素(如此处所述),选择“复制XPath”,得到以下结果:

Chrome: //*[@id="js-pjax-container"]/div2/div2/form/button

Firefox(使用Firebug):/html/body/div[4]/div2/div2/div2/form/button

(其中一个带有属性值,另一个(FF)是绝对路径,这表明FF不理解Chrome生成的Xpath)

因此,在Selenium测试中,浏览器之间的差异很重要。(我没有在IE上测试)

我运行了以下命令:

 @Test
        public void testGitHubButton(){
        WebDriver driver = new FirefoxDriver();
        driver.get("https://github.com/");
       String signup = driver.findElement(By.xpath("/html/body/div[4]/div[1]/div[1]/div[1]/form/button")).getText();
           Assert.assertEquals("Testing for string equality", "Sign up for GitHub", signup );
        driver.close();
        driver.quit();
        }

测试通过。如果我在那里复制粘贴Chrome的Xpath,它将失败。


0

首先,是由开发/测试工程师 (SDET) 构建的。因此,构建有效的xpath在很大程度上取决于开发/测试工程师。优化的xpath应该在跨浏览器跨平台测试中表现出相同的效果。


getText()

getText() 获取此元素的可见文本(即未被 CSS 隐藏的文本),包括子元素,即返回元素的可见文本。

java.lang.String getText()

因此,您不必通过toString()显式转换返回的结果,可以将其删除。因此,您的有效代码行将是:
System.out.print(driver.findElement(By.xpath("//*[@id='error-box']/ul/li")).getText());

规范

根据WebDriver-W3C Editor's Draft

获取元素文本命令旨在“按呈现方式”返回元素的文本。元素的呈现文本也用于通过链接文本和部分链接文本定位元素。

这个规范的主要输入之一是开源的Selenium项目。在编写此规范之前,它已被广泛使用,因此已经设置了用户对获取元素文本命令应该如何工作的期望。因此,这里提出的方法已知存在缺陷,但提供了与现有用户最佳兼容性。


元素的xpath为什么会改变?

所有浏览器都不使用相同的渲染引擎或渲染规则,这成为Web开发人员的主要障碍之一,而且这似乎不会很快消失。


解决方案

解决这个问题的通用方法是尽可能使用,因为浏览器在严格的样式表规则下最易遵从。以下是一些示例:

  • 使用HTML <!DOCTYPE>声明:所有HTML文档都必须以<!DOCTYPE>声明开头。该声明不是HTML标签,而是向浏览器提供有关所期望的文档类型的信息。在HTML 5中,声明如下:

  • 使用Reset CSS:重置样式表的目标是减少浏览器在默认行高、边距和标题字体大小等方面的不一致性。

  • 使用clearfix:清除浮动的有用方法。


这个用例

理想情况下,为了提取所需的文本,您需要使用WebDriverWait来诱导 visibilityOfElementLocated(),并且您可以使用以下定位策略

System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[@id='error-box']/ul/li"))).getText());

-1

它们在每个浏览器中都不同。有些是区分大小写的,有些则不是。根据w3schools.com的说法:“不幸的是,在Internet Explorer和其他浏览器中处理XPath有不同的方法。”


-1

IE和Chrome之间的区别仅在Xpath中的[Index]编号上。在IE中,索引从0开始,但在Chrome中,索引从1开始。
例如:

如果您从Chrome获取的Xpath为

/html/body/div[4]/div[3]/div[3]/div[1]/form/button 

在Internet Explorer(IE)中相同的Xpath将是

/html/body/div[3]/div[2]/div[2]/div/form/button

(注意: div与div [0]相同)

由于IE中没有本地Xpath引擎,因此您可以从Chrome复制Xpath并按上述方法减少索引,这对我在使用自己的方法将xpath转换为IE的IHTMLElement标记时非常有效。


-2

不,XPath在任何地方都被解释为相同的方式。

您可能想要检查getText()方法。

或者您可能想要检查您是否已登录到IE中的某个帐户(而不是Chrome / FF)或反之。例如:您将获得google.com的不同DOM,与google.com(登录到google帐户)不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接