現在表示されていない要素をクリックするようにSelenium WebDriverに強制する方法は?


99

FirefoxDriverでSelenium 2 Java APIを使用しています。フォームに入力すると、フォームの入力に応じてページにチェックボックスが追加されます。

Seleniumを使用して、これらのチェックボックスのクリックをシミュレートしたいと思います。要素は通常のブラウザで表示され、使用できますが、セレンは要素が表示されないと断言します。

"Element is not currently visible and so may not be interacted with"

セレンに要素の非表示状態を無視させることができますか?Seleniumに非表示要素との相互作用を強制するにはどうすればよいですか?


どのブラウザを使用していますか?エンドユーザーが要素を操作できないため、無効または表示されていない要素を操作することはできません。問題の診断を試みたい場合は、テストコードとページのソースを提供する必要があります。
アルデスコ

回答:


102

Seleniumは、次の基準によって要素が表示されるかどうかを決定します(DOMインスペクターを使用して、要素に適用するCSSを決定します。計算されたスタイルを確認してください)。

  • 可視性!=非表示
  • display!= none(すべての親要素に対してもチェックされます)
  • 不透明度!= 0(これは要素をクリックするためにチェックされません)
  • 高さと幅の両方が0より大きい
  • 入力の場合、属性タイプ!=非表示

要素はこれらの基準のいずれかに一致しています。要素のスタイルを変更する機能がない場合は、JavaScriptを使用して強制的に変更する方法を次に示します(Selenium2 APIと言ったため、WebDriverを想定します)。

((JavascriptExecutor)driver).executeScript("arguments[0].checked = true;", inputElement);

ただし、JavaScriptイベントは発生しません。その入力の変更イベントに依存している場合は、それも発生させる必要があります(そのための多くの方法、そのページに読み込まれているJavaScriptライブラリを使用するのが最も簡単です)。

可視性チェックのソース-

https://github.com/SeleniumHQ/selenium/blob/master/javascript/atoms/dom.js#L577

これを定義するWebDriver仕様-

https://dvcs.w3.org/hg/webdriver/raw-file/tip/webdriver-spec.html#widl-WebElement-isDisplayed-boolean


1
条件のリストのソース(または正規リンク)はありますか?
mjs

2
Javascriptを読み取れる限り、メソッドbot.dom.isShownが可視性を決定します。code.google.com
p

ここでinputElementとは何ですか。以下のコードを実行しますWebElement inputElement = driver.findElement(By.xpath(PASSWORD_PATH)); ((JavascriptExecutor)driver).executeScript( "arguments [0] .checked = true;"、inputElement); しかし、ヘルプはありませんinputElement.sendKeys(password);
Deepak Goel

2
@NIleshSharma pythonには、メソッドexecute_scriptがドライバーオブジェクト自体に直接あります。driver.execute_script(...)
lukeis

1
@TunaBumによって投稿されたソースリンクがcode.google.com/p/selenium/source/browse/javascript/atoms/…に変更されました
Shepmaster

27

これは、検索しようとしている同じプロパティを持つページに複数の要素があり、「間違った要素と対話している」ことを意味する場合があります。

要素を:idまたは:name(または:class)で一意に識別できない場合は、注意が必要です。

:xpathで要素を検索すると役立つ場合があり、場合によっては実用的ではありません。

そのような場合、基準に一致するすべての要素を取得し、インデックスによって適切な要素を参照する必要があります。汚れていますが、動作します。

Ruby on RailsアプリのSelenium / Watirを使用しているので、私の場合の例は次のようになります。

browser = Watir::Browser.new(:firefox, :profile => "default")       
browser.goto("http://www.google.com/analytics")
# login
browser.divs(:text, "+ New Property").last.click

お役に立てれば。


idをdom要素に追加すると修正されました
naoru

同じ問題があり、XPathを調整してユニークな要素を区別できるようにしました。
JohnL、2015

私も同じ問題を抱えていました。一致をカウントするようにfindElements()への呼び出しを変更しました。一致する要素がもう1つありました。ありがとう!
牡羊座

私にとってこれだけです。常に、選択基準が、操作していると思われる要素に対して十分に具体的であることを確認してください。多くの場合、2つの要素を使用していて、1つは非表示になっていて、このエラーが発生します。
Chris

14

同様の問題がありましたが、ビューポートに表示されない要素に関連していました。スクリーンショットを撮ったところ、ブラウザウィンドウが狭すぎて要素が見えないことに気付きました。私はこれらの1つを行い、それはうまくいきました:

driver.maximize_window()

参照:WebDriver.maximize_window()


7

または、Seleniumアクションクラスを使用してユーザーインタラクションをシミュレートすることもできます-たとえば

    WebDriver = new FirefoxDriver();

    WebElement menu = driver.findElement(By.xpath("")); // the triger event element

    Actions build = new Actions(driver); // heare you state ActionBuider
    build.moveToElement(menu).build().perform(); // Here you perform hover mouse over the needed elemnt to triger the visibility of the hidden
    WebElement m2m= driver.findElement(By.xpath(""));//the previous non visible element
    m2m.click();

7

可視要素が非表示として認識される別のケースもあります:

  • 要素がCSSに変換されるとき
  • 要素の親要素がCSS変換される場合

やり取りしたくない要素がCSSで変換されているかどうかを確認するには、CHROMEで次のようにします。

  1. 検査官を開く
  2. 興味深い要素(またはおそらくその親要素、おそらくdiv要素)を見つける
  3. 「計算済み」タブを選択します
  4. パラメータがある場合:webkit-transform:matrix(...)これは、要素がCSSで変換され、セレン2によって可視要素として認識されない可能性があることを意味します

5

非表示は、要素がゆっくりと表示されるはずのタイミングが原因である場合もあります。その場合、ブラウザに少し待つように強制することが役立つ場合があります。

たとえば、要素が存在するまでWebDriverを待機させることに関する質問を参照してください。


2

Internet Explorer 9のセレン2でも同じ問題がありましたが、私の修正は本当に奇妙です。フォーム内の入力をクリックできませんでした->セレンの繰り返し、それらは表示されません。

フォームに影が付いているときに発生しました-> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects:具体的な「効果2」

この疑似要素ソリューションがセレンテストを停止した理由と方法はわかりませんが、私には有効です。


2

Seleniumはユーザーインタラクションを模倣するように設計されているため、ユーザーが通常アクセスできない要素に強制的にアクセス/変更することはできません。

このエラーが発生した場合は、次のことを確認してください。

  • 要素はあなたのビューポートに表示され、例えば(使用しているwebdriverをすることを現在のウィンドウを最大化しようmaximize()のNode.jsmaximize_window() Pythonで)、
  • あなたの要素は(同じセレクタの下で)2回表示されておらず、間違ったものを選択しています、
  • 要素が非表示の場合は、表示することを検討してください。
  • あなたが制限のにもかかわらず、隠された要素のアクセス/変更値たい場合は、その後、(例えばそのためにJavascriptを使用executeScript()のNode.jsexecute_script()Pythonで)を。

1
Seleniumがこのように厳密に設計されているとは思いもしませんでした。それは一般的な意味では実際には自動化ツールではなく、自動化されたユーザー対話ツールのようです。私が推測することは少し理にかなっています。明確にしていただきありがとうございます!
DanielLidström18年

1

次のように追加して、rorプロジェクトでカピバラを使用しているときにこのエラーを解決します。

Capybara.ignore_elements = true

features/support/env.rb


1

要素の表示プロパティを待機することでこのエラーを解決します

waitFor() { element.displayed }

このページのすべての回答の中で、これがブートストラップモーダルダイアログの問題を修正したものです。@Suat Keskinに感謝!
alastairs

1

次のように、テンプレートのリンクとしてブートストラップグリフィコンを使用して、djangoサイトでの機能テストにセレンを使用してElementNotVisibleException例外に入ります。

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger"></span></a>

私の機能テスト中に、ブートストラップスタイルが読み込まれていません。そのようなリンクをクリックしようとすると、ElementNotVisibleExceptionが発生します。次のように、タグにスペース追加するだけでクリックできるようにしています。

<a href="{% url 'item-add' %}"><span class="glyphicon glyphicon-plus text-danger">&nbsp;</span></a>

1

このページには多くの良い答えがあります。

  1. 私は通常、maximize.window()から始めますが、実際には、これをドライバーファクトリーまたはドライバーを初期化する場所で行います。これはデフォルトで行われるものです-常に。
  2. 通常、JavaScriptの遅延のため、要素を待機しています。

どちらも上記のさまざまな詳細で説明されています。私が見なかった答えはScrollToElementでした。要素のリストを処理しているときに、さらに要素、チェックボックスを作成しているようです。これにより、リスト内の要素が表示されているページから移動する可能性があります。時々、要素を肉眼で見ることができますが、それをクリックすることはできません。リストを処理するとき、スクロールを挿入する必要がある場合があります。

  • ブレークポイントを設定し、使用している要素がウィンドウの端(上下左右)にあるかどうかを確認します。これが当てはまる場合、セレン経由ではアクセスできないことがありますが、マウスで手動でクリックできます。

これに出くわしたので、PageScroll.javaを作成し、そこにスクロールスクリプトを配置しました。このクラスのメソッドのいくつかを次に示します。

public static void scrollToTop(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0,0)");
    }

    public static void scrollToBottom(WebDriver driver) {
      ((JavascriptExecutor) driver)
        .executeScript("window.scrollTo(0, document.body.scrollHeight)");
    }

    public static void scrollToElementTop(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(true);", element);
    }

    public static void scrollToElementBottom(WebDriver driver, WebElement element) {
      ((JavascriptExecutor) driver).executeScript(
        "arguments[0].scrollIntoView(false);", element);
    }

その他の例については、Selenium要素をスクロールして表示するを 参照してください


0

受け入れられた答えは私のために働いた。以下は、Seleniumに見えないようにさせる親要素を見つけるためのコードです。

function getStyles(element){
	
	computedStyle = window.getComputedStyle(element);

	if(computedStyle.opacity === 0
	|| computedStyle.display === "none"
	|| computedStyle.visibility === "hidden"
	|| (computedStyle.height < 0 && computedStyle.height < 0)
	|| element.type === "hidden") {
		console.log("Found an element that Selenium will consider to not be visible")
		console.log(element);
		console.log("opacity: " + computedStyle.opacity);
		console.log("display: " + computedStyle.display);
		console.log("visibility: " + computedStyle.visibility);
		console.log("height: " + computedStyle.height);
		console.log("width: " + computedStyle.width);
	}

	if(element.parentElement){
		getStyles(element.parentElement);
	}
}

getStyles(document.getElementById('REPLACE WITH THE ID OF THE ELEMENT YOU THINK IS VISIBLE BUT SELENIUM CAN NOT FIND'));


0

ここに砂粒を追加するには:要素が固定divの背後にある場合、その要素は非表示と見なされ、クリックできません。これは最近私に起こりました、そして私は上で推奨されたようにスクリプトを実行してそれを解決しました、それはします:

document.evaluate("<xpath locator for element to be clicked>", document, null, XPathResult.ANY_TYPE, null).iterateNext().click()", locator);

ここのロケーターとは何ですか?
アンジャナ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.