问题 InvalidSelectorException使用CSS选择器来定位“data-”属性标注元素


动机

利用Selenium的CSS选择器机制以及CSS属性选择器和HTML5 data- 自定义属性,用于解决元素的特定挂钩。

问题

使用上面的方法来定位一个分配了CSS类名的元素和 data- 属性,抛出以下异常:

Caused by: org.openqa.selenium.remote.ErrorHandler$UnknownServerException: The given selector .gs-a-btn["data-value"] is either invalid or does not result in a WebElement. The following error occurred:
[Exception... "An invalid or illegal string was specified"  code: "12" nsresult: "0x8053000c (NS_ERROR_DOM_SYNTAX_ERR)"  location: "file:///C:/DOCUME~1/eliranm/LOCALS~1/Temp/anonymous6109849275533680625webdriver-profile/extensions/fxdriver@googlecode.com/components/driver_component.js Line: 5956"]
Build info: version: '2.23.1', revision: '17143', time: '2012-06-08 18:59:28'
System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_31'
Driver info: driver.version: unknown
    at <anonymous class>.<anonymous method>(file:///C:/DOCUME~1/eliranm/LOCALS~1/Temp/anonymous6109849275533680625webdriver-profile/extensions/fxdriver@googlecode.com/components/driver_component.js:6537)

相关守则

public void previous(String type) {
    By cssSelector = By.cssSelector(".gs-a-btn[data-value='" + type + "']");
    driver.findElement(cssSelector).click();
}

我试过了什么

  • 用属性选择器查询中的转义双引号替换单引号。
  • 指定属性选择器而不是属性值选择器,即 ".gs-a-btn[\"data-value\"]" 宁 ".gs-a-btn[data-value='" + type + "']"
  • 查找引用中的信息,例如 硒参考,对CSS属性选择器的任何限制。该文件明确指出:

    目前,css选择器定位器支持所有css1,css2和css3   选择器除了css3中的命名空间,一些伪类(:nth-of-type,    :nth-last-of-type:first-of-type:last-of-type:only-of-type,    :visited:hover:active:focus:indeterminate)和伪   元素(::first-line::first-letter::selection::before,    ::after)。


11314
2018-06-19 13:14


起源

您是否尝试过替换或转义中的引号? type 值? - BoltClock♦
是的,没有用。现在继续调查,这似乎是一个时间问题,如选择 By.cssSelector 使用属性选择器似乎比仅仅使用慢 By.className。它偶尔会失败。 - Eliran Malka
@EliranMalka By.className 内部使用(至少在Firefox上) document.getElementsByClassName() (缓存)因此应该几乎是即时的。 By.cssSelector 使用 document.querySelector() 和 document.querySelectorAll() 这需要一段时间来解析和处理。如果这是一个时间问题,我偶尔会发现 NoSuchElementException(可以修复),不是很奇怪 UnknownServerException。 - Petr Janeček


答案:


您链接的引用是Selenium IDE。

Selenium WebDriver文档主要在官方网站上找到 这里(基本用法) 和 这里(高级用法), 但也 这里 (a.k.a“尚未进入文档的内容” - 特别是 常问问题高级用户交互 以及关于Selenium internals的大量信息。该 主要信息来源 当然是 的JavaDoc


无论如何。 Selenium支持的CSS选择器是它下面的浏览器支持的(除了Selenium RC有一个Sizzle CSS引擎),所以你的例子肯定会有用。使用这个简单的测试页面:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8" />
    </head>
    <body>
        <input type="text" id="myInput" class="field" data-test="testytest" />
    </body>
</html>

我能够在IE 8(!!)和Firefox 13中成功运行它:

WebDriver driver = new FirefoxDriver();
driver.get("path to the file");
By cssSelector = By.cssSelector(".field[data-test='testytest']");
        // or By.cssSelector(".field[data-test=testytest]")
        // or By.cssSelector(".field[data-test]")
driver.findElement(cssSelector).sendKeys("Hello");
driver.quit();

所以我挖了更多。如果您尝试在FF13 Firebug控制台中运行以下任何一项:

document.querySelector(".field[data-test]")
document.querySelector(".field[data-test=testytest]")
document.querySelector(".field[data-test='testytest']")

它返回正确的元素。但是,任何这个:

document.querySelector(".field['data-test']")
document.querySelector(".field[\"data-test\"]")

失败并显示“指定了无效或非法字符串”错误(在Firefox和IE中)都是正确的(因此,您获得的错误消息是正确的,选择器无效)。

请再试一次,摆脱 任何 引号,确保你的 type 变量不包含任何引号或反斜杠或诸如此类的东西。该结构应该绝对有效。如果没有,发布新的异常堆栈跟踪,以便我们可以看到导致它的确切选择器。


10
2017-07-01 17:29



没有什么可惊讶的 - IE8支持所有CSS2.1选择器(以及带有一些奇怪错误的IE7)。 - BoltClock♦
@BoltClock完全正确。这就是为什么我对这个问题感到困惑的原因。显示的例外是一个明显的错误,但在该片段中 Relevant code 问题部分应该可行。我真的很期待新的堆栈跟踪。 - Petr Janeček
大。多谢一堆,你是绝对正确的 - 这应该有效,而且我似乎有两个问题: 1。 计时问题作为测试流程的一部分,即元素在访问时没有附加,所以我使用重复的断言来调试它,并且 2。 双引号表现出我不知道的错误。 - Eliran Malka
关于时间 - 最常见的事情是 隐式等待和需要的地方,显式等待。 - Petr Janeček
@Slanec,我最近了解了这个,这个链接让事情变得更加明朗。谢谢。 - Eliran Malka