Selenium WebDriver:使用XPath单击SVG中的元素

时间:2013-01-29 21:01:09

标签: java firefox xpath selenium webdriver

我有一个带有几个圆形和矩形元素的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本身交互,我已经可以做了。

我正在使用Selenium 2.28(并尝试使用2.29)w / Java + Firefox 17。

任何想法都非常感激。

8 个答案:

答案 0 :(得分:24)

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

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

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

不起作用。

答案 1 :(得分:12)

尝试此解决方法:

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

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

答案 2 :(得分:3)

我们能够通过做这两件事来避免奇怪的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驱动程序,所以随时修复任何编译错误)

答案 3 :(得分:3)

你走了:

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

这样你就可以做到。

答案 4 :(得分: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();

答案 5 :(得分:0)

对于JS解决方案:

var selector = "//*[name()='svg']/*[name()='rect']";
browser.moveToObject(selector, 5, 5);//Move to selector object with offsets.
browser.buttonPress(null);//Left-click

答案 6 :(得分:0)

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

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

IList<IWebElement> rectElements = svgElement.FindElements(By.CssSelector("rect"));

答案 7 :(得分:-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");
相关问题