いくつかの円と長方形の要素を持つ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を試しました)w/Java + Firefox 17。
どんなアイデアも大歓迎です。
興味のある方は、次の方法でこれを解決しました。
1)私はもともとこれをFirefox 17およびSelenium 2.28/29を使用してOSXでテストしていましたが、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);
一部の要素をクリックするときに問題が多すぎる場合は常に、この回避策を使用します。
どうぞ:
driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("x")
driver.findElement(By.cssSelector("#canvas > svg > rect")).getAttribute("y")
この方法でそれを行うことができます。
これら2つのことを行うことで、奇妙な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ドライバーを使用したため、コンパイルエラーを修正してください)
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"));