Selenium 的 GetAttribute 方法的并发症

Posted

技术标签:

【中文标题】Selenium 的 GetAttribute 方法的并发症【英文标题】:Complications with Selenium's GetAttribute method 【发布时间】:2011-07-07 11:19:13 【问题描述】:

我最近尝试使用 selenium RC 的 GetAttribute 方法,但立即遇到了挑战。我尝试执行一个非常简单的selenium.GetAttribute("//a/@href"),但代码抛出了 SeleniumException,并显示消息 “错误:找不到元素属性://a/@href”。 通过用 selenium.GetText("//a[@href]") 代替 GetAttribute 调用,我确认了一个元素确实存在,因为该语句正确地返回了链接的文本。

然后我尝试了:

使用不同的协议(file:/// vs http://)指向不同的网页——同样的问题。 使用指向不同属性的不同 xpath 定位器——同样的问题。 使用 DOM 定位器selenium.GetAttribute("document.getElementsByTagName('a')[0].getAttribute('href')")——同样的问题;错误消息略有不同(并且错误消息缺少最后的括号):“错误:元素 document.getElementsByTagName('a')[0].getAttribute('href' not found”。请注意这个确切的表达式在 Firebug 的控制台中可以正常工作。 使用绝对而不是相对 xpath 寻址,使用 selenium.GetText("xpath=/html/body/a[@href]") 确认存在,然后使用 selenium.GetAttribute("xpath=/html/body/a/@href") 获取属性 - 它有效!

虽然手册明确指出 relative xpath 定位器不需要明确的定位器类型(即“xpath=”前缀),但它没有提及 absolute xpath 定位器;我从这里解释说前缀是必需的。但出于好奇,我回到我的相对表达式并添加了显式前缀——将selenium.GetAttribute("//a/@href") 更改为selenium.GetAttribute("xpath=//a/@href")——这也有效!

最后,我在 Selenium IDE 中使用非常方便的 Find 按钮进行的​​实验表明,它可以很好地处理元素,但不能处理属性。我可以理解,因为属性不是可见的页面元素,所以突出显示属性没有意义,但是为什么不突出显示包含该属性的元素,并使其具有不同的颜色呢?也许不是一件小事……

我的问题:

我将上述实验的结果提炼成这些问题;这就是我在这里发帖的全部目的!这些对我来说似乎都是一个错误,但如果您认为我的用法不正确或有解决方法,请告诉我:

    为什么带有 XPath 定位器类型的 GetAttribute 唯一需要 显式 定位器类型,而其他方法(例如 GetText)不需要? 为什么 DOM 定位器失败并出现“未找到”错误? (手册还明确指出 DOM 定位器需要明确的定位器类型前缀,但我仍然尝试在 DOM 测试中添加“dom=”作为前缀;它仍然失败。) 为什么 Selenium IDE 在尝试突出显示(查找)属性时不会更优雅地失败?使用相同的 "xpath=//a/@href" 定位器,按下 Find 按钮会产生这条丑陋的消息:“[error] locator not found: xpath=//a/@href, error = [Exception...”Could not convert javascript argument arg 0 [ inIFlasher.scrollElementIntoView]" nsresult: "0x80570009 (NS_ERROR_XPC_BAD_CONVERT_JS)" location: "JS frame :: chrome://selenium-ide/content/selenium-runner.js :: showElement :: line 386" data: no]"李>

您的输入还需要以下内容:我想要的每个测试的模式是 (A) GetText(locator-for-element-with-attribute)确认元素的存在然后 (B) GetAttribute(locator-for-attribute-itself)。在下表中的 6 个插槽中,我成功地解决了其中的 3 个,正如刚才详述的那样,第 4 个似乎是一个错误。 剩下的两个槽有解决方案吗?

类型 GetText GetAttribute XPath //a[@href] xpath=//a/@href CSS css=a[href] ?? DOM ?? document.getElementsByTagName('a')[0].getAttribute('href')

(详情:Selenium RC 版本 1.0.3,浏览器:Firefox 3.6.13,我在 C# 中的目标代码)

【问题讨论】:

【参考方案1】:

Selenium RC 的GetAttribute 方法返回元素\属性定位器的。这些定位器的一般形式是

"[locator (id, xpath, css, etc)]@[attribute name]"

例如

"SaveButton@href"

返回 id 为 SaveButton 的元素的 href 属性值。也可以使用 Xpath 定位器:

"xpath=//a[contains(@id, 'SaveButton')]@href"

返回其 id 包含文本 SaveButton 的元素的 href 属性的值。

为了回答您的问题,

1:我真的不知道,这是 Selenium 设计者的问题。

2:Selenium 命令执行几个不同的“上下文”。在某些命令中,document 指的是被测网页,在其他命令中,document 指的是包含 Selenium 框架的页面(我相信是 testRunner.html)。

3:错误消息说它找不到您请求的元素。如果确实存在错误,那么之后的信息可能对 Selenium 团队有用,但不会真正影响您。信息越多越好,对吧?

【讨论】:

非常简洁精确位的信息!我错过了 Selenium 使用自定义格式的属性,而不是我假设的“本机”格式。这很容易出错,因为 xpath 使用与 Selenium 选择使用相同的“@”元标记。因此,正确的 Selenium //a@href 有效,而正确的 xpath //a/@href 有效 not (除了某些怪癖,它可以使用显式的“xpath=”前缀)。所以不经意间——或者我应该说间接——你确实回答了问题 1 和 2。:-) 此外,你的回答让我完成了 6 个表格条目中的 5 个。【参考方案2】:

http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/java/com/thoughtworks/selenium/Selenium.html#getAttribute%28java.lang.String%29

getAttribute

java.lang.String getAttribute(java.lang.String attributeLocator)

    Gets the value of an element attribute.

    Parameters:
        attributeLocator - an element locator followed by an @ sign and then the name of the attribute, e.g. "foo@bar" 
    Returns:
        the value of the specified attribute

所以你应该说selenium.GetAttribute("locator@href") Locator 是id 或name。如果你的 a 元素没有 id 或 name,你应该使用 xpath,selenium.GetAttribute("xpath=/html/body/a/@href"),就像你已经成功尝试过的那样。

【讨论】:

感谢您对“隐藏”API 文档的参考!从Selenium website 有一个指向API doc 的链接,但它被删节了——它不包括getText 或getAttribute 等。从您的网址中,我实际上找到了 API 的 later version。

以上是关于Selenium 的 GetAttribute 方法的并发症的主要内容,如果未能解决你的问题,请参考以下文章

无法从 HTML Dom 获取值/文本。我使用了 Selenium WebDriver 的 getAttribute() 和 getText()

selenium操作测试对象

使用 Selenium 修改 innerHTML

selenium学习记录

selenium获取测试对象的内容和状态

如何在 Selenium 中获取 WebElement 的 HTML 代码