Selenium是一套開源工具和庫,允許您與瀏覽器進行交互,執行各種操作,如發送文本、點擊按鈕、選擇下拉菜單等。
然而,有時候實際的Selenium WebDriver命令無法按預期工作,因為Selenium無法直接與WebElements交互。這就是JavaScriptExecutor出現的地方。
在本博客中,我們將討論Selenium中的JavaScriptExecutor,以及如何開始應用實際用例和示例。
JavaScriptExecutor在Selenium中是什麼?
JavaScriptExecutor是Selenium提供的一個接口,用於執行JavaScript命令。該接口提供了在所選窗口或當前網頁上運行JavaScript的方法。它適用於Selenium支持的所有語言綁定。
Selenium中的JavaScriptExecutor可以通過導入自動化測試腳本中的以下包進行直接使用:
org.openqa.selenium.JavascriptExecutor
Selenium中的JavaScriptExecutor提供了兩種與WebElements交互的方法:
executeScript()
– 這個方法在Selenium中當前選定的窗口或框架的上下文中執行JavaScript。該腳本將作為匿名函數的主體執行。executeAsyncScript()
– 該方法在Selenium中的當前選定窗口或框架的上下文中執行一段異步的JavaScript代碼。該腳本將作為匿名函數的主體執行。
注意:使用executeAsyncScript()
調用的腳本必須使用callback()
函數發出關於執行完成的信號。
在測試中需要在瀏覽器中進行休眠或需要在AJAX應用程序中同步測試時,通常使用executeAsyncScript()
調用方法。
為什麼在Selenium中使用JavaScriptExecutor?
有一些情況,一些WebDriver命令由於多種原因而無法正常工作,如下:
- Selenium無法直接與WebElements交互
- 執行操作,如滾動到視圖中,單擊位於覆蓋層後面隱藏的WebElements,或在只讀字段中設置值
- 執行特定於瀏覽器的行為,如動態修改DOM
在這些情況下,我們尋求在Selenium中使用JavaScriptExecutor的幫助。
傳統上,我們使用Selenium 定位器,例如 ID、Name、CSS 選擇器、XPath 等,來定位 WebElement。如果這些定位器不起作用,或者您正在處理一個棘手的 XPath,在這種情況下,JavaScriptExecutor 可以幫助定位所需的 WebElement。
有些情況下,click()
方法可能無法在所有瀏覽器上正常工作,或者網頁控件在不同瀏覽器上的行為可能不同。為了克服這些情況,應該使用 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
在我們看如何在Selenium中使用JavaScriptExecuter之前,請遵循以下先決條件:
- 在IntelliJ IDE中創建一個新的Maven項目
- 在pom.xml中添加最新的Selenium WebDriver依賴
- 在pom.xml中添加最新的TestNG依賴
我們將使用LambdaTest電子商務遊樂場網站來演示在Selenium中使用JavaScriptExecutor的工作原理,並在本地Chrome瀏覽器上運行測試。
測試方案1
我們的目標是編寫一個簡單的代碼示例,使用executeScript()
方法來演示以下測試方案。
- 前往LambdaTest電子商務遊樂場網站的帳戶登錄頁面。
- 輸入有效的登錄憑證,並通過突出顯示帶有紅色邊框的字段來點擊登錄按鈕。
- 打印頁面標題和域名。
- 斷言成功登錄時頁面標題“My Account”是否顯示。
實施
建立一個新的 TestJavaScriptExecutor
類別來實現測試方案。我們將首先在這個測試類別中建立兩個方法,這些方法將允許我們設定並優雅地退出 Selenium WebDriver 會話。
讓我們將 WebDriver
在類別級別聲明,因為我們會在兩個方法中使用到它,即 setup()
方法用於啟動驅動程序會話,以及 tearDown()
方法用於優雅地退出會話。
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 電子商務遊樂場網站的登錄頁面。接下來的代碼將 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電子商務遊樂場網站。
- 滾動到首頁的底部。
- 斷言在頁面底部顯示文本“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具有一個稱為JavaScriptExecutor的接口,當WebDriver命令不能按預期運行時,可以使用該接口。借助JavaScriptExecutor,我們可以使用WebDriver在網站上執行JavaScript代碼,從而以一種優雅且有效的方式處理各種任務,否則僅使用Java是不可能的。
在這篇博文中,我們探討了如何在Selenium中使用JavaScriptExecutor及其不同的方法。此外,我們還涵蓋了使用不同方法解決問題的各種情況,並提供了實際示例。
Source:
https://dzone.com/articles/how-to-use-javascriptexecutor-in-selenium