Selenium WebDriver: clicking on elements within an SVG using XPath
Solution 1
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.
Solution 2
Try this workaround :
WebElement mapObject = driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", mapObject);
Whenever I have too many problems with some elements while trying to click them, I use this workaround.
Solution 3
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)
Solution 4
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.
Solution 5
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
Related videos on Youtube
![jgode](https://i.stack.imgur.com/EMxlL.jpg?s=256&g=1)
jgode
Updated on July 09, 2022Comments
-
jgode almost 2 years
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 seems to be with clicking (or any mouse interaction), as I can use getAttribute() to return the value(s) of width, ID, x/y, text, etc, for anything under it.
Here is an example of the 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>
And an example of WebDriver trying to right click a rectangle element (and failing):
WebElement mapObject = driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']")); Actions builder = new Actions(driver); builder.contextClick(mapObject).perform();
But this works and returns a value:
driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']")).getAttribute("x");
When WebDriver errors, it's usually this:
org.openqa.selenium.WebDriverException: '[JavaScript Error: "a.scrollIntoView is not a function" {file: "file:///var/folders/sm/jngvd6s97ldb916b7h25d57r0000gn/T/anonymous490577185394048506webdriver-profile/extensions/[email protected]/components/synthetic_mouse.js" line: 8544}]' when calling method: [wdIMouse::move]
I've spent some time researching this and it seems to be a somewhat common issue with Selenium and SVGs, however I'm wondering if there is a workaround. The only solutions I've found are interacting with the SVG itself, which I can already do.
I'm using Selenium 2.28 (and tried 2.29) w/ Java + Firefox 17.
Any ideas greatly appreciated.
-
Alex Okrushko over 11 yearsMaybe unrelated, but why not to use
driver.findElement(By.xpath("//svg/rect")).getAttribute("x");
? -
jgode over 11 yearsBecause in order to interact with an SVG via XPath in Selenium, you have to call the name() or local-name() methods. I don't know why, but, without that, it doesn't work.
-
-
jgode over 11 yearsSo, there's progress here. First, using JavascriptExecutor no longer throws the error I was getting in WebDriver when interacting with an SVG object. However, when I run the test, it says it clicks/hovers/etc successfully, but I don't see the interaction happen on screen. In theory, if the test successfully clicks on a rect or circle, I should see a menu pop up for the element being clicked.. but that doesn't happen, even though WebDriver says it did so. Also worth mentioning, "arguments[0].click();" didn't work for me, but .click and .click; does. P.S. Thanks for the reply.
-
Oliver Bock over 11 yearsThe XPath check using name() is necessary because SVG DOM nodes are in a different namespace.
-
Oliver Bock over 11 yearsAlso, I could get this to work in FF17.0.1, but I did need to use Actions, a straight WebElement.click() failed.
-
Mrchief almost 10 yearsYou don't need xpath necessarily, at least for the JS driver. It works with any element, even if you find them by CSS or Id or however.
-
Febian Shah over 9 years@jgode did you find a solution? I have the same problem where it executes without an error but I don't see the webpage navigate to the new page.
-
jgode over 9 years@FebianShah, yes.. see my above post where I describe how I got it working in Firefox: stackoverflow.com/a/14761832/2023074 Also, it's worth noting that in IE it's possible to target SVG elements by their RaphaelID, which makes it easier. Although in my case, because I have to test SVG pages in multiple browsers, I ended up using coordinates, which I hate for automation, but it was the most stable way.
-
joaorodr84 over 8 yearssimple and effective on ChromeDriver, in Ubuntu... thanks a lot! :)
-
Sakshi Singla over 7 yearsI get 'Element is not clickable at point (231.1666717529297, 312.04998779296875). Other element would receive the click:' exception when I try to click on a circle in my svg. Any idea bout this?
-
jgode over 7 yearsI'd need a little more context to understand why that doesn't work. Code, environment, etc.
-
dlauzon about 5 yearsThis dispatchEvent with the specified parameters is the only solution that worked for me on a deeply nested SVG
<text>
element. -
spacepickle over 4 yearsThere is no context to this answer and, even if it answers the original question, it leaves only a new question of why this then works. Can you give some reasoning of what the answer is telling us and why it works?
-
Ashok kumar Ganesan over 4 yearsWhat is the reason that it does not work as normal tags, why this much complication for svg
-
jgode over 4 years@AshokkumarGanesan this issue is from 6 years ago, so things have evolved since then with how we can interact with svgs, and how browsers treat them with regards to automation. One issue I still see sometimes, since I still test products with svgs, is, depending on how the developers have configured them, they may not be visible to the DOM. Otherwise, I don't know that the same workarounds are still necessary.
-
Ashok kumar Ganesan over 4 yearsAlright,is the svg is a special tag apart from div span etc.,