1. ホーム
  2. javascript

[解決済み] WebDriverのclick()とJavaScriptのclick()の比較

2022-05-06 23:34:25

質問

ストーリーは?

この StackOverflow で、selenium WebDriver の "click" コマンドで要素をクリックできない、スクリプトを実行して JavaScript でクリックすれば回避できる、というユーザーの報告を見かけました。

Pythonでの例。

element = driver.find_element_by_id("myid")
driver.execute_script("arguments[0].click();", element)

WebDriverJS/Protractor での例です。

var elm = $("#myid");
browser.executeScript("arguments[0].click();", elm.getWebElement());

質問です。

通常のWebDriverクリックでは動作しないのに、"via JavaScript"クリックでは動作するのはなぜですか?また、この回避策の欠点は何ですか(もしあれば)?

私自身、なぜそうしなければならないのか、それがどのような問題につながるのかを十分に理解しないまま、この回避策を使ってしまいました。

解決方法は?

とは対照的に 現在受け入れられている回答 WebDriverにクリックをさせるか、JavaScriptで行うかの違いについては、PhantomJSに特化したものはありません。

違い

この2つの方法の本質的な違いは、すべてのブラウザに共通するもので、非常に簡単に説明することができます。

  • WebDriverです。 WebDriver がクリックを実行するとき、実際のユーザーがブラウザを使用するときに起こることを可能な限りシミュレートしようとします。 例えば、"Click me"というボタンである要素Aと、"Click me"というボタンである要素Bがあるとします。 div を持つ、透明な要素であり、その寸法と zIndex 次に、WebDriver に A をクリックするように指示します。WebDriver はクリックをシミュレートして、B がクリックを受けるようにします。 最初 . なぜか?なぜなら、BはAをカバーしており、もしユーザーがAをクリックしようとしたら、Bが先にイベントを取得することになるからです。Aが最終的にクリックイベントを取得するかどうかは、Bがそのイベントをどう処理するかによります。いずれにせよ、この場合のWebDriverでの動作は、実際のユーザーがAをクリックしようとしたときと同じになります。

  • JavaScriptです。では、JavaScriptを使って A.click() . この方法では、ユーザーがAをクリックしようとしたときに実際に起こることを再現することはできません。 JavaScriptが送信する click イベントは直接 A に送られ、B は何のイベントも受け取りません。

WebDriverのクリックが効かないのにJavaScriptのクリックが効くのはなぜ?

上で述べたように、WebDriverは実際のユーザーがブラウザを使用しているときに起こることを可能な限りシミュレートしようとします。実際、DOMはユーザーが操作できない要素を含むことができ、WebDriverはこれらの要素をクリックすることを許可しません。先ほどのオーバーラップのケースに加え、不可視の要素もクリックすることができません。Stack Overflowの質問でよく見かけるケースは、DOMにすでに存在するが、他の要素が操作されたときだけ見えるようになるGUI要素と対話しようとしている人です。これは、ドロップダウンメニューで時々起こります。メニュー項目を選択する前に、まずドロップダウンメニューを表示するボタンをクリックする必要があります。メニューが表示される前に誰かがメニュー項目をクリックしようとすると、WebDriver はその要素を操作できないと断ります。 もし、その人がJavaScriptでそれを行おうとしたら、イベントは可視性に関係なく、要素に直接配信されるので、うまくいきます。

クリック操作にJavaScriptを使うべき場合とは?

Seleniumを使用している場合 アプリケーションのテスト この質問に対する私の答えは ほとんどないですね。 概して、Seleniumのテストは、ユーザーがブラウザで行うことを再現する必要があります。ドロップダウンメニューを例にとると、テストはまずドロップダウンを表示するボタンをクリックし、次にメニュー項目をクリックします。もしボタンが見えない、あるいはボタンがメニュー項目を表示しないなど、GUIに問題があれば、テストは失敗し、バグを検出したことになります。 JavaScriptを使ってクリックしまくると、自動テストでこれらのバグを検出することができません。

私が「ほとんどない」と言ったのは、JavaScriptを使うことが意味のある例外があるかもしれないからです。しかし、それは非常にまれなことです。

のためにSeleniumを使用している場合 スクレイピングサイト であれば、ユーザーの行動を再現することはそれほど重要ではありません。そのため、GUIをバイパスするためにJavaScriptを使用することは、それほど問題ではありません。