Seleniumは、ブラウザとやり取りしてテキストを送信したり、ボタンをクリックしたり、ドロップダウンを選択したりするなど、さまざまな操作を実行するためのツールやライブラリのオープンソースのスイートです。
ただし、実際のSelenium WebDriverコマンドが期待通りに機能しないシナリオがある場合があります。SeleniumはWeb要素と直接やり取りできないためです。ここでJavaScriptExecutorが登場します。
このブログでは、SeleniumにおけるJavaScriptExecutorと実用例や例を始める方法について説明します。
SeleniumにおけるJavaScriptExecutorとは何ですか?
JavaScriptExecutorは、JavaScriptコマンドを実行するのに役立つSeleniumが提供するインターフェースです。このインターフェースでは、選択したウィンドウまたは現在のWebページ上でJavaScriptを実行するためのメソッドが提供されます。Seleniumでサポートされているすべての言語バインディングで利用可能です。
SeleniumのJavaScriptExecutorは、自動化テストスクリプトで次のパッケージをインポートすることで直接使用できます。
org.openqa.selenium.JavascriptExecutor
SeleniumのJavaScriptExecutorは、Web要素とやり取りするための2つのメソッドを提供します。
executeScript()
–このメソッドは、Seleniumの現在選択されたウィンドウまたはフレームのコンテキストでJavaScriptを実行します。スクリプトは無名関数の本体として実行されます。executeAsyncScript()
– このメソッドは、Seleniumの現在選択されたウィンドウやフレームのコンテキストで非同期のJavaScriptスニペットを実行します。スクリプトは無名関数の本体として実行されます。
注意: executeScript()
とexecuteAsyncScript()
メソッドの主な違いは、executeAsyncScript()
を使用して呼び出されるスクリプトが、callback()
関数を使用して実行の完了を通知しなければならないことです。
executeAsyncScript()
を使用してメソッドを呼び出すことは、テスト中にブラウザでスリープを実行する必要がある場合や、AJAXアプリケーション内でテストを同期させる必要がある場合に主に使用されます。
SeleniumでJavaScriptExecutorを使用する理由
いくつかのWebDriverコマンドが複数の理由で期待どおりに機能しない場合があります:
- Seleniumが直接Web要素とやり取りしていない
- 表示されているオーバーレイの後ろに隠れているWeb要素にスクロールしたりクリックしたり、読み取り専用フィールドに値を設定したりする
- DOMを動的に変更するなど、ブラウザ固有の動作を実行する
これらの場合、SeleniumでJavaScriptExecutorの助けを借ります。
従来、私たちはID、名前、CSSセレクタ、XPathなどのSeleniumロケータを使用してWebElementを検出します。これらのロケータが機能しない場合や、トリッキーなXPathを扱っている場合、JavaScriptExecutorを使用して目的のWebElementを見つけるのに役立ちます。
click()
メソッドがすべてのWebブラウザで機能しない場合や、Webコントロールが異なるブラウザで異なる動作をする可能性がある場合があります。そのような状況を乗り越えるためには、JavaScriptExecutorを使用してクリックアクションを実行する必要があります。
ブラウザにはJavaScriptの実装が内蔵されており、JavaScriptコマンドを理解できます。したがって、SeleniumでのJavaScriptExecutorの理解により、さまざまな操作を効率的に実行できるようになります。
SeleniumでのJavaScriptExecutorの基礎
このセクションの目的は、SeleniumでJavaScriptExecutorを実装する手順の概要を提供することです。デモンストレーションでは、優先されるプログラミング言語としてJavaを使用します。
主要なステップを見てみましょう。
1. JavaScriptExecutorに関連するパッケージをインポートします:
import org.openqa.selenium.JavascriptExecutor;
2. JavaScriptExecutorを使用して、インターフェースのリファレンスを作成し、WebDriverインスタンスに型キャストして割り当てます:
JavascriptExecutor js = (JavascriptExecutor) driver;
3. executeAsyncScript()
またはexecuteScript()
メソッドを呼び出します。たとえば、executeScript()
の構文は次のとおりです:
js.executeScript(java.lang.String script, java.lang.Object... args)
デモ:SeleniumでJavaScriptExecutorを使用する方法
JavaScriptExecutorをSeleniumで使用する方法を見る前に、以下の前提条件に従ってください:
- IntelliJ IDEを使用して新しいMavenプロジェクトを作成する
- pom.xmlに最新のSelenium WebDriver依存関係を追加する
- pom.xmlに最新のTestNG依存関係を追加する
私たちは、ローカルのChromeブラウザでテストを実行して、SeleniumでJavaScriptExecutorの動作をデモするためにLambdaTest eCommerce Playgroundウェブサイトを使用します。
テストシナリオ1
当社の目的は、executeScript()
メソッドを使用して以下のテストシナリオを示すための単純なコードを記述することです。
- LambdaTest eCommerce Playgroundウェブサイトのアカウントログインページに移動する
- 有効なログイン資格情報を入力し、赤い枠でフィールドを強調表示してログインボタンをクリックする
- ページのタイトルとドメイン名を表示する
- 成功したログイン時にページヘッダー「マイアカウント」が表示されていることをアサートする
実装
新しいTestJavaScriptExecutor
クラスを作成して、テストシナリオを実装します。まず、このテストクラスに、Selenium WebDriverセッションを設定および正常に終了させるための2つのメソッドを作成します。
両方のメソッド、つまりsetup()
メソッドでドライバーセッションを開始し、tearDown()
メソッドでセッションを正常に終了させるために、WebDriver
をクラスレベルで宣言しましょう。
public class TestJavaScriptExecutor {
private WebDriver driver;
//...
}
新しいsetup()
メソッドを作成し、WebDriver
クラスのインスタンスを生成し、ローカルChromeブラウザでテストを実行するための構成を適切に設定します。
public void setup () {
driver = new ChromeDriver ();
driver.manage ()
.window ()
.maximize ();
driver.manage ()
.timeouts ()
.implicitlyWait (Duration.ofSeconds (30));
}
このメソッドは、Chromeブラウザを開き、ウィンドウを最大化し、また、30秒の暗黙の待機時間を適用します。この暗黙の待機時間により、テスト実行が開始される前にすべてのウェブサイトコンテンツが正常に読み込まれることが可能となります。

