it-swarm.com.ru

Selenium WebDriver: нажатие на элементы в SVG с использованием XPath

У меня есть объект SVG с несколькими элементами окружности и прямоугольника. Используя веб-драйвер, я могу щелкнуть по основному объекту SVG, но не по элементам в нем. Кажется, что проблема только в щелчке (или любом взаимодействии с мышью), так как я могу использовать getAttribute (), чтобы возвратить значения ширины, идентификатора, x/y, текста и т.д. Для всего, что находится под ним.

Вот пример 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>

И пример того, как WebDriver пытается щелкнуть правой кнопкой мыши по элементу прямоугольника (и терпит неудачу):

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

Но это работает и возвращает значение:

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

Когда WebDriver выдает ошибки, обычно это так:

    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]

Я потратил некоторое время на изучение этого вопроса, и это кажется довольно распространенной проблемой для Selenium и SVG, однако мне интересно, есть ли обходной путь. Единственные решения, которые я нашел, - это взаимодействие с самим SVG, что я уже могу сделать.

Я использую Selenium 2.28 (и пробовал 2.29) с Java + Firefox 17.

Любые идеи с благодарностью.

37
jgode

Для тех, кто заинтересован, я решил это следующим образом:

1) Я первоначально тестировал это на OSX с Firefox 17 и Selenium 2.28/29, но понял, что это работает (по крайней мере для меня) только на Windows с Firefox 18 и Selenium 2.29

2) взаимодействие с SVG со стандартом:

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

не работает Вам нужно использовать действия.

3) для взаимодействия с объектами SVG работают следующие XPath:

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

Объект SVG - это все, что находится под элементом SVG (например, круг, прямоугольник, текст и т.д.).

Пример нажатия на объект SVG:

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

Примечание: вам нужно вызвать путь внутри функции click (); с помощью:

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

не работает.

23
jgode

Попробуйте этот обходной путь: 

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

Всякий раз, когда у меня возникает слишком много проблем с некоторыми элементами при попытке щелкнуть их, я использую этот обходной путь.

11
Ioan

Ну вот: 

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

Таким образом, вы можете сделать это.

2
user3487861

Мы смогли избежать нечетного выбора xpath, выполнив эти две вещи

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

Это работало на OSX и Phantomjs, но я думаю, что это должно быть в любом современном браузере.

(Мы использовали драйвер js, поэтому не стесняйтесь исправлять любые ошибки компиляции)

2
case nelson

Для решения 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

В моем проекте разные верхние графики, и моя цель состояла в том, чтобы дважды щелкнуть участок диаграммы, чтобы получить дополнительную информацию, и мне удалось сделать это, используя следующие строки кода .... XPath не работал для меня, но CssSelector работал просто отлично.

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

Вот пример обходного пути в C #:

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

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