如何使用XPath仅选择可见元素?

Dav*_*ebb 46 gwt selenium xpath

我有一个GWT应用程序,我正在尝试使用Selenium编写一些测试.

我正在使用XPath来识别测试页面上的元素.使用id将不起作用,因为idGWT自动生成值并且可以更改.当我意识到我可以通过他们的标签找到按钮时,情况开始顺利,如下所示:

//button[.='OK']
Run Code Online (Sandbox Code Playgroud)

但是,当我开始运行多个测试时,我开始遇到问题.我意识到问题是一旦由Javascript生成的GWT应用程序的所有不同"页面"保留在隐藏<div>元素的HTML中.这意味着我的Selenium测试有时会单击隐藏按钮而不是当前视图中可见的按钮.

使用Firebug检查HTML ,似乎GWT <div>通过添加属性display: none来隐藏元素style.这意味着我可以找到所有隐藏的OK按钮,如下所示:

//div[contains(@style,'display: none')]//button[.='OK']
Run Code Online (Sandbox Code Playgroud)

这会发现所有的隐藏的按钮OK,即它有一个祖先的按钮<div>被具有隐藏display: nonestyle.

我的问题是:如何使用XPath只查找可见的OK按钮?如何找到它们没有什么祖先的按钮<div>与元素display: nonestyle

Jul*_*urg 56

这应该工作:

.//button[.='OK' and not(ancestor::div[contains(@style,'display:none')])
and not(ancestor::div[contains(@style,'display: none')])]
Run Code Online (Sandbox Code Playgroud)

编辑:

下面更简单,更有效的表达方式:

//div[not(contains(@style,'display:none'))]//button[.='OK']
Run Code Online (Sandbox Code Playgroud)

因为每个按钮至少有一个在其祖先中可见的div,所以无法正常工作.

  • 注意`class ="display:none;"`与上面没有匹配(空格使它不同). (7认同)
  • 请注意未来的读者:虽然这是一个很好的解决方案(并且最好的XPath可能会这样做),但它并不适用于所有情况**,因为给定的元素可能有一个CSS类,其中`display:none ;`设置,从而使元素不可见,但仍然与此XPath表达式匹配. (6认同)
  • 在检查之前,最好从属性中删除空间,而不是将其用于空间.translate(normalize-space(@style),'','')适用于任意数量的空格. (4认同)
  • @sureshvv 我花了几分钟盯着它才发现那部分_没有_重复。其中有两个子句:第一个子句表示它不能有任何样式属性包含“display:none”的祖先,另一个子句执行相同的操作,但“display:none”带有空格。 (2认同)

Har*_*ddy 12

Selenium 2 Webdriver为我们提供了isDisplayed()方法的选项,可以解决这个问题.硒贡献者的出色工作.

  • 是的,但你必须检查这个特定的元素,不能匹配整个集合. (2认同)
  • 要小心,因为在检索(`find by*`)和使用`isDisplayed()`检查其可见性之间更改元素时,这会引发`StaleElementReferenceException`异常. (2认同)