Подтвердить что ты не робот

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

    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.

Любые идеи получили высокую оценку.

4b9b3361

Ответ 1

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

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

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

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

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

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

не работает.

Ответ 2

Попробуйте обходное решение:

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

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

Ответ 3

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

Ответ 4

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

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

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

Ответ 5

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

Ответ 6

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

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

Ответ 7

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

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

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

Ответ 8

actual = driver.findElement(By.xpath(
"//div[contains(@class,'review-action')]//div[contains(@class,'rating')]/*[name()='svg'][1]/*[name()='g']/*[name()='path'][2]"))
.getAttribute("stroke");