首页 > 解决方案 > 如何使用 Selenium WebDriver 单击此 SVG 元素?

问题描述

我正在尝试使用 Selenium 和 Java 对 SVG 元素进行单击。它在 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)">&lt;/text>
</g>

我首先找到 svgStruct 元素。然后我寻找它<g class="node"下面的元素。我实际上想单击其中之一。实验似乎表明,被点击的实际元素是其<path下方的第二个元素。所以,我深入研究,然后尝试执行点击。首先,我确定它是可点击的——它说它是可点击的。

new WebDriverWait(driver, timeOut).until(ExpectedConditions.elementToBeClickable(element));

在确定我的元素是可点击的之后,我尝试发送点击。

我得到一个错误的回应:

TypeError: arguments[0].click is not a function

那么发生了什么?

为什么它首先告诉我元素是可点击的,然后它不是?

我正在使用 Firefox Quantum 浏览器 61.0.1(64 位)、Selenium 3.8.1

整个过程如下所示:

    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;
}

我的 Common.clickElement 过程使用这个:

JavascriptExecutor executor = (JavascriptExecutor) driver; executor.executeScript("arguments[0].click();"

输出确认我正在尝试单击具有正确属性的元素:

{d=M0,0a30,30,0,1,0,0,60h0a30,30,0,1,0,0,-60Z, fill=#904098}

更新:

我设法通过使用以下几行来单击元素来使其工作:

Actions action = new Actions(driver);
action.click(path).build().perform();

这个想法来自这里:Selenium WebDriver: click on elements within an SVG using XPath

标签: javascripthtmlseleniumsvg

解决方案


推荐阅读