Selenium RC定位器 - 指后续元素?

时间:2023-02-10 19:28:39

When there is more than a single element with the same locator in a page, how should the next elements be referenced?

当页面中有多个具有相同定位符的元素时,应如何引用下一个元素?

Using Xpath locators it's possible to add array notation, e.g. xpath=(//span/div)[1] But with simple locators?

使用Xpath定位器可以添加数组表示法,例如xpath =(// span / div)[1]但是使用简单的定位器?

For example, if there are 3 links identified by "link=Click Here", simply appending [3] won't get the 3rd element.

例如,如果有3个链接由“link = Click Here”标识,则只需附加[3]将不会获得第3个元素。

And where is the authoritative reference for addressing array of elements? I couldn't find any.

哪些是解决元素数组的权威参考?我找不到任何东西。

2 个解决方案

#1


Selenium doesn't handle arrays of locators by itself. It just returns the first element that meets your query, so if you want to do that, you have to use xpath, dom or even better, css.

Selenium本身不处理定位器数组。它只返回满足查询的第一个元素,所以如果你想这样做,你必须使用xpath,dom甚至更好的css。

So for the link example you should use:

因此,对于链接示例,您应该使用:

selenium.click("css=a:contains('Click Here'):nth-child(3)")

#2


Santi is correct that Selenium returns the first element matching your specified locator and you have to apply the appropriate expression of the locator type you use. I thought it would be useful to give the details here, though, for in this case they do border on being "gory details":

Santi是正确的,Selenium返回与您指定的定位器匹配的第一个元素,您必须应用您使用的定位器类型的相应表达式。我认为在这里提供详细信息会很有用,因为在这种情况下,它们与“血腥细节”接壤:

CSS

The :nth-child pseudo-class is tricky to use; it has subtleties that are little-known and not clearly documented, even on the W3C pages. Consider a list such as this:

:nth-​​child伪类很难使用;它具有鲜为人知的微妙之处,即使在W3C页面上也没有明确记录。考虑一个这样的列表:

<ul>
  <li class="bird">petrel</li>
  <li class="mammal">platypus</li>
  <li class="bird">albatross</li>
  <li class="bird">shearwater</li>
</ul>

Then the selector css=li.bird:nth-child(3) returns the albatross element not the shearwater! The reason for this is that it uses your index (3) into the list of elements that are siblings of the first matching element--unfiltered by the .bird class! Once it has the correct element, in this example the third one, it then applies the bird class filter: if the element in hand matches, it returns it. If it does not, it fails to match.

然后选择器css = li.bird:nth-​​child(3)返回信天翁元素而不是剪切水!这样做的原因是它将你的索引(3)用在第一个匹配元素的兄弟元素列表中 - 未被.bird类过滤!一旦它具有正确的元素,在这个例子中是第三个元素,它然后应用鸟类过滤器:如果手中的元素匹配,则返回它。如果没有,则无法匹配。

Now consider the selector css=li.bird:nth-child(2). This starts with the second element--platypus--sees it is not a bird and comes up empty. This manifests as your code throwing a "not found" exception!

现在考虑选择器css = li.bird:nth-​​child(2)。这从第二个元素开始 - 鸭嘴兽 - 看到它不是一只鸟而且是空的。这表现为您的代码抛出“未找到”异常!

What might fit the typical mental model of finding an indexed entry is the CSS :nth-of-type pseudo-class which applies the filter before indexing. Unfortunately, this is not supported by Selenium, according to the official documentation on locators.

可能适合寻找索引条目的典型心理模型的是CSS:nth-​​of-type伪类,它在索引之前应用过滤器。不幸的是,根据定位器的官方文档,Selenium不支持这一点。

XPath

Your question already showed that you know how to do this in XPath. Add an array reference at any point in the expression with square brackets. You could, for example use something like this: //*[@id='abc']/div[3]/p[2]/span to find a span in the second paragraph under the 3rd div under the specified id.

您的问题已经表明您知道如何在XPath中执行此操作。使用方括号在表达式中的任何位置添加数组引用。例如,您可以使用以下内容:// * [@ id ='abc'] / div [3] / p [2] / span在指定ID下的第3个div下的第二个段落中查找范围。

DOM

DOM uses the same square bracket notation as XPath except that DOM indexes from zero while XPath indexes from 1: document.getElementsByTagName("div")[1] returns the second div, not the first div! DOM offers an alternate syntax as well: document.getElementsByTagName("div").item(0) is exactly equivalent. And note that with getElementsByTagName you always have to use an index since it returns a node set, not a single node.

DOM使用与XPath相同的方括号表示法,除了DOM索引从零开始,而XPath索引从1开始:document.getElementsByTagName(“div”)[1]返回第二个div,而不是第一个div! DOM还提供了另一种语法:document.getElementsByTagName(“div”)。item(0)完全等效。请注意,使用getElementsByTagName,您始终必须使用索引,因为它返回节点集,而不是单个节点。

#1


Selenium doesn't handle arrays of locators by itself. It just returns the first element that meets your query, so if you want to do that, you have to use xpath, dom or even better, css.

Selenium本身不处理定位器数组。它只返回满足查询的第一个元素,所以如果你想这样做,你必须使用xpath,dom甚至更好的css。

So for the link example you should use:

因此,对于链接示例,您应该使用:

selenium.click("css=a:contains('Click Here'):nth-child(3)")

#2


Santi is correct that Selenium returns the first element matching your specified locator and you have to apply the appropriate expression of the locator type you use. I thought it would be useful to give the details here, though, for in this case they do border on being "gory details":

Santi是正确的,Selenium返回与您指定的定位器匹配的第一个元素,您必须应用您使用的定位器类型的相应表达式。我认为在这里提供详细信息会很有用,因为在这种情况下,它们与“血腥细节”接壤:

CSS

The :nth-child pseudo-class is tricky to use; it has subtleties that are little-known and not clearly documented, even on the W3C pages. Consider a list such as this:

:nth-​​child伪类很难使用;它具有鲜为人知的微妙之处,即使在W3C页面上也没有明确记录。考虑一个这样的列表:

<ul>
  <li class="bird">petrel</li>
  <li class="mammal">platypus</li>
  <li class="bird">albatross</li>
  <li class="bird">shearwater</li>
</ul>

Then the selector css=li.bird:nth-child(3) returns the albatross element not the shearwater! The reason for this is that it uses your index (3) into the list of elements that are siblings of the first matching element--unfiltered by the .bird class! Once it has the correct element, in this example the third one, it then applies the bird class filter: if the element in hand matches, it returns it. If it does not, it fails to match.

然后选择器css = li.bird:nth-​​child(3)返回信天翁元素而不是剪切水!这样做的原因是它将你的索引(3)用在第一个匹配元素的兄弟元素列表中 - 未被.bird类过滤!一旦它具有正确的元素,在这个例子中是第三个元素,它然后应用鸟类过滤器:如果手中的元素匹配,则返回它。如果没有,则无法匹配。

Now consider the selector css=li.bird:nth-child(2). This starts with the second element--platypus--sees it is not a bird and comes up empty. This manifests as your code throwing a "not found" exception!

现在考虑选择器css = li.bird:nth-​​child(2)。这从第二个元素开始 - 鸭嘴兽 - 看到它不是一只鸟而且是空的。这表现为您的代码抛出“未找到”异常!

What might fit the typical mental model of finding an indexed entry is the CSS :nth-of-type pseudo-class which applies the filter before indexing. Unfortunately, this is not supported by Selenium, according to the official documentation on locators.

可能适合寻找索引条目的典型心理模型的是CSS:nth-​​of-type伪类,它在索引之前应用过滤器。不幸的是,根据定位器的官方文档,Selenium不支持这一点。

XPath

Your question already showed that you know how to do this in XPath. Add an array reference at any point in the expression with square brackets. You could, for example use something like this: //*[@id='abc']/div[3]/p[2]/span to find a span in the second paragraph under the 3rd div under the specified id.

您的问题已经表明您知道如何在XPath中执行此操作。使用方括号在表达式中的任何位置添加数组引用。例如,您可以使用以下内容:// * [@ id ='abc'] / div [3] / p [2] / span在指定ID下的第3个div下的第二个段落中查找范围。

DOM

DOM uses the same square bracket notation as XPath except that DOM indexes from zero while XPath indexes from 1: document.getElementsByTagName("div")[1] returns the second div, not the first div! DOM offers an alternate syntax as well: document.getElementsByTagName("div").item(0) is exactly equivalent. And note that with getElementsByTagName you always have to use an index since it returns a node set, not a single node.

DOM使用与XPath相同的方括号表示法,除了DOM索引从零开始,而XPath索引从1开始:document.getElementsByTagName(“div”)[1]返回第二个div,而不是第一个div! DOM还提供了另一种语法:document.getElementsByTagName(“div”)。item(0)完全等效。请注意,使用getElementsByTagName,您始终必须使用索引,因为它返回节点集,而不是单个节点。