javascript - 如何使用 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)"></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