2015-07-20 113 views
6

我正在测试基于OpenLayers的API和Selenium WebDriver(Java版本)。如何在Selenium WebDriver中使用xPath获取SVG元素?

我想测试使用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; 
} 

EDIT 2 - 正确的XPath

// This solution from Razib is valid if the SVG is on the root note 
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']"; 

回答

8

也许您需要使用name属性中的动作Xpath。 在你的XPath使用它 -

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

那就试试下面的代码片段 -

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

Hi @Razib。我挣扎了一段时间才得到这个工作,但感谢您的提示,它现在起作用了! :) 非常感谢你!!!查看我的帖子上的编辑以获取解决方案的更多详细信息。 – joaorodr84

2

尝试@fill而不是fillOpenLayers_Geometry_Point,而不是OpenLayers.Geometry.Point

+0

嗨@peetya。感谢“OpenLayers_Geometry_Point”提示。我完全忘了用下划线代替点。无论如何,'@fill'提示不起作用。如果我使用这个xPath'// * [contains(@id,'OpenLayers_Geometry_Point')]',我得到6分。但我只想要3个红色。 – joaorodr84

0

得到公正分享范围的元素,你可以使用:

wait = new WebDriverWait(driver, 5); 
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("bla bla"))); 
相关问题