it-swarm.com.de

Selenium WebDriver: Klicken Sie mit XPath auf Elemente in einem SVG

Ich habe ein SVG-Objekt mit einigen Kreis- und Rechteckelementen. Mit dem Webtreiber kann ich auf das Haupt-svg-Objekt klicken, jedoch keines der darin enthaltenen Elemente. Das Problem scheint nur beim Klicken (oder bei einer beliebigen Mausinteraktion) zu liegen, da ich getAttribute () verwenden kann, um die Werte (width), ID, x/y, Text usw. für alles darunter zurückzugeben.

Hier ist ein Beispiel für das 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>

Und ein Beispiel, wie WebDriver versucht, mit der rechten Maustaste auf ein Rechteckelement zu klicken (und fehlschlägt):

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

Das funktioniert aber und gibt einen Wert zurück:

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

Wenn WebDriver-Fehler auftreten, ist dies normalerweise Folgendes:

    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]

Ich habe einige Zeit damit verbracht, dies zu recherchieren, und bei Selenium und SVGs scheint es ein häufiges Problem zu sein. Ich frage mich jedoch, ob es eine Problemumgehung gibt. Die einzigen Lösungen, die ich gefunden habe, sind die Interaktion mit dem SVG selbst, was ich bereits tun kann.

Ich verwende Selenium 2.28 (und versuchte es mit 2.29) mit Java + Firefox 17.

Alle Ideen sehr geschätzt.

37
jgode

Für alle Interessierten habe ich dies auf folgende Weise gelöst:

1) Ich habe dies ursprünglich unter OSX mit Firefox 17 und Selenium 2.28/29 getestet, aber herausgefunden, dass es nur (zumindest für mich) unter Windows mit Firefox 18 und Selenium 2.29 funktioniert

2) Interaktion mit SVGs mit dem Standard:

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

funktioniert nicht Sie müssen Aktionen verwenden.

3) Um mit SVG-Objekten zu interagieren, funktioniert der folgende XPath:

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

Das SVG-Objekt ist alles unter dem SVG-Element (z. B. Kreis, Rechteck, Text usw.).

Ein Beispiel für das Klicken auf ein SVG-Objekt:

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

Hinweis: Sie müssen den Pfad innerhalb der click () - Funktion aufrufen. mit:

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

funktioniert nicht.

23
jgode

Versuchen Sie diese Problemumgehung: 

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

Wenn ich beim Klicken auf einige Elemente zu viele Probleme habe, verwende ich diese Problemumgehung.

11
Ioan

Bitte schön: 

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

Auf diese Weise kannst du es schaffen.

2
user3487861

Wir konnten die ungeraden xpath select durch diese beiden Dinge vermeiden

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

Dies funktionierte auf osx und phantomjs, aber ich denke, es sollte in jedem modernen Browser in Ordnung sein.

(Wir haben den js-Treiber verwendet, um Fehler beim Kompilieren zu beheben.)

2
case nelson

Für eine JS-Lösung:

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

Ich habe verschiedene hohe Diagramme in meinem Projekt und mein Ziel war es, auf einen Abschnitt eines Diagramms zu doppelklicken, um weitere Informationen zu erhalten, und ich habe es geschafft, indem ich die folgenden Codezeilen benutzt habe mir aber CssSelector hat gut funktioniert.

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

Hier ist ein Beispiel für eine Problemumgehung in C #:

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

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