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()