0

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

Steve Staple
  • 2,983
  • 9
  • 38
  • 73
  • 6
    SVG elements do not support the click() method (that's only for html elements). You'd have to fire a click event: https://stackoverflow.com/questions/7696010/how-to-fire-js-event-in-selenium – Robert Longson Jul 20 '18 at 13:23
  • @Robert Longson My Common.clickElement procedure uses this: JavascriptExecutor executor = (JavascriptExecutor) driver; executor.executeScript("arguments[0].click();", element); myPrint(thisClass + " element clicked."); - isn't that the same? – Steve Staple Jul 20 '18 at 13:26
  • @RobertLongson I cannot see anything I can use in the linked article, except it also uses ExecuteScript? – Steve Staple Jul 20 '18 at 13:45
  • @RobertLongson "Take at look at this StackOverflow question for inspiration" - did you forget to add the link? – Steve Staple Jul 20 '18 at 13:57
  • @RobertLongson I have read https://stackoverflow.com/questions/7696010/how-to-fire-js-event-in-selenium, but I do not see anything there I can use. [your fire event javascript code] is hardly an answer! – Steve Staple Jul 20 '18 at 14:19
  • @RobertLongson I am afraid yours was the wrong answer. My element did respond to a click, when I switched to: Actions action = new Actions(driver); action.click(path).build().perform(); – Steve Staple Jul 20 '18 at 14:44
  • Feel free to write your own answer if you've solved the problem. – Robert Longson Jul 20 '18 at 14:48
  • @RobertLongson I think "SVG elements do not support the click() method" is misleading. This element was part of an SVG element? – Steve Staple Jul 20 '18 at 15:18
  • It happens to be true per the SVG specification. Firefox implements the specification as written in this regard as does Edge. Maybe the browser you are using is non-standard or maybe the element isn't actually an SVG element. – Robert Longson Jul 20 '18 at 16:03
  • @RobertLongson I am using Firefox Quantum browser, but my element is not the SvgStruct, it is a child of it. – Steve Staple Jul 20 '18 at 16:12
  • Firefox quantum does not support calling click() on an SVG element or a child of an SVG element unless that child is also an HTML child of a foreignObject element (in which case it isn't an SVG element at all). – Robert Longson Jul 20 '18 at 16:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/176429/discussion-between-robert-longson-and-steve-staple). – Robert Longson Jul 20 '18 at 16:23

0 Answers0