2015-07-20 25 views
6

Tôi đang thử nghiệm một API, dựa trên OpenLayers, với Selenium WebDriver (phiên bản Java).Làm thế nào để sử dụng xPath trong Selenium WebDriver để lấy các phần tử SVG?

Tôi muốn thử nghiệm một chức năng sử dụng OpenLayers .Control.ModifyFeature. Tôi muốn nhấp vào các đối tượng địa lý được vẽ (SVG), sau đó kéo và kiểm tra xem chúng có mặt, hiển thị hay ẩn hay không.

Tôi đã vẽ một đa giác và tôi đã chọn hình đa giác. Xem hình dưới đây:

polygon_and_handles

HTML của các yếu tố SVG là ở đây:

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

Giả sử tôi muốn chọn những điểm màu đỏ.

Tôi đã làm điều này:

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

Nhưng nó luôn luôn trả về một danh sách trống [].

Tôi đang làm gì sai ở đây? Ai có thể giúp tôi được không?

Cảm ơn rất nhiều.

EDIT 1 - Chức năng: verticesAreVisible

Trước những hành động nhấp vào, tôi muốn để có được các yếu tố và kiểm tra xem họ có thể nhìn thấy. Tôi đang sử dụng chức năng này.

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 - Đúng 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']"; 

Trả lời

8

Có thể bạn cần sử dụng các hành động với thuộc tính name trong Xpath. Trong XPath của bạn sử dụng nó -

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

Sau đó thử đoạn mã sau đây -

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

Xin chào @Razib. Tôi đã vật lộn một chút thời gian để làm việc này, nhưng nhờ vào mẹo của bạn, nó hoạt động ngay bây giờ! :) Cảm ơn nhiều!!! Xem các chỉnh sửa trên bài đăng của tôi để biết thêm chi tiết về giải pháp. – joaorodr84

2

Hãy thử @fill thay vì fillOpenLayers_Geometry_Point thay vì OpenLayers.Geometry.Point.

+0

Hi @peetya. Cảm ơn mẹo 'OpenLayers_Geometry_Point'. Tôi hoàn toàn quên để thay thế dấu chấm với dấu gạch dưới. Dù sao, mẹo '@fill' không hoạt động. Nếu tôi sử dụng xPath này '// * [chứa (@id,' OpenLayers_Geometry_Point ')]', tôi nhận được 6 điểm. Nhưng tôi chỉ muốn 3 màu đỏ. – joaorodr84

0

Để có được chỉ visibile yếu tố mà bạn có thể sử dụng:

wait = new WebDriverWait(driver, 5); 
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("bla bla"))); 
Các vấn đề liên quan