web-dev-qa-db-ja.com

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

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

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

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

Seleniumに要素の非表示状態を無視させることはできますか? Seleniumに非表示要素との対話を強制するにはどうすればよいですか?

96
djondal

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

  • 可視性!=非表示
  • display!= none(すべての親要素に対してもチェックされます)
  • opacity!= 0(これは要素をクリックしてもチェックされません)
  • 高さと幅の両方が> 0
  • 入力の場合、属性タイプ!= hidden

要素がこれらの基準のいずれかに一致しています。要素のスタイリングを変更する機能がない場合は、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

101
lukeis

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

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

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

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

私はRubyアプリの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

お役に立てれば。

27
ranktrackerpro

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

driver.maximize_window()

参照: WebDriver.maximize_window()

15
mynameistechno

または、Selenium Action Classを使用して、ユーザーインタラクションをシミュレートできます。たとえば、

    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
fil mihaylov

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

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

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

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

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

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

5
avandeursen

Internet Explorer 9のSelenium 2でも同じ問題が発生しましたが、修正は本当に奇妙です。フォーム内の入力をクリックすることはできませんでした-> Seleniumの繰り返しは表示されません。

私のフォームが湾曲した影を持っているときに発生しました-> http://www.paulund.co.uk/creating-different-css3-box-shadows-effects :具体的な「Effect no。2」

この擬似要素ソリューションがSeleniumテストを停止した理由と方法はわかりませんが、うまくいきます。

2
Agoreddah

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

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

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

Rorプロジェクトでcapybaraを使用しているときにこのエラーを解決するには、以下を追加します。

Capybara.ignore_elements = true

features/support/env.rbに。

1
Zernel

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

waitFor() { element.displayed }
1
Suat Keskin

テンプレート内のリンクとしてDjangoグリフィコンを含むbootstrapサイトの機能テストにSeleniumを使用してElementNotVisibleException例外が発生します。

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

私の機能テスト中、bootstrapスタイルはロードされません。そのようなリンクをクリックしようとするとElementNotVisibleExceptionが発生します。私はそれらをクリック可能にしましたスペースを追加するだけ、そのように:

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

受け入れられた答えは私のために働いた。以下は、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
starmer

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

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

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

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

これに遭遇したため、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
mancocapac

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

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