簡體   English   中英

Selenium WebDriver:使用 XPath 單擊 SVG 中的元素

[英]Selenium WebDriver: clicking on elements within an SVG using 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/fxdriver@googlecode.com/components/synthetic_mouse.js" line: 8544}]' when calling method: [wdIMouse::move]

我花了一些時間對此進行研究,這似乎是 Selenium 和 SVG 的一個常見問題,但是我想知道是否有解決方法。 我發現的唯一解決方案是與 SVG 本身交互,我已經可以做到了。

我正在使用帶有 Java + Firefox 17 的 Selenium 2.28(並嘗試過 2.29)。

任何想法都非常感謝。

對於任何感興趣的人,我通過以下方式解決了這個問題:

1)我最初是在 OSX 上使用 Firefox 17 和 Selenium 2.28/29 進行測試,但發現它僅適用於(至少對我而言)使用 Firefox 18 和 Selenium 2.29 的 Windows

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

不起作用。

試試這個解決方法:

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

這樣你就可以做到。

對於 JS 解決方案:

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

我的項目中有不同的高位圖表,我的目標是雙擊圖表的一部分以深入了解更多信息,我已經設法使用以下代碼行來做到這一點。 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();

以下是 C# 中解決方法的示例:

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

IList<IWebElement> rectElements = svgElement.FindElements(By.CssSelector("rect"));
actual = driver.findElement(By.xpath(
"//div[contains(@class,'review-action')]//div[contains(@class,'rating')]/*[name()='svg'][1]/*[name()='g']/*[name()='path'][2]"))
.getAttribute("stroke");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM