Selenium-Webdriver:找到元素后获取属性

Posted

技术标签:

【中文标题】Selenium-Webdriver:找到元素后获取属性【英文标题】:Selenium-Webdriver: Get attributes after finding an element 【发布时间】:2012-12-26 16:04:45 【问题描述】:

我对自动化的东西还是很陌生,所以这听起来像是一个愚蠢的问题。 在发布问题之前,我确实谷歌搜索了它:)

总之,问题来了

我正在 android 设备上自动执行测试 其中一项测试是验证项目是否已被标记为“收藏” 页面代码sn-p为:

<li class = "resultItem isFavorite" data-index="2">
<div class="name" data-cis="4ced6feb-3b5c-415a-ae1c-0b8bca8e3c85" onclick="return true">f,f</div>
</li>

我可以使用el = @driver.find_element(:xpath, "//*[class='name' and text() ='f,f']") 在列表中找到元素。我希望 el.class 会告诉我 resultItem isFavorite。 相反,我得到的是: Selenium:WebDriver::Element

如果项目未标记为收藏,则不会在字段中添加 isFavorite 标志。 我希望使用 isFavorite 来验证一个项目是否被标记为收藏,但我似乎无法将它放入变量中。

任何帮助将不胜感激。

谢谢,

杰夫

【问题讨论】:

【参考方案1】:

红宝石

element.attribute("attribute name")

Python

element.get_attribute("attribute name")

Java

element.getAttribute("attribute name")

C#

element.GetAttribute("attribute name");

【讨论】:

【参考方案2】:

我在这里阅读两个问题。首先,简短易懂。

问:现在我找到了el,如何访问它的类 html 属性?

答:使用el.attribute('class'),或其简写形式el['class']。见Selenium::WebDriver::Element.attribute。

现在更长了。

问:如何测试el 表示的项目是否被标记为收藏?

答:见下文。

为了提供更好的答案,我需要有关我们正在测试的页面组成的更多信息。我做了一些基本假设:

页面包含一个或多个li 元素,其类为'resultItem',其中一些元素还具有'isFavorite' 类。 每个li 元素都有一个或多个子元素,其中一个保证为div'name'。 只有一个这样的孩子div 会有文字'f,f'

一般来说,我们有两种方法可以解决这个问题。

    我们可以找到相关的div,然后验证其父li有类'isFavorite'。 我们可以找到类'isFavorite'的所有li元素,然后验证其中一个元素是否包含相关的div

这里有很多事情我们需要注意。

对于 Selenium,XPath 选择器擅长通过文本查找,但 poor at finding by class。 CSS 选择器擅长按类查找,但 cannot find by text。这些都不是找到我们所追求的div 的理想选择。

如上所述,我们可以使用element['class'] 获取元素的类(属性)。我们发现,element.class 调用 Object#class,给我们Selenium::WebDriver::Elementel['class'],在这种情况下,给了我们字符串'name'。如果调用它的父元素,我们会得到'resultItem isFavorite'

我们可以使用element.text 获取元素的文本。在这种情况下,el.text 会给我们'f,f'。与javascript's textContent function 一样,它返回元素的文本及其所有后代,因此在父元素上调用text() 也会给我们'f,f'。请注意,此方法可能很慢,并且如果元素以某种方式不可见,则会返回一个空字符串。谨慎使用。请参阅Selenium::WebDriver::Element.text 了解更多信息。

鉴于上述情况,让我们看看方法#1 和#2 是如何发挥作用的。 (以下为 Ruby 1.9.3。)

方法#1

div_elements = @driver.find_elements(:css, 'li > div.name').select  |e| e.text == 'f,f' 
div_element = div_elements.first

parent_li = div_element.find_element(:xpath, './..')
parent_li_classes = parent_li['class'].scan(/\S+/)
if parent_li_classes.include?('isFavorite')
  # PASS
else
  # FAIL
end

方法#2

favorite_items = @driver.find_elements(:css, 'li.isFavorite')
if favorite_items.any?  |item| item.find_element(:css, 'div.name').text == 'f,f' 
  # PASS
else
  # FAIL
end

方法#2,重构

if @driver.find_elements(:css, 'li.isFavorite').any?  |item| item.text == 'f,f' 
  # PASS
else
  # FAIL
end

【讨论】:

【参考方案3】:

我可以通过另一种方式解决这个问题:

element = @driver.find_elements(:class, "isFavorite")
element.each do |t|
   if t.text() == 'f,f' then
       result = "pass"
   end
end

我觉得这可能真的很慢,如果有一个很长的列表......但至少它有效:)

谢谢

杰夫

【讨论】:

【参考方案4】:

您真正想要的是以下内容:

# Note: Possibly incorrect Ruby code here. 
# Written from memory.
el = @driver.find_element(:xpath, "/your/xpath/here")
# Could also your el["class"]
element_class_attribute = el.attribute("class")

通常,使用大多数属性名称,如src(如el.src)会给你一个运行时错误。不过碰巧class在Ruby中有着特殊的含义,每个对象都有一个class属性,也就是Ruby类。

【讨论】:

嗨,吉姆,我尝试了 get_attribute 及其变体。但它不断提出“未定义的方法”。我会继续寻找 ruby​​ get_attribute 等价物是什么。不过,我确实找到了解决这个问题的另一种方法。 您想要的实际 ruby​​ 方法是 .attribute()。我已经更正了答案中的示例代码以反映这一点。请记住,您始终可以在 this link 找到 Ruby 的 API 文档 @SSchneid 所以这是一条评论,这意味着我不能回去编辑它。此外,这是一个超过 4 的评论。该项目早已从 Google Code 迁移到 GitHub。

以上是关于Selenium-Webdriver:找到元素后获取属性的主要内容,如果未能解决你的问题,请参考以下文章

selenium-webdriver定位多个元素

当目标元素和目标元素在不同的帧中时,如何使用 selenium-webdriver 执行拖放?

python selenium-webdriver 元素操作之键盘操作

selenium-webdriver八种定位元素的常用方式

(转)python selenium-webdriver 元素操作之鼠标和键盘事件

轻松自动化---selenium-webdriver(python)