2015-07-20 9 views
6

Sto testando un'API, basata su OpenLayers, con selenio WebDriver (versione Java).Come usare xPath in Selenium WebDriver per afferrare elementi SVG?

Voglio testare una funzionalità che utilizza OpenLayers .Control.ModifyFeature. Voglio fare clic su caratteristiche disegnate (SVG), trascinare e controllare se sono presenti, visibili o nascosti.

Ho disegnato un poligono e l'ho selezionato. Vedere l'immagine qui sotto:

polygon_and_handles

Il codice HTML di questi elementi SVG è qui:

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

Supponiamo che voglio selezionare i punti rossi.

ho fatto questo:

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

ma restituisce sempre una lista vuota [].

Cosa sto facendo di sbagliato qui? Qualcuno potrebbe aiutarmi, per favore?

Grazie mille.

EDIT 1 - Funzione: verticesAreVisible

Prima le azioni di clic, voglio ottenere gli elementi e verificare se sono visibili. Sto usando questa funzione.

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 corrette

// 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']"; 

risposta

8

Potrebbe essere necessario utilizzare le azioni con attributo name in Xpath. Nella vostra XPath usarlo -

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

quindi provare il seguente frammento di codice -

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

Ciao @Razib. Ho faticato un po 'di tempo per farlo funzionare, ma grazie al tuo suggerimento, ora funziona! :) Grazie mille!!! Vedi le modifiche sul mio post per maggiori dettagli sulla soluzione. – joaorodr84

2

Prova @fill invece di fill e OpenLayers_Geometry_Point invece di OpenLayers.Geometry.Point.

+0

Hi @peetya. Grazie per il suggerimento "OpenLayers_Geometry_Point". Ho completamente dimenticato di sostituire punti con trattini bassi. Ad ogni modo, il suggerimento "@fill" non ha funzionato. Se utilizzo questo xPath '// * [contiene (@id,' OpenLayers_Geometry_Point ')]', ottengo i 6 punti. Ma voglio solo il 3 rosso. – joaorodr84

0

per ottenere solo visibile elementi è possibile utilizzare:

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