I am trying to perform a click on an SVG element using Selenium & Java. It looks something like this in HTML:
<svg style="position: relative; overflow: visible; margin-top: 50px; margin-left: 20px; min-width: 100%; height: 450px; width: 227.5px;" id="svgstruct" width="100%" height="100%">
<path class="link" fill="none" stroke-width="3px" d="M 157.5 330 Q 157.5 303.3333333333333, 115 250" stroke="#904098"></path>
<path class="link" fill="none" stroke-width="3px" d="M 72.5 330 Q 72.5 303.3333333333333, 115 250" stroke="#904098"></path>
<path class="link" fill="none" stroke-width="3px" d="M 115 220 Q 115 193.33333333333334, 115 140" stroke="#904098"></path>
<path class="link" fill="none" stroke-width="3px" d="M 115 110 Q 115 83.33333333333333, 72.5 30" stroke="#904098"></path>
<path class="link" fill="none" stroke-width="3px" d="M 30 110 Q 30 83.33333333333333, 72.5 30" stroke="#904098"></path>
<path d="M 72.5 0 l 0 -50" stroke-width="3px" stroke="#904098"></path>
<g class="node" cursor="pointer" transform="translate(72.5,0)">
<path d="M0,-10a40,40,0,1,0,0,80h0a40,40,0,1,0,0,-80Z" fill="rgba(144,64,152,0.3)"></path>
<path d="M0,0a30,30,0,1,0,0,60h0a30,30,0,1,0,0,-60Z" fill="#904098"></path>
<text fill="#fff" font-size="32px" font-family="mapicons" transform="translate(0,30)"></text>
</g>
I begin by finding the svgStruct element.
Then I look for the <g class="node"
elements beneath this.
I actually want to click on one of these. Experiment seems to show that the actual element that gets clicked is the second <path
element beneath this.
So, I drill down to that, then try to perform a click.
First, I ascertain that it is clickable - and it says it is.
new WebDriverWait(driver, timeOut).until(ExpectedConditions.elementToBeClickable(element));
Having ascertained that my element is clickable, I try & send a click.
I get an error in response:
TypeError: arguments[0].click is not a function
So what is going on?
Why is it telling me first the element is clickable, and then it is not?
I am using Firefox Quantum browser 61.0.1 (64-bit), Selenium 3.8.1
The whole procedure looks like this:
public boolean clickComponent() {
// Get the source value of the svg and navigate to the graph
Common.myPrint(thisClass + " findComponents executing... ");
Common.myPrint(thisClass + " find svgstruct ");
List<WebElement> svgStructs = driver.findElements(By.id("svgstruct"));
Common.myPrint(thisClass + " svgStructs count: " + svgStructs.size());
for (WebElement element : svgStructs) {
// select an element
Common.myPrint(thisClass + " attributes for svgStruct");
Common.getAllAttributes(element, driver);
Common.myPrint(thisClass + " find nodes ");
// look for <g class = node
List<WebElement> nodes = element.findElements(By.className("node"));
int noOfNodes = nodes.size();
Common.myPrint(thisClass + " nodes count: " + nodes.size());
int index = 0;
for (WebElement node : nodes) {
index++;
// do last node only!
if (index == noOfNodes) {
if (node.isDisplayed()) {
Common.myPrint(thisClass + " attributes for node: " + index);
String attr = Common.getAllAttributes(node, driver);
Common.myPrint(thisClass + " attr: " + attr);
if (attr.contains("translate")) {
// look for second <path element under this
List<WebElement> paths = node.findElements(By.tagName("path"));
Common.myPrint(thisClass + " paths count: " + paths.size());
int j=0;
for (WebElement path : paths) {
// select second one of these
j++;
if(j==2) {
String attr2 = Common.getAllAttributes(path, driver);
return Common.clickElement(path, driver);
}
}
}
}
}
}
}
return false;
}
My Common.clickElement procedure uses this:
JavascriptExecutor executor = (JavascriptExecutor) driver; executor.executeScript("arguments[0].click();"
Output confirms that I am trying to click element with the correct attributes:
{d=M0,0a30,30,0,1,0,0,60h0a30,30,0,1,0,0,-60Z, fill=#904098}
Update:
I managed to get this working by using the following lines to click the element instead:
Actions action = new Actions(driver);
action.click(path).build().perform();
The idea came from here: Selenium WebDriver: clicking on elements within an SVG using XPath