java - 如何在Selenium WebDriver中使用xPath抓取SVG元素?

标签 java selenium svg xpath css-selectors

我正在使用 Selenium WebDriver(Java 版本)测试基于 OpenLayers 的 API。

我想测试使用 OpenLayers.Control.ModifyFeature 的功能。我想点击绘制的特征 (SVG),然后拖动并检查它们是否存在、可见或隐藏。

我画了一个多边形,我选择了它。见下图:

polygon_and_handles

这些 SVG 元素的 HTML 在这里:

<svg id="OpenLayers_Layer_Vector_161_svgRoot" width="1235" height="495" viewBox="0 0 1235 495" style="display: block;">
    <g id="OpenLayers_Layer_Vector_161_root" transform="" style="visibility: visible;">
        <g id="OpenLayers_Layer_Vector_161_vroot">
            <path id="OpenLayers_Geometry_Polygon_200" d=" M 393.0000000000964,213.9999999999891 486.0000000003338,275.9999999997126 384.00000000036925,284.9999999994434 393.0000000000964,213.9999999999891 z" fill-rule="evenodd" fill="blue" fill-opacity="0.4" stroke="blue" stroke-opacity="1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="pointer" />
            <circle id="OpenLayers_Geometry_Point_619" cx="439.50000000021464" cy="244.99999999985084" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_621" cx="435.00000000035106" cy="280.49999999958163" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_623" cx="388.50000000023283" cy="249.4999999997126" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_202" cx="393.0000000000964" cy="213.9999999999891" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_203" cx="486.0000000003338" cy="275.9999999997126" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_204" cx="384.00000000036925" cy="284.9999999994434" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
        </g>
        <g id="OpenLayers_Layer_Vector_161_troot" />
    </g>
</svg>

假设我要选择红色点。

我试过:

String xpath = "//circle[contains(@id, 'OpenLayers_Geometry_Point') AND fill = '#990000']";
List<WebElement> vertices = driver.findElements(By.xpath(xpath));

但它总是返回一个空列表[]

我在这里做错了什么?有谁能帮帮我吗?

非常感谢。

编辑 1 - 函数:verticesAreVisible

在单击操作之前,我想获取元素并检查它们是否可见。我正在使用这个功能。

public static boolean verticesAreVisible(WebDriver driver, String xpath) {
    List<WebElement> list = driver.findElements(By.xpath(xpath));
    if (list.isEmpty()) {
        return false;
    }
    boolean visible = true;
    for (int i = 0; i < list.size(); i++) {
        visible = visible && list.get(i).isDisplayed();
    }
    return !verticesAreNotVisible(driver) && visible;
}

编辑 2 - 正确的 xPath

// This solution from Razib is valid if the SVG is on the root node
String xpath = "/*[name()='svg']/*[name()='circle']";
// I changed it so that any descendant is valid "//"
String xpath = "//*[name()='svg']//*[name()='circle']";
// Since I wanted only the red vertices, I added this
String xpath = "//*[name()='svg']//*[name()='circle' and @fill='#990000']";

最佳答案

可能您需要在 Xpath 中使用带有 name 属性的 Actions。 在您的 XPath 中使用它 -

"/*[name()='svg']/*[name()='SVG OBJECT']"  

然后试试下面的代码片段——

WebElement svgObj = driver.findElement(By.xpath(XPATH));
Actions actionBuilder = new Actions(driver);
actionBuilder.click(svgObj).build().perform();

关于java - 如何在Selenium WebDriver中使用xPath抓取SVG元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31520642/

相关文章:

java - 使用 SQlite 数据库在自定义基础适配器 ListView 中存储复选框状态

php - 将 SVG 转换为 PNG/JPEG/BMP 和反之亦然?

svg - 带有Illustrator的透明SVG

python - 有没有办法优化for循环? Selenium 抓取 38 页的时间太长

python - Selenium 以形式按下按钮

node.js - WebDriverJs 的 getPageSource 为我提供了一个对象而不是页面的源

c++ - 如何使用 cairo 将图像写入 SVG 文件?

java - 找不到 cfg.xml 资源 (/hibernate.cfg.xml)

java - 更新 jar 中的文件会抛出 ZipException

java - 尝试运行 JCuda 示例时 java.library.path 中没有 JCudaRuntime-0.9.2-windows-x86_64