Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selenium WebDriver: clicking on elements within an SVG using XPath

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.

like image 640
jgode Avatar asked Jan 29 '13 21:01

jgode


People also ask

How do I write xpath for SVG elements in Selenium?

To create a xpath for a svg element, we have the syntax as //*[local-name()='svg']. Here, data-icon is an attribute of the svg tag element which is added accompanied with @ symbol. The [local-name()='path'] is included since it is the child of the svg tagname.

What is SVG in Selenium?

SVG stands for Scalable Vector Graphics. It is mainly used for vector-type diagrams like bar charts, pie charts, scalable icons, scalable logos, and other design diagrams. An SVG viewer is used to render the elements. Usually, SVG elements are not captured by the selenium IDE.

How do I use xpath to find elements?

We can find an element using the xpath locator with Selenium webdriver. To identify the element with xpath, the expression should be //tagname[@attribute='value']. To identify the element with xpath, the expression should be //tagname[@class='value']. There can be two types of xpath – relative and absolute.


1 Answers

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.

like image 126
jgode Avatar answered Oct 01 '22 05:10

jgode