I have an SVG object with a few circle and rectangle elements. Using webdriver, I can click on the main svg object, but not any of the elements within it. The problem only s
We were able to avoid the odd xpath select by doing these two things
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);
This worked on osx and phantomjs but I think it should be ok in any modern browser.
(We used the js driver so feel free to fix any compile errors)
For anyone interested, I solved this in the following ways:
1) I was originally testing this on OSX with Firefox 17 and Selenium 2.28/29, but figured out it only works (at least for me) on Windows with Firefox 18 and Selenium 2.29
2) interacting with SVGs with the standard:
driver.findElement(By.xpath(YOUR XPATH)).click();
doesn't work. You need to use Actions.
3) to interact with SVG objects, the following XPath works:
"/*[name()='svg']/*[name()='SVG OBJECT']";
The SVG object being anything under the SVG element (e.g. circle, rect, text, etc).
An example of clicking an SVG object:
WebElement svgObject = driver.findElement(By.xpath(YOUR XPATH));
Actions builder = new Actions(driver);
builder.click(svgObject).build().perform();
Note: you need to call the path inside the click() function; using:
moveToElement(YOUR XPATH).click().build().perform();
doesn't work.
I have different high charts in my project and my aim was to double click on a section of a chart to drill down for further information and I've managed to do it using following lines of code. XPath didn't work for me but CssSelector worked just fine.
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();
Here you go:
driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("x")
driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("y")
This way you can do it.
For a JS solution:
var selector = "//*[name()='svg']/*[name()='rect']";
browser.moveToObject(selector, 5, 5);//Move to selector object with offsets.
browser.buttonPress(null);//Left-click
Here is an example of a workaround in C#:
IWebElement svgElement = Driver.FindElement(By.CssSelector("svg"));
IList<IWebElement> rectElements = svgElement.FindElements(By.CssSelector("rect"));