2015-07-20 3 views
6

Я тестирую API на основе OpenLayers, с Selenium WebDriver (версия Java).Как использовать xPath в Selenium WebDriver для захвата элементов SVG?

Я хочу протестировать функциональность, которая использует OpenLayers .Control.ModifyFeature. Я хочу нажать на нарисованные объекты (SVG), затем перетащить и проверить, присутствуют ли они, видимы или скрыты.

Я нарисовал многоугольник, и я выбрал его. Смотрите изображение ниже:

polygon_and_handles

HTML, SVG этих элементов здесь:

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

Но он всегда возвращает пустой список [].

Что я здесь делаю неправильно? Может ли кто-нибудь помочь мне, пожалуйста?

Большое спасибо.

EDIT 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

Привет @Razib. Я изо всех сил пытался заставить это работать, но благодаря вашему совету, он работает сейчас! :) Большое спасибо!!! См. Изменения в моем сообщении для получения более подробной информации о решении. – joaorodr84

2

Попробуйте @fill вместо fill и OpenLayers_Geometry_Point вместо OpenLayers.Geometry.Point.

+0

Hi @peetya. Спасибо за подсказку OpenLayers_Geometry_Point. Я полностью забыл заменить точки символами подчеркивания. Во всяком случае, подсказка @fill не работает. Если я использую этот xPath '// * [содержит (@id,' OpenLayers_Geometry_Point ')]', я получаю 6 баллов. Но я хочу только 3 красных. – joaorodr84

0

Чтобы получить только элементы, которые вы Запись видна можно использовать:

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