Selenium là một trong những bộ công cụ kiểm thử tự động phổ biến nhất, được sử dụng rộng rãi để tự động hóa các ứng dụng web. Nó có thể thực hiện từ các hành động cơ bản đến nâng cao trên trang web, như nhấp vào nút, nhập văn bản vào trường đầu vào, chọn mục từ danh sách thả xuống, thao tác chuột-bàn phím, v.v. Tuy nhiên, có những trường hợp Selenium WebDriver không thể tương tác với một số phần tử nhất định trên trang — đó là lúc JavascriptExecutor phát huy tác dụng!
JavascriptExecutor trong Selenium là gì?
JavascriptExecutor là một giao diện (interface) cung cấp cơ chế thực thi mã JavaScript thông qua Selenium WebDriver. Giao diện này cung cấp nhiều phương thức để chạy JavaScript trên cửa sổ được chọn hoặc trang web hiện tại. Selenium WebDriver hỗ trợ nhiều ngôn ngữ lập trình, và JavascriptExecutor đều có sẵn trong từng binding đó.
JavaScript là ngôn ngữ lập trình tương tác với HTML trong trình duyệt, và để làm điều đó trong Selenium thì cần đến giao diện JavascriptExecutor.
Để sử dụng JavascriptExecutor trong Selenium, bạn cần import gói sau:
import org.openqa.selenium.JavascriptExecutor;
JavascriptExecutor cung cấp hai phương thức chính để tương tác với phần tử web:
1. executeScript()
Phương thức này thực thi mã JavaScript trong ngữ cảnh của cửa sổ hoặc khung (frame) hiện được chọn. Mã script sẽ được thực thi như một hàm nặc danh và chỉ khi thực thi xong mới trả quyền điều khiển về.
Dùng khi: cần chạy các lệnh JS đơn giản và nhanh như click, cuộn trang, đọc giá trị...
Ví dụ:
JavascriptExecutor js = (JavascriptExecutor) driver;
String title = (String) js.executeScript("return document.title;"); System.out.println("Page title is: " + title);
2. executeAsyncScript()
Thực thi mã JavaScript bất đồng bộ trong ngữ cảnh hiện tại. Thường dùng để xử lý các thao tác bất đồng bộ như đợi các lời gọi AJAX hoàn tất (sử dụng callback).
Dùng khi: xử lý setTimeout
, AJAX hoặc thao tác async.
Ví dụ:
js.executeAsyncScript(
"var callback = arguments[arguments.length - 1];" +
"setTimeout(function(){ callback('Async script executed'); }, 1000);"
);
Tại sao nên dùng JavascriptExecutor trong Selenium?
Bạn nên sử dụng JavascriptExecutor khi các phương thức tiêu chuẩn của WebDriver như click()
, sendKeys()
không thể thực hiện được do:
- Cuộn trang: Selenium không có hàm cuộn riêng, nhưng có thể làm được với JavascriptExecutor.
- Tương tác với phần tử không khả dụng: Ví dụ như phần tử bị ẩn hoặc không tương tác được, dẫn đến lỗi
ElementNotInteractableException
. - Xử lý sự kiện chuột: Một số phần tử dùng framework JS phức tạp nên các thao tác như hover, drag-drop không hoạt động bình thường.
- Thao tác DOM: Có thể chỉnh sửa style, thuộc tính, thêm/xóa phần tử để phục vụ kiểm thử.
Cách JavascriptExecutor hoạt động trong Selenium
Mỗi trình duyệt đều có engine JavaScript riêng: Chrome dùng V8, Firefox dùng SpiderMonkey. Khi bạn dùng JavascriptExecutor, Selenium gửi mã JS đến trình duyệt thông qua driver (ChromeDriver, FirefoxDriver...) để thực thi trong engine JavaScript.
Cú pháp:
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript(script, arguments);
Các lệnh phổ biến dùng với JavascriptExecutor
JavascriptExecutor có thể được sử dụng để mô phỏng nhiều hành động khác nhau như nhấp chuột, cuộn, lấy và đặt văn bản, làm mới trang, v.v.
Đầu tiên bạn cần nhập giao diện JavascriptExecutor, tạo tham chiếu đến giao diện đó, sau đó gọi các phương thức của giao diện đó.
//import the package
import org.openqa.selenium.JavascriptExecutor;
//create a reference variable
JavascriptExecutor js = (JavascriptExecutor) driver;
//call the method
js.executeScript(script, args);
1. Nhấp vào nút:
js.executeScript("document.getElementById('element id').click();");
// or
js.executeScript("arguments[0].click();", element);
VD:
js.executeScript(“document.getElementById(’submit’).click();”);
2. Cuộn đến phần tử:
js.executeScript(“arguments[0].scrollIntoView(true);”, element);
VD:
js.executeScript(“arguments[0].scrollIntoView(true);”, subscribe);
3. Cuộn đến cuối trang:
js.executeScript(“window.scrollTo(0, document.body.scrollHeight)”);
4. Cuộn theo pixel được chỉ định:
js.executeScript(“window.scrollBy(x-axis, y-axis)”);
VD:
js.executeScript(“window.scrollBy(0, 400)”);
5. Nhập text không dùng sendKeys:
js.executeScript(“document.getElementById(‘element id’).value=’Value’;”);
VD:
js.executeScript(“document.getElementById(‘email’).value=’username@xyz.com’;”);
6. Lấy tiêu đề trang:
String title = js.executeScript(“return document.title;”).toString();
7. Lấy tên domain:
String domainName= js.executeScript(“return document.domain;”).toString();
8. Lấy URL:
String url= js.executeScript(“return document.URL;”).toString();
9. Điều hướng đến URL khác:
js.executeScript(“window.location = ‘page url’”);
VD:
js.executeScript(“window.location = ‘ https://testgrid.io/’”);
10. Lấy nội dung toàn trang:
String innerText = js.executeScript(” return document.documentElement.innerText;”).toString();
11. Lấy chiều cao và chiều rộng:
String height = js.executeScript("return window.innerHeight;").toString();
String width = js.executeScript("return window.innerWidth;").toString();
12. Tạo hộp thoại cảnh báo:
js.executeScript(“alert(‘Alert message’);”);
VD:
js.executeScript(“alert(‘This is an alert triggered by JSExecutor!’);”);
Ví dụ thực tế: Nhập liệu và submit form
Đoạn mã bên dưới sẽ giúp bạn hiểu rõ hơn về cách triển khai JavascriptExecutor thông qua mã Selenium.
Điều kiện tiên quyết:
- Java 8 hoặc bất kỳ phiên bản cao hơn nào được cài đặt trên hệ thống.
- Đã cài đặt Eclipse hoặc bất kỳ IDE tương tự nào.
- Đối với một dự án Java thông thường, hãy thêm các jar Selenium Java cần thiết và đối với một dự án Maven, hãy thêm phụ thuộc Selenium maven vào tệp
pom.xml
.
<dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.31.0</version> </dependency>
</dependencies> package testcases;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver; public class JavascriptExecutorExample { public static void main(String[] args) { WebDriver driver; driver= new ChromeDriver(); driver.get("https://demoqa.com/text-box"); WebElement fullName= driver.findElement(By.cssSelector("input#userName")); WebElement email= driver.findElement(By.cssSelector("input#userEmail")); WebElement cAdd= driver.findElement(By.cssSelector("textarea#currentAddress")); WebElement pAdd= driver.findElement(By.cssSelector("textarea#permanentAddress")); WebElement submit= driver.findElement(By.cssSelector("button#submit")); JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript("arguments[0].value='TestUser';", fullName); js.executeScript("arguments[0].value='test@yopmail.com';", email); js.executeScript("arguments[0].value='India';", cAdd); js.executeScript("arguments[0].value='India';", pAdd); js.executeScript("arguments[0].click();", submit); driver.quit(); }
}
Trong mã Selenium ở trên, trước tiên một phiên bản WebDriver (trình điều khiển) được tạo cho ChromeDriver()
. Phiên bản trình điều khiển được sử dụng để điều hướng đến URL mong muốn. Các trình định vị được tạo cho các thành phần web cần được Selenium WebDriver tương tác. Và sau đó JavascriptExecutor được sử dụng để nhập giá trị vào các trường văn bản và nhấp vào nút gửi.
Dưới đây là một ví dụ khác giúp bạn hiểu cách cuộn đến cuối trang web, lấy tiêu đề trang, tên miền, URL của trang web, điều hướng đến một URL khác và tạo cảnh báo trên trang web thông qua JavascriptExecutor.
package testcases; import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver; public class JavaScriptExecutorExample { public static void main(String[] args) { WebDriver driver; driver= new ChromeDriver(); driver.get("https://demoqa.com/text-box"); JavascriptExecutor js = (JavascriptExecutor) driver; //To scroll till bottom of the web page js.executeScript("window.scrollTo(0, document.body.scrollHeight)"); //To get the page title String title = js.executeScript("return document.title;").toString(); System.out.println("Page title is: "+title); //To get the domain name String domainName= js.executeScript("return document.domain;").toString(); System.out.println("Domain name is: "+domainName); //To get the URL of a web page String url= js.executeScript("return document.URL;").toString(); System.out.println("URL is: "+url); //To navigate to a different URL js.executeScript("window.location = 'https://testgrid.io/'"); js.executeScript("alert('This is an alert triggered by JSExecutor!');"); }
}
Kết luận
Selenium là công cụ mạnh mẽ để tự động hóa ứng dụng web, nhưng với sự hỗ trợ của JavascriptExecutor, bạn có thể mở rộng khả năng thao tác và xử lý nâng cao hơn nữa. Bài viết này phù hợp với những ai muốn học cách triển khai các phương thức executeScript
và executeAsyncScript
để xử lý các tình huống mà Selenium thuần không xử lý được chỉ với Java.