web-dev-qa-db-fra.com

Selenium WebDriver: cliquer sur les éléments d'un SVG avec XPath

J'ai un objet SVG avec quelques éléments de cercle et de rectangle. À l'aide de webdriver, je peux cliquer sur l'objet svg principal, mais aucun des éléments qu'il contient. Le problème ne semble concerner que le clic (ou toute interaction de la souris), car je peux utiliser getAttribute () pour renvoyer la ou les valeurs de largeur, ID, x/y, texte, etc.

Voici un exemple de code HTML:

    <div id="canvas">
        <svg height="840" version="1.1" width="757" xmlns="http://www.w3.org/2000/svg" style="overflow: hidden; position: relative;">
            <image x="0" y="0" width="757" height="840" preserveAspectRatio="none">
            <circle cx="272.34" cy="132.14">
            <rect x="241.47" y="139.23">
            <text style="text-anchor: middle; x="272.47" y="144.11">
        </svg>
    </div>

Et un exemple de WebDriver qui tente de cliquer avec le bouton droit de la souris sur un élément rectangle (et qui échoue):

    WebElement mapObject = driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']"));
    Actions builder = new Actions(driver);
    builder.contextClick(mapObject).perform();

Mais cela fonctionne et renvoie une valeur:

    driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']")).getAttribute("x");    

Lorsque WebDriver se trompe, c'est généralement ceci:

    org.openqa.Selenium.WebDriverException: '[JavaScript Error: "a.scrollIntoView is not a function" {file: "file:///var/folders/sm/jngvd6s97ldb916b7h25d57r0000gn/T/anonymous490577185394048506webdriver-profile/extensions/[email protected]/components/synthetic_mouse.js" line: 8544}]' when calling method: [wdIMouse::move]

J'ai passé un peu de temps à chercher cela et il semble que ce soit un problème assez commun avec Selenium et les SVG, mais je me demande s'il existe une solution de contournement. Les seules solutions que j'ai trouvées sont une interaction avec le SVG lui-même, ce que je peux déjà faire.

J'utilise Selenium 2.28 (et essayé 2.29) avec Java + Firefox 17.

Toutes les idées grandement appréciées.

37
jgode

Pour toute personne intéressée, j'ai résolu ce problème de la manière suivante:

1) J'essayais à l'origine de ceci sur OSX avec Firefox 17 et Selenium 2.28/29, mais je me suis dit que cela ne fonctionnait que (du moins pour moi) sous Windows avec Firefox 18 et Selenium 2.29

2) interagir avec les SVG avec le standard:

driver.findElement(By.xpath(YOUR XPATH)).click();

ne fonctionne pas. Vous devez utiliser des actions.

3) pour interagir avec les objets SVG, le XPath suivant fonctionne:

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

L'objet SVG se trouvant sous l'élément SVG (par exemple, un cercle, un rect, un texte, etc.).

Un exemple de clic sur un objet SVG:

WebElement svgObject = driver.findElement(By.xpath(YOUR XPATH));
Actions builder = new Actions(driver);
builder.click(svgObject).build().perform();

Remarque: vous devez appeler le chemin à l'intérieur de la fonction click (). en utilisant:

moveToElement(YOUR XPATH).click().build().perform();

ne fonctionne pas.

23
jgode

Essayez cette solution de contournement: 

WebElement mapObject = driver.findElement(By.xpath("//*[name()='svg']/*[name()='rect']"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", mapObject);

Lorsque j’ai trop de problèmes avec certains éléments en essayant de cliquer dessus, j’utilise cette solution de contournement.

11
Ioan

Voici: 

driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("x") 
driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("y") 

De cette façon, vous pouvez le faire.

2
user3487861

Nous avons pu éviter le xpath impair sélectionné en faisant ces deux choses

WebElement mapObject = (WebElement) driver.executeScript('return document.querySelector(arguments[0])', "svg rect")

((JavascriptExecutor) driver).executeScript("arguments[0].dispatchEvent(new MouseEvent('click', {view: window, bubbles:true, cancelable: true}))", mapObject);

Cela a fonctionné sur osx et phantomjs mais je pense que ça devrait aller dans n'importe quel navigateur moderne.

(Nous avons utilisé le pilote js, alors n'hésitez pas à corriger les erreurs de compilation)

2
case nelson

Pour une solution JS:

var selector = "//*[name()='svg']/*[name()='rect']";
browser.moveToObject(selector, 5, 5);//Move to selector object with offsets.
browser.buttonPress(null);//Left-click
0
atahan

Mon projet comporte différentes cartes hautes et mon objectif était de double-cliquer sur une section d'une carte pour obtenir des informations supplémentaires. J'ai réussi à le faire en utilisant les lignes de code suivantes . XPath n'a pas fonctionné. moi mais CssSelector a bien fonctionné.

var elementToClick= Browser.Driver.FindElementEx(By.CssSelector("#highcharts-0 > svg > g.highcharts-series-group > g.highcharts-series.highcharts-tracker > path:nth-child(1)"), 10);
Actions action = new Actions(Browser.Driver);
action.Click(elementToClick).Build().Perform();
action.DoubleClick(elementToClick).Build().Perform();
0
Vish

Voici un exemple de solution de contournement en C #:

IWebElement svgElement = Driver.FindElement(By.CssSelector("svg"));

IList<IWebElement> rectElements = svgElement.FindElements(By.CssSelector("rect"));
0