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

у меня есть объект SVG с несколькими элементами круга и прямоугольника. Используя webdriver, я могу нажать на основной объект svg, но не на любой из элементов внутри него. Проблема только в щелчке (или любом взаимодействии с мышью), так как я могу использовать getAttribute () для возврата значения ширины, ID, 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, пытающегося щелкнуть правой кнопкой мыши элемент прямоугольника (и failing):

    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/fxdriver@googlecode.com/components/synthetic_mouse.js" line: 8544}]' when calling method: [wdIMouse::move]

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

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

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

7 ответов


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

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

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

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

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

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

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

в СВГ объект, являющийся чем-либо под элементом SVG (например, circle, rect, text и т. д.).

пример нажатия на объект 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();

не работает.


попробуйте этот метод :

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

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


мы смогли избежать нечетного выбора 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, поэтому не стесняйтесь исправлять любые ошибки компиляции)


здесь вы идете:

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

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


У меня есть разные высокие диаграммы в моем проекте, и моя цель состояла в том, чтобы дважды щелкнуть по разделу диаграммы для детализации для получения дополнительной информации, и мне удалось сделать это, используя следующие строки кода. 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();

для решения JS:

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

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

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

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