Je teste une API, basée sur OpenLayers
, avec Selenium WebDriver
(version Java).
Je veux tester une fonctionnalité qui utilise OpenLayers
. Control.ModifyFeature. Je veux cliquer sur les entités dessinées (SVG), les faire glisser ensuite et vérifier si elles sont présentes, visibles ou masquées.
J'ai dessiné un polygone et je l'ai sélectionné. Voir l'image ci-dessous:
Le code HTML de ces éléments SVG est ici:
<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>
Supposons que je veuille sélectionner les points rouges.
J'ai fait ça:
String xpath = "//circle[contains(@id, 'OpenLayers_Geometry_Point') AND fill = '#990000']";
List<WebElement> vertices = driver.findElements(By.xpath(xpath));
Mais il retourne toujours une liste vide []
.
Qu'est-ce que je fais mal ici? Quelqu'un pourrait-t'il m'aider s'il vous plaît?
Merci beaucoup.
EDIT 1 - Fonction: verticesAreVisible
Avant de cliquer sur les actions, je souhaite obtenir les éléments et vérifier s'ils sont visibles. J'utilise cette fonction.
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 - Corrigez 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']";
Vous devrez peut-être utiliser l'attribut Actions avec name
dans Xpath
. Dans votre XPath, utilisez-le -
"/*[name()='svg']/*[name()='SVG OBJECT']"
Ensuite, essayez l'extrait de code suivant -
WebElement svgObj = driver.findElement(By.xpath(XPATH));
Actions actionBuilder = new Actions(driver);
actionBuilder.click(svgObj).build().perform();
Essayez @fill
au lieu de fill
et OpenLayers_Geometry_Point
au lieu de OpenLayers.Geometry.Point
.
Pour obtenir uniquement des éléments visibles, vous pouvez utiliser:
wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("bla bla")));
We also faced the similar issue in one of the screens where we have SVG implementation, I resolved using action class.
Action Class Package :
Java.lang.Object
org.openqa.Selenium.interactions.Actions
Sample Code :
WebElement svgObject= driver.findElement(By.xpath(XPATH));
Actions actionBuilderObj = new Actions(driver);
actionBuilderObj .click(svgObject).build().perform();