public void tearDown () {
driver.quit ();
}
最後に、テストが実行されると、tearDown()
メソッドが呼び出され、RemoteWebDriverセッションが正常に閉じられます。
さて、同じテストクラスにtestJavaScriptExecutorCommand()
メソッドを追加して、議論したテストシナリオを実装します。
public void testJavaScriptExecutorCommand () {
driver.get ("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
JavascriptExecutor js = (JavascriptExecutor) driver;
//....
}
コードは、LambdaTest eCommerce Playgroundウェブサイトのログインページに移動します。次の行では、WebDriverインスタンスをJavascriptExecutor
にキャストして、ブラウザでJavaScriptコマンドを実行できるようにします。
WebElement emailAddressField = driver.findElement (By.id ("input-email"));
js.executeScript ("arguments[0].style.border='3px solid red'", emailAddressField);
emailAddressField.sendKeys ("[email protected]");
js.executeScript ("arguments[0].style.border='2px solid #ced4da'", emailAddressField);
次に、id
ロケータ戦略を使用してemailAddressField
を見つけます。その後、JavaScriptExecutorコマンドを使用して、メールアドレスフィールドの境界線を赤色でハイライト表示します。
WebElement passwordField = driver.findElement (By.id ("input-password"));
js.executeScript ("arguments[0].style.border='3px solid red'", passwordField);
passwordField.sendKeys ("Password123");
js.executeScript ("arguments[0].style.border='2px solid #ced4da'", passwordField);
次に、パスワードフィールドが見つかり、赤い境界線で強調表示されます。このハイライトは、自動化テストの実行時にどのステップが実行されているかを知るのに役立ちます。
WebElement loginBtn = driver.findElement (By.cssSelector ("input.btn"));
js.executeScript ("arguments[0].style.border='3px solid red'", loginBtn);
js.executeScript ("arguments[0].click();", loginBtn);
同様に、CSSセレクター戦略を使用してログインボタンを見つけ、それも強調表示されます。
String titleText = js.executeScript ("return document.title;").toString ();
System.out.println ("Page Title is: " + titleText);
String domainName = js.executeScript ("return document.domain;").toString ();
System.out.println ("Domain is: " + domainName);
次に、ページタイトルとドメイン名をJavaScriptExecutorを使用して見つけ、コンソールに出力します。
String myAccountHeader = driver.findElement (By.cssSelector ("#content h2")).getText ();
assertEquals (myAccountHeader, "My Account");
最後に、成功したログイン後に表示される「マイアカウント」ページのページヘッダーを見つけ、それがテキスト “マイアカウント” を表示していることを確認するためにアサーションが実行されます。
こちらがTestJavaScriptExecutor
クラスからの完全なコードです:
public class TestJavaScriptExecutor {
private WebDriver driver;
public void setup () {
driver = new ChromeDriver ();
driver.manage ()
.window ()
.maximize ();
driver.manage ()
.timeouts ()
.implicitlyWait (Duration.ofSeconds (30));
}
public void tearDown () {
driver.quit ();
}
public void testJavaScriptExecutorCommand () {
driver.get ("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement emailAddressField = driver.findElement (By.id ("input-email"));
js.executeScript ("arguments[0].style.border='3px solid red'", emailAddressField);
emailAddressField.sendKeys ("[email protected]");
js.executeScript ("arguments[0].style.border='2px solid #ced4da'", emailAddressField);
WebElement passwordField = driver.findElement (By.id ("input-password"));
js.executeScript ("arguments[0].style.border='3px solid red'", passwordField);
passwordField.sendKeys ("Password123");
js.executeScript ("arguments[0].style.border='2px solid #ced4da'", passwordField);
WebElement loginBtn = driver.findElement (By.cssSelector ("input.btn"));
js.executeScript ("arguments[0].style.border='3px solid red'", loginBtn);
js.executeScript ("arguments[0].click();", loginBtn);
String titleText = js.executeScript ("return document.title;")
.toString ();
System.out.println ("Page Title is: " + titleText);
String domainName = js.executeScript ("return document.domain;")
.toString ();
System.out.println ("Domain is: " + domainName);
String myAccountHeader = driver.findElement (By.cssSelector ("#content h2"))
.getText ();
assertEquals (myAccountHeader, "My Account");
}
テストの実行
IntelliJ IDEからの以下のスクリーンショットによると、テストは正常に実行されました。

テストシナリオ2
私たちの目標は、次のテストシナリオを使用してexecuteAsyncScript()
メソッドを使用した例を示すためのシンプルなコードを書くことです。
- LambdaTest eCommerce Playgroundウェブサイトに移動します。
- ホームページの一番下までスクロールします。
- ページの下部にテキスト“FROM THE BLOG”が表示されていることをアサートします。
実装:
既存のテキストクラスTestJavaScriptExecutor
に新しいtestExecuteAsyncScript()
メソッドを作成します。
public void testExecuteAsyncScript() {
driver.get("https://ecommerce-playground.lambdatest.io");
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeAsyncScript("var callback = arguments[arguments.length - 1];" + "window.scrollBy(0,document.body.scrollHeight); + callback()");
String fromTheBlogText = driver.findElement(By.cssSelector("#entry_217991 > h3")).getText();
assertEquals(fromTheBlogText, "FROM THE BLOG");
}
コードはLambdaTest eCommerce Playgroundウェブサイトのホームページに移動します。次に、JavaScriptExecutorのexecuteAsyncScript()
メソッドが呼び出され、ウィンドウをスクロールするアクションが行われます。
executeAsyncScript()
メソッドでは、実行されるスクリプトは提供されたcallback()
メソッドを呼び出して明示的に終了する必要があります。
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeAsyncScript("var callback = arguments[arguments.length - 1];"
+ "window.scrollBy(0,document.body.scrollHeight); + callback()");
ウィンドウの一番下までスクロールした後、テキスト”FROM THE BLOG“が見つかり、それに対してアサーションが実行されます。
String fromTheBlogText = driver.findElement(By.cssSelector("#entry_217991 > h3")).getText();
assertEquals(fromTheBlogText, "FROM THE BLOG");
テストの実行
以下のスクリーンショットは、テストが正常に実行されたことを示しています。

SeleniumでJavaScriptExecutorを使用するためのコマンド
JavaScriptExecutorインターフェースを使用してSeleniumテスト自動化で処理できるシナリオを検討しましょう。
ボタンをクリックするには:
js.executeScript("document.getElementById('enter element id').click();");
//or
js.executeScript("arguments[0].click();", okButton);
sendKeys()
メソッドを使用せずにテキストボックスにテキストを入力するには: メソッド:
js.executeScript("document.getElementById(id').value='someValue';");
js.executeScript("document.getElementById('Email').value='SeleniumTesting.com';");
値をtrueまたはfalseとしてチェックボックスを処理するには:
js.executeScript("document.getElementById('enter element id').checked=false;");
Selenium WebDriverでアラートポップアップウィンドウを生成するには:
js.executeScript("alert('Welcome To Selenium Testing');");
JavaScriptを使用してブラウザウィンドウをリフレッシュするには:
js.executeScript("history.go(0)");
Seleniumでウェブページ全体のinnertextを取得するには:
String innerText = js.executeScript(" return document.documentElement.innerText;").toString();
System.out.println(innerText);
ウェブページのタイトルを取得するには:
String titleText = js.executeScript("return document.title;").toString();
System.out.println(titleText);
ドメイン名を取得するには:
String domainName= js.executeScript("return document.domain;").toString();
System.out.println(domainName);
ウェブページのURLを取得するには:
String url= js.executeScript("return document.URL;").toString();
System.out.println(url);
ウェブページの高さと幅を取得するには:
js.executeScript(“return window.innerHeight;”).toString();
js.executeScript(“return window.innerWidth;”).toString();
JavaScriptを使用して別のページに移動するには:
js.executeScript("window.location = 'https://www.google.com");
Seleniumを使用してアプリケーションでスクロールを実行します。
- ページを垂直に500pxスクロールするには:
Java
js.executeScript(“window.scrollBy(0,500)”);
- ページを最後まで垂直にスクロールするには:
Java
js.executeScript(“window.scrollBy(0,document.body.scrollHeight)”);
ドキュメントオブジェクトモデル(DOM)に要素を追加するには:
js.executeScript("var btn=document.createElement('newButton');"
+ "document.body.appendChild(btn);");
DOM内でシャドウルートを取得するには:
WebElement element = driver.findElement(By.id("shadowroot"));
js.executeScript("return arguments[0].shadowRoot", element);
結論
Seleniumには、WebDriverコマンドが意図した通りに機能しない場合に利用されるJavaScriptExecutorというインターフェースがあります。JavaScriptExecutorを使用することで、WebDriverを使用してウェブサイトでJavaScriptコードを実行し、Javaのみを使用して不可能だったさまざまなタスクをエレガントかつ効果的な方法で処理できます。
このブログでは、SeleniumでJavaScriptExecutorを使用する方法とその異なるメソッドを探求しました。さらに、さまざまなシナリオをカバーし、異なるメソッドを使用した効果的なソリューションを実用例とともに紹介しました。
Source:
https://dzone.com/articles/how-to-use-javascriptexecutor-in-selenium