web-dev-qa-db-ja.com

Selenium WebDriverでxPathを使用してSVG要素を取得する方法

OpenLayersに基づくAPIをSelenium WebDriver(Javaバージョン)でテストしています。

OpenLayers。Control.ModifyFeatureを使用する機能をテストしたい。描画されたフィーチャ(SVG)をクリックしてドラッグし、それらが存在するか、表示されているか、非表示になっているかを確認します。

ポリゴンを描き、それを選択しました。下の画像をご覧ください。

polygon_and_handles

これらのSVG要素のHTMLは次のとおりです。

<svg id="OpenLayers_Layer_Vector_161_svgRoot" width="1235" height="495" viewBox="0 0 1235 495" style="display: block;">
    <g id="OpenLayers_Layer_Vector_161_root" transform="" style="visibility: visible;">
        <g id="OpenLayers_Layer_Vector_161_vroot">
            <path id="OpenLayers_Geometry_Polygon_200" d=" M 393.0000000000964,213.9999999999891 486.0000000003338,275.9999999997126 384.00000000036925,284.9999999994434 393.0000000000964,213.9999999999891 z" fill-rule="evenodd" fill="blue" fill-opacity="0.4" stroke="blue" stroke-opacity="1" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="pointer" />
            <circle id="OpenLayers_Geometry_Point_619" cx="439.50000000021464" cy="244.99999999985084" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_621" cx="435.00000000035106" cy="280.49999999958163" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_623" cx="388.50000000023283" cy="249.4999999997126" r="6" fill="#009900" fill-opacity="0.5" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_202" cx="393.0000000000964" cy="213.9999999999891" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_203" cx="486.0000000003338" cy="275.9999999997126" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
            <circle id="OpenLayers_Geometry_Point_204" cx="384.00000000036925" cy="284.9999999994434" r="6" fill="#990000" fill-opacity="1" stroke="#ee9900" stroke-opacity="1" stroke-width="1" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="none" pointer-events="visiblePainted" cursor="inherit" />
        </g>
        <g id="OpenLayers_Layer_Vector_161_troot" />
    </g>
</svg>

赤い点を選択したいとします。

これは私がしました:

String xpath = "//circle[contains(@id, 'OpenLayers_Geometry_Point') AND fill = '#990000']";
List<WebElement> vertices = driver.findElements(By.xpath(xpath));

ただし、常に空のリスト[]が返されます。

ここで何が悪いのですか?誰か助けてもらえますか?

どうもありがとう。

編集1-関数:verticesAreVisible

クリックアクションの前に、要素を取得して、それらが表示されるかどうかを確認したいと思います。この機能を使用しています。

public static boolean verticesAreVisible(WebDriver driver, String xpath) {
    List<WebElement> list = driver.findElements(By.xpath(xpath));
    if (list.isEmpty()) {
        return false;
    }
    boolean visible = true;
    for (int i = 0; i < list.size(); i++) {
        visible = visible && list.get(i).isDisplayed();
    }
    return !verticesAreNotVisible(driver) && visible;
}

編集2-xPathを修正

// This solution from Razib is valid if the SVG is on the root note
String xpath = "/*[name()='svg']/*[name()='circle']";
// I changed it so that any descendant is valid "//"
String xpath = "//*[name()='svg']//*[name()='circle']";
// Since I wanted only the red vertices, I added this
String xpath = "//*[name()='svg']//*[name()='circle' and @fill='#990000']";
17
joaorodr84

nameXpath属性を持つアクションを使用する必要があるかもしれません。 XPathで使用します-

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

次に、次のコードスニペットを試してください-

WebElement svgObj = driver.findElement(By.xpath(XPATH));
Actions actionBuilder = new Actions(driver);
actionBuilder.click(svgObj).build().perform();
22
Razib

fillの代わりに@fillを、OpenLayers_Geometry_Pointの代わりにOpenLayers.Geometry.Pointをお試しください。

3
peetya

表示されている要素だけを取得するには、以下を使用できます。

wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("bla bla")));
0

SVG実装がある画面の1つでも同様の問題に直面し、アクションクラスを使用して解決しました。

Action Class Package :
Java.lang.Object
org.openqa.Selenium.interactions.Actions

サンプルコード:

WebElement svgObject= driver.findElement(By.xpath(XPATH));
Actions actionBuilderObj = new Actions(driver);
actionBuilderObj .click(svgObject).build().perform();
0
shiv

インをダイブするためにあらゆる種類のテクニックを試しましたが、少なくともこの状況に対処する簡単な方法を見つけました。目的のsvgに名前がなく、適切なxpathが動的に変更される場合、「cssSelector」を使用しました

WebElement DesiredSvg = driver.findElement(By.cssSelector("#scrollable-auto-tabpanel-0 > div > div > form > div:nth-child(1) > div:nth-child(1) > div > div > div.jss10127 > div > div.jss11602 > svg:nth-child(3)"));

DesiredSvg.click();
0
Manideep Reddy