NỘI DUNG BÀI HỌC

Selenium WebDriver cho phép bạn giao tiếp với các trình duyệt khác nhau để thực hiện các lệnh và xác nhận trên các phần tử DOM.

Tuy nhiên, có những trường hợp mà các lệnh Webdriver thực tế sẽ không hoạt động hiệu quả như mong đợi. Đây là lúc JavaScriptExecutor xuất hiện bổ trợ cho chúng ta.

Trong bài viết này, chúng ta sẽ thảo luận về JavaScriptExecutor trong Selenium WebDriver. Cách khai báo, cách sử dụng JavaScriptExecutor trong Selenium. Chúng ta sẽ đi sâu hơn vào việc triển khai và khám phá các hàm khác nhau trong JavascriptExecutor cùng với các ví dụ thực tế.



JavaScriptExecutor trong Selenium là gì?

JavaScriptExecutor là một giao diện được cung cấp bởi Selenium Webdriver, trình bày cách thực thi JavaScript từ Webdriver. Giao diện này cung cấp các phương pháp để chạy JavaScript trên cửa sổ đã chọn hoặc trang hiện tại. JavaScriptExecutor là một giao diện có sẵn cho tất cả các ngôn ngữ hỗ trợ Selenium Framework .

Vì JavaScriptExecutor là một giao diện Selenium, nên không cần thêm plugin hoặc tiện ích bổ sung. Bạn có thể sử dụng nó trực tiếp bằng cách nhập gói  org.openqa.selenium.JavascriptExecutor.


Tại sao sử dụng JavaScriptExecutor trong Selenium?

Riêng Selenium Webdriver cho phép bạn thực hiện các thao tác trên các phần tử web như gửi dữ liệu, nhấp vào các nút, v.v. Tuy nhiên, như đã nói trước đây, có những trường hợp mà các lệnh của Webdriver sẽ không hoạt động như mong đợi do nhiều lý do khác nhau. Trong những trường hợp này, chúng tôi sẽ nhờ đến sự trợ giúp của JavaScriptExecutor.

Ví dụ: theo truyền thống để xác định vị trí một phần tử web, chúng ta sử dụng các chiến lược định vị web khác nhau như ID, Tên, bộ chọn CSS và XPath, v.v. Nếu các trình định vị này không hoạt động như mong đợi hoặc bạn đang xử lý một XPath phức tạp, bạn có thể sử dụng JavaScriptExecutor để thực hiện thao tác mong muốn trên WebElement.

Trên các dòng tương tự, để nhấp vào WebElement, chúng ta thường sử dụng click() phương pháp được cung cấp bởi Selenium Webdriver.

Đôi khi, phương thức click() có thể không hoạt động trên tất cả các trình duyệt web hoặc các điều khiển web có thể hoạt động khác nhau trên các trình duyệt khác nhau. Hay nó bị che bởi 1 phần tử khác chẵn hạn. Để khắc phục những tình huống như vậy, giao diện JavaScriptExecutor được sử dụng.

Như chúng ta đã biết, các trình duyệt có triển khai Javascript bên trong chúng và có thể hiểu các lệnh JavaScript. Do đó, hiểu JavaScriptExecutor trong Selenium sẽ cho phép bạn thực hiện một loạt các hoạt động hiệu quả và thanh lịch hơn.


Cú pháp cơ bản của JavaScriptExecutor trong Selenium

Mục đích của phần này là cung cấp ý tưởng về các bước triển khai của JavaScriptExecutor trong Selenium. Chúng ta hãy xem xét các bước chính.


Bước 1:
Import interface JavascriptExecutor thuộc Selenium

Bước 2: Bây giờ để sử dụng JavascriptExecutor, hãy tạo một tham chiếu cho giao diện JavascriptExecutor và gán nó cho đối tượng driver với cú pháp:

JavascriptExecutor js = (JavascriptExecutor) driver;

 

Bước 3: Chúng ta đã tạo một tham chiếu JavascriptExecutor. Bây giờ chúng ta gọi các phương thức executeScript. Cú pháp cho executeScript đượcthể hiện dưới đây:

js.executeScript​(java.lang.String script, java.lang.Object... args)

Thông số:

script - JavaScript để thực thi
args - Các đối số của script. Có thể trống.

Giá trị trả về

Boolean / Long / Double/ String/ List / Map / WebElement / Null.

 

Các tình huống sử dụng JavaScriptExecutor trong Selenium

Một số tình huống chúng ta có thể xử lý bằng cách sử dụng Giao diện JavaScriptExecutor

1. Nhấp vào một Element

js.executeScript("document.getElementById('id_of_element').click();");
//hoặc
js.executeScript("arguments[0].click();", buttonLogin);

Khi mà Selenium nó báo là không thể tương tác hay không thể click vào một phần tử web nghĩa là có thể nó đang bị che hoặc chưa load lên UI kịp thời. Khi đó thằng Javascript này nó click dựa vào DOM nên nó không quan tâm bị che. Có ví dụ code chạy bên dưới.


2. Để nhập văn bản vào hộp văn bản mà không sử dụng phương thức sendKeys ()

js.executeScript("document.getElementById('email').setAttribute('value','admin02@mailinator.com');");
js.executeScript("document.getElementById('password').setAttribute('value','123456');");

"value" là thuộc tính trong thẻ input. Ngoài thuộc tính "value" thì có thể dùng các thuộc tính còn lại như "placeholder", "innerHTML",...


3. Để xử lý Checkbox bằng cách chuyển giá trị là true hoặc false

js.executeScript("document.getElementById('id_of_element').checked=false;");
//hoặc
js.executeScript("document.getElementById('id_of_element').checked=true;");


4. Để tạo Alert trong Selenium Webdriver

js.executeScript("alert('Welcome To Anh Tester - Automation Testing');");


5. Để làm mới cửa sổ trình duyệt bằng Javascript

js.executeScript("history.go(0)");


6. Để lấy nội dung của toàn bộ trang web trong Selenium

String innerText = js.executeScript("return document.documentElement.innerText;").toString();
System.out.println(innerText);


7. Để lấy Tiêu đề của trang web

String titleText = js.executeScript("return document.title;").toString();
System.out.println(titleText);


8. Để lấy tên miền

String domainName= js.executeScript("return document.domain;").toString();
System.out.println(domainName);


9. Để lấy URL của một trang web

String url= js.executeScript("return document.URL;").toString();
System.out.println(url);


10. Để lấy Chiều cao và Chiều rộng của một trang web

js.executeScript("return window.innerHeight;").toString();
js.executeScript("return window.innerWidth;").toString();


11. Để tìm một phần tử ẩn (bị khuất) trong Selenium bằng JavaScriptExecutor

js.executeScript("arguments[0].click();", element);


12. Để điều hướng đến một trang khác bằng Javascript

js.executeScript("window.location = 'https://anhtester.com'");


13. Để thực hiện Cuộn chuột

a) Để cuộn trang theo chiều dọc 500px

js.executeScript("window.scrollTo(0,500)");


b) Để cuộn trang theo chiều dọc cho đến hết (cuối trang)

js.executeScript("window.scrollTo(0,document.body.scrollHeight)");


c) Để cuộn tới 1 phần tử trong trang (này dùng nhiều)

//Giá trị true là cuộn nằm phía trên
//Giá trị false là cuộn nằm phía dưới
WebElement element = driver.findElement(By.id("id_of_element"));

js.executeScript("arguments[0].scrollIntoView(true);", WebElement);



14. Thêm một phần tử trong DOM

Chúng ta cũng có thể thêm một phần tử trong DOM nếu được yêu cầu. Tuy nhiên, vì chỉ liên quan đến việc bắt chước các tương tác của người dùng trong trình duyệt, tùy chọn này có thể không được sử dụng.

js.executeScript("var btn=document.createElement('newButton');" + "document.body.appendChild(btn);");

 

15. Set và Get giá trị vào LocalStorage trên Browser

LocalStorage là nơi trong Browser để chứa các biến (Key) kèm giá trị tương ứng tồn tại trong suốt quá trình mở Browser đó. Giống giống Properties á. Mình có thể tận dụng để Set và Get giá trị trong quá trình chạy auto có sự chuyển trang chuyển tab gì đó xong sẽ dùng lại giá trị ban đầu thì LocalStorage rất hiệu quả đây.


16. Highlight phần tử trên web

Đây là ví dụ highlight cái border của một element lên màu Đỏ

js.executeScript("arguments[0].style.border='3px solid red'", WebElement);



Set giá trị vào LocalStorage trên Browser:

js.executeScript("window.localStorage.setItem(arguments[0],arguments[1])","key","value");

Ví dụ: js.executeScript("window.localStorage.setItem(arguments[0],arguments[1])","age","30");

Thì nó sẽ set giá trị 30 vào biến "age" trong browser. Lúc bấy giờ mình sẽ gọi hàm get để lấy nó ra dùng là xong.


Get giá trị từ LocalStorage trên Browser:

(String) js.executeScript("return window.localStorage.getItem(arguments[0])", "key");

Ví dụ: tiếp tục của ví dụ trên thì mình sẽ gọi key "age" ra để lấy giá trị 30:

String localGetVar = (String) js.executeScript("return window.localStorage.getItem(arguments[0])", "age");

Vậy là xong !!!


Chú ý:

Chúng ta có các hàm document.getElementBy* sau:

[Selenium Java] Bài 14: Cách dùng Javascript Executor để hành động | Anh TesterNó không có Xpath đâu nhen =))


Các lệnh Javascript tham khảo thêm:

https://www.w3schools.com/jsref/default.asp

 

Code demo JavascriptExecutor

package com.anhtester.Bai14_JavascriptExecutor;

import com.anhtester.common.BaseTest;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.testng.annotations.Test;

public class DemoJavascriptExecutor extends BaseTest {

    @Test
    public void jsExecutorDemo01() throws InterruptedException {
        // Creating the JavascriptExecutor interface object
        JavascriptExecutor js = (JavascriptExecutor) driver;

        driver.get("https://anhtester.com/");
        Thread.sleep(1000);

        // Click on "Website Testing" module using JavascriptExecutor
        WebElement button = driver.findElement(By.xpath("//h3[normalize-space()='Website Testing']"));
        js.executeScript("arguments[0].click();", button);
        Thread.sleep(1000);

        // Get page title and Domain using JavascriptExecutor
        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);

        // Add Alert window using JavascriptExecutor
        js.executeScript("alert('Successfully Logged In');");

        Thread.sleep(2000);
    }
}


Ví dụ sendKeys

@Test
public void jsExecutorDemo02() throws InterruptedException {

    JavascriptExecutor js = (JavascriptExecutor) driver;

    driver.get("https://crm.anhtester.com/admin/authentication");
    Thread.sleep(1000);

    // sendKeys text on input
    js.executeScript("document.getElementById('email').setAttribute('value','admin@example.com');");
    js.executeScript("document.getElementById('password').setAttribute('value','123456');");

    js.executeScript("document.getElementsByClassName('btn-primary')[0].click()");
    Thread.sleep(2000);

}


Ví dụ Scroll to element

@Test
public void jsExecutorDemo03() throws InterruptedException {

    driver.get("https://anhtester.com/");
    Thread.sleep(1000);

    JavascriptExecutor js = (JavascriptExecutor) driver;

    WebElement webElement = driver.findElement(By.xpath("//h2[contains(text(),'Kiến thức Automation Testing')]"));

    //Scroll to element
    //Giá trị true là nằm phía trên
    //Giá trị false là nằm phía dưới
    js.executeScript("arguments[0].scrollIntoView(true);", webElement);

    Thread.sleep(2000);
}


Nếu mình dùng dòng lệnh webElement.click(); thì nó có thể sẽ không được vì nó bị che bởi 1 element khác là cái dropdown bên ngoài.

Còn dùng Js để click thì nó dựa vào DOM để click nên không quan tâm bị che.

Ví dụ Highlight phần tử

@Test
public void jsExecutorDemo04() throws InterruptedException {
    driver.get("https://crm.anhtester.com/admin/authentication");
    Thread.sleep(1000);

    JavascriptExecutor js = (JavascriptExecutor) driver;

    WebElement inputEmail = driver.findElement(By.xpath("//input[@id='email']"));
    js.executeScript("arguments[0].style.border='3px solid red'", inputEmail);
    inputEmail.sendKeys("admin@example.com");
    Thread.sleep(1000);
    WebElement inputPassword = driver.findElement(By.xpath("//input[@id='password']"));
    js.executeScript("arguments[0].style.border='3px solid red'", inputPassword);
    inputPassword.sendKeys("123456");
    Thread.sleep(1000);
    WebElement buttonLogin = driver.findElement(By.xpath("//button[normalize-space()='Login']"));
    js.executeScript("arguments[0].style.border='3px solid red'", buttonLogin);
    inputEmail.click();

    Thread.sleep(2000);
}


Ví dụ về Set và Get LocalStorage với Javascript

@Test
public void localStorage() throws InterruptedException {

    String localGetVar = "";

    driver.navigate().to("https://anhtester.com");
    Thread.sleep(1000);

    JavascriptExecutor js = (JavascriptExecutor) driver;

    //Set giá trị
    js.executeScript("window.localStorage.setItem(arguments[0],arguments[1])", "age", "30");

    Thread.sleep(1000);

    //Get giá trị
    localGetVar = (String) js.executeScript("return window.localStorage.getItem(arguments[0])", "age");

    System.out.println(localGetVar);

    Thread.sleep(1000);
}



Cái BaseTest là class viết riêng chứa createDriver closeDriver cái browser (driver).

package com.anhtester.common;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.*;

import java.time.Duration;

public class BaseTest {
    public WebDriver driver;

    @BeforeMethod
    public void createDriver() {
        driver = new ChromeDriver();
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
        driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(60));
    }

    @AfterMethod
    public void closeDriver() {
        driver.quit();
    }

    public void sleep(double second) {
        try {
            Thread.sleep((long) (1000 * second));
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

}

Teacher

Teacher

Anh Tester

Software Quality Engineer

Đường dẫu khó chân vẫn cần bước đi
Đời dẫu khổ tâm vẫn cần nghĩ thấu

Cộng đồng Automation Testing Việt Nam:

🌱 Telegram Automation Testing:   Cộng đồng Automation Testing
🌱 
Facebook Group Automation: Cộng đồng Automation Testing Việt Nam
🌱 
Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium
🌱 Telegram
Manual Testing:   Cộng đồng Manual Testing
🌱 
Facebook Group Manual: Cộng đồng Manual Testing Việt Nam

Chia sẻ khóa học lên trang

Bạn có thể đăng khóa học của chính bạn lên trang Anh Tester để kiếm tiền

Danh sách bài học