48

我有一个带有一些圆形和矩形元素的 SVG 对象。使用 webdriver,我可以单击主 svg 对象,但不能单击其中的任何元素。问题似乎只在于单击(或任何鼠标交互),因为我可以使用 getAttribute() 来返回其下任何内容的宽度、ID、x/y、文本等的值。

下面是一个 HTML 示例:

    <div id="canvas">
        <svg height="840" version="1.1" width="757" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; position: relative;">
            <image x="0" y="0" width="757" height="840" preserveAspectRatio="none">
            <circle cx="272.34" cy="132.14">
            <rect x="241.47" y="139.23">
            <text style="text-anchor: middle; x="272.47" y="144.11">
        </svg>
    </div>

还有一个 WebDriver 尝试右键单击矩形元素的示例(并且失败):

    WebElement mapObject = driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']"));
    Actions builder = new Actions(driver);
    builder.contextClick(mapObject).perform();

但这有效并返回一个值:

    driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']")).getAttribute("x");    

当 WebDriver 出错时,通常是这样的:

    org.openqa.selenium.WebDriverException: '[JavaScript Error: "a.scrollIntoView is not a function" {file: "file:///var/folders/sm/jngvd6s97ldb916b7h25d57r0000gn/T/anonymous490577185394048506webdriver-profile/extensions/fxdriver@googlecode.com/components/synthetic_mouse.js" line: 8544}]' when calling method: [wdIMouse::move]

我花了一些时间研究这个问题,这似乎是 Selenium 和 SVG 的一个常见问题,但我想知道是否有解决方法。我发现的唯一解决方案是与 SVG 本身交互,我已经可以做到。

我正在使用带有 Java + Firefox 17 的 Selenium 2.28(并尝试过 2.29)。

任何想法都非常感谢。

4

8 回答 8

31

对于任何有兴趣的人,我通过以下方式解决了这个问题:

1) 我最初是在 OSX 上使用 Firefox 17 和 Selenium 2.28/29 进行测试,但发现它只能在使用 Firefox 18 和 Selenium 2.29 的 Windows 上工作(至少对我而言)

2) 使用标准与 SVG 交互:

driver.findElement(By.xpath(YOUR XPATH)).click();

不起作用。您需要使用操作。

3) 与 SVG 对象交互,以下 XPath 起作用:

"/*[name()='svg']/*[name()='SVG OBJECT']";

SVG 对象是 SVG 元素下的任何东西(例如圆形、矩形、文本等)。

单击 SVG 对象的示例:

WebElement svgObject = driver.findElement(By.xpath(YOUR XPATH));
Actions builder = new Actions(driver);
builder.click(svgObject).build().perform();

注意:需要在click()函数里面调用路径;使用:

moveToElement(YOUR XPATH).click().build().perform();

不起作用。

于 2013-02-07T22:00:21.110 回答
12

试试这个解决方法:

WebElement mapObject = driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", mapObject);

每当我在尝试单击某些元素时遇到太多问题时,我都会使用此解决方法。

于 2013-01-31T13:02:21.243 回答
4

通过做这两件事,我们能够避免奇怪的 xpath 选择

WebElement mapObject = (WebElement) driver.executeScript('return document.querySelector(arguments[0])', "svg rect")

((JavascriptExecutor) driver).executeScript("arguments[0].dispatchEvent(new MouseEvent('click', {view: window, bubbles:true, cancelable: true}))", mapObject);

这适用于 osx 和 phantomjs,但我认为在任何现代浏览器中都应该没问题。

(我们使用了 js 驱动,所以请随时修复任何编译错误)

于 2014-01-28T19:06:42.070 回答
3

干得好:

driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("x") 
driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("y") 

这样你就可以做到。

于 2014-04-03T10:29:37.553 回答
1

对于 JS 解决方案:

var selector = "//*[name()='svg']/*[name()='rect']";
browser.moveToObject(selector, 5, 5);//Move to selector object with offsets.
browser.buttonPress(null);//Left-click
于 2016-08-15T21:07:21.003 回答
0

我的项目中有不同的高位图表,我的目标是双击图表的一部分以深入了解更多信息,我已经设法使用以下代码行来做到这一点。XPath 对我不起作用,但 CssSelector 工作得很好。

var elementToClick= Browser.Driver.FindElementEx(By.CssSelector("#highcharts-0 > svg > g.highcharts-series-group > g.highcharts-series.highcharts-tracker > path:nth-child(1)"), 10);
Actions action = new Actions(Browser.Driver);
action.Click(elementToClick).Build().Perform();
action.DoubleClick(elementToClick).Build().Perform();
于 2016-05-09T12:29:15.940 回答
0

以下是 C# 中的解决方法示例:

IWebElement svgElement = Driver.FindElement(By.CssSelector("svg"));

IList<IWebElement> rectElements = svgElement.FindElements(By.CssSelector("rect"));
于 2018-08-02T10:41:03.427 回答
-2
actual = driver.findElement(By.xpath(
"//div[contains(@class,'review-action')]//div[contains(@class,'rating')]/*[name()='svg'][1]/*[name()='g']/*[name()='path'][2]"))
.getAttribute("stroke");
于 2019-10-01T08:57:03.870 回答