Showing posts with label selenium webdriver. Show all posts
Showing posts with label selenium webdriver. Show all posts

Page Object Model In Robot Framework

Chào các bạn, chúng ta lại gặp nhau trong loạt bài về robot framework.
Hôm nay chúng ta sẽ nói về mô hình POM - Page Object Model in robot framework.
Mình tin rằng khi các bạn mới dùng robot framework thì cũng sẽ thắc mắc về cách tổ chức code trong project của robotframework như thế nào?
Đầu tiên chúng ta sẽ chia thành các thư mục như sau:
1. Page: nơi sẽ chứa các page của trang web or mobile app. ví dụ nhưng page login chả hạn
2. Resources: Nơi sẽ chứa các hàm common, hoặc các data test hoặc file cài đặt , ví dụ như apk or app
3. Test: Nơi sẽ chứa toàn bộ test case của dự án, có thể chia nhỏ hơn thành các thư mục con, ví dụ như test_login

Code của 3 file như sau


OK, chúng ta sẽ đi từng file cụ thể như sau:
1. File common_keyword.robot:
File này sẽ chứa toàn bộ các keyword dùng chung, ví dụ như input text , click element...
Trong ví dụ này, cụ thể mình có 03 keyword như dưới đây. Để đảm bảo tetstcase luôn đúng thì mình  chờ cho nó xuất hiện.
Ở đây, chúng ta sẽ khai báo tất cả các thư viện cần sử dụng vào 1 file này, khi cần sửa, xóa thì cứ vào file common_keyword.robot chứ không cần phải đi tìm ở các file khác.

*** Settings ***
Library    SeleniumLibrary

*** Keywords ***
wait and input text
    [Arguments]    ${locator}    ${txt_value}
    Wait Until Element Is Visible     ${locator}
    Input Text    ${locator}    ${txt_value}

wait and click element
    [Arguments]    ${locator}
     Wait Until Element Is Visible     ${locator}
     Click Element    ${locator}


Check Element Visible
    [Arguments]    ${locator}
    ${present}=    Run Keyword And Return Status    Element Should Be Visible       ${locator}    10s
    [Return]    ${present}

2. File loginPage.robot
File này chứa các element của page cần test, và chứa các action liên quan .
Chú ý: các locator của element sẽ được đặt vào biến, để sau này khi locator bị thay đổi, thì chúng ta chỉ cần đổi ở nơi khai báo biến là được.
Trong page, cần import file common để có thể sử dụng tất cả các keywork của file common.
*** Settings ***
Resource    ../Resources/common_keyword.robot

*** Variables ***
${url}    https://www.adayroi.com/
${btn_DangNhap_DangKy}      Class:header-username
${txt_name}    id:j_username
${txt_pass}    id=j_password
${btn_login}    css=.btn.btn-primary.btn-block.js-login-btn

*** Keywords ***
open website Adayroi
    Open Browser    ${url}    chrome

click button DangNhap,DangKy
    wait and click element    ${btn_DangNhap_DangKy}

type username
    [Arguments]    ${txt_value}
    wait and input text    ${txt_name}     ${txt_value}

type password
    [Arguments]    ${txt_value}
    wait and input text    ${txt_pass}     ${txt_value}

click button login
    wait and click element    ${btn_login}
3. File testLogin.robot
file test này chúng ta chỉ cần gọi lại các action tương ứng với các step ở Page cần test.
Chú ý: trong setting cần import file loginpage để có thể dùng các keywork ở page đó.

*** Settings ***
Resource    ../page/loginPage.robot
*** Test Cases ***
test login
    open website Adayroi
    click button DangNhap,DangKy
    type username    hainv
    type password    123456
    click button login

OK, vậy là chúng ta đã hiểu cơ bản cách dùng Page Object Model in robot framework là như thế nào.
Hẹn gặp các bạn ở bài sau!
Các bạn có ý kiến gì hãy để lại comment nhé!

Get all values dropdown selenium - lấy các giá trị của dropdown

Bài viết này cập nhật các kỹ thuật mới nhất để lấy danh sách giá trị từ Dropdown list, tối ưu hóa code với Java Streams và xử lý các loại dropdown phức tạp (Custom Dropdown) thường gặp trong năm 2026.

Phân loại Dropdown:
Trước khi code, bạn cần Inspect (F12) để xem dropdown thuộc loại nào:
  • Standard Dropdown: Dùng thẻ <select><option>.
  • Custom Dropdown: Dùng các thẻ <div>, <ul>, <li> kết hợp CSS/JS (React, Angular, Vue...).

1. Đối với Standard Dropdown (<select>)

Thay vì dùng vòng lặp for truyền thống, chúng ta sử dụng Java Streams API để code gọn gàng chỉ trong 1 dòng.

import org.openqa.selenium.support.ui.Select;
import java.util.List;
import java.util.stream.Collectors;

public List<String> getSelectDropdownValues(WebElement dropdownElement) {
    Select select = new Select(dropdownElement);
    
    // Cách 2026: Sử dụng Stream để map WebElement -> String
    return select.getOptions().stream()
            .map(WebElement::getText)
            .collect(Collectors.toList());
}

2. Đối với Custom Dropdown (Div/Ul/Li)

Loại này phổ biến hơn ở các UI hiện đại. Quy trình chuẩn:

  1. Click vào dropdown để mở danh sách.
  2. Chờ (Wait) cho các item hiển thị.
  3. Dùng findElements để lấy list item.
  4. Lấy text.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;

public List<String> getCustomDropdownValues(WebDriver driver) {
    WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));

    // 1. Mở Dropdown
    WebElement dropdownTrigger = driver.findElement(By.cssSelector(".dropdown-trigger"));
    dropdownTrigger.click();

    // 2. Chờ list option hiển thị (Quan trọng!)
    By itemLocator = By.cssSelector(".dropdown-menu .item");
    wait.until(ExpectedConditions.visibilityOfElementLocated(itemLocator));

    // 3. Lấy tất cả elements
    List<WebElement> options = driver.findElements(itemLocator);

    // 4. Convert sang List String bằng Stream
    return options.stream()
            .map(e -> e.getText().trim()) // Trim để loại bỏ khoảng trắng thừa
            .filter(text -> !text.isEmpty()) // Lọc bỏ các dòng rỗng nếu có
            .collect(Collectors.toList());
}

3. Lưu ý quan trọng (Best Practices)

  • StaleElementReferenceException: Nếu dropdown bị reload lại DOM khi scroll hoặc filter, hãy lấy lại list element trước khi get text.
  • Hidden Elements: Đôi khi dropdown chứa các option ẩn, hãy dùng hàm getAttribute("textContent") thay vì getText() nếu muốn lấy cả text ẩn.
  • Performance: Với các dropdown lớn (>1000 items), hạn chế in log (System.out.println) trong vòng lặp.

Hy vọng với cách xử lý mới này, code của bạn sẽ trở nên chuyên nghiệp và tối ưu hơn!

Browser Notification with Selenium - Xử lý thông báo của trình duyệt

Chào các bạn, tối nay chúng ta lại gặp nhau!
Đã bao giờ bạn cảm thấy khó chịu khi vào 1 web mà nó show thông báo kiểu này lên chưa?



Trong bài viết này, chúng ta sẽ tìm cách disable Browser Notification  trong selenium nhé!

1. Với Chrome
chúng ta dùng code sau để khai báo driver khi dùng chrome và Java
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-notifications");
WebDriver driver = new ChromeDriver(options);
driver.get("https://adayroi.com");
2. Với Firefox
FirefoxProfile ffprofile = new FirefoxProfile();
ffprofile.setPreference("dom.webnotifications.enabled", false);
WebDriver driver = new FirefoxDriver(ffprofile);
driver.get("https://adayroi.com");
Vậy là chúng ta đã có cách disable browser notification with selenium.
Hẹn gặp các bạn trong các bài sau!

Nguồn: sưu tầm trên linkedin

iFrame Selenium - Xử lý iFrame với selenium

Chào các bạn! Bao lâu rồi chúng ta không gặp nhau?
Vâng, cũng khá lâu rồi mình mới có thể viết 1 bài. Nhân cái tiện là có 1 người chị nhờ mình xem giúp cái iFrame nên mình note lại bài này để sau này có thể sẽ cần tới.
Bài viết này chúng ta sẽ đi qua các vấn đề sau:

  1. iFrame là gì, và tại sao người ta dùng nó?
  2. cách chuyển từ main page qua iFrame và ngược lại

1. Trước tiên chúng ta sẽ tìm hiểu qua 1 chút về iFrame, và tại sao người ta dùng nó.
Chúng ta hiểu đơn giản là iFrame giống như là 1 module trong phát triển phần mềm vậy. Một dự án gồm nhiều người code, mỗi người code 1 phần rồi ghép lại. Iframe để hiển thị 1 web trong 1 trang web khác.
2. Cách nhận biết nó là 1 iframe hay kiểu popup
Chúng ta sẽ sử dụng Firefox hay Chrome để kiểm tra xem nó có phải là iFrame không nhé


Nếu khi chuột phải vào mà có "This Frame" thì chính xác rồi đó.
Một iFrame thường có dạng như sau:

3. Cách Xử lý iFrame với selenium
Để xử lý iframe thì ta sử dụng dòng code sau:
driver.switchTo.frame(...)


khi dùng lệnh driver.switchTo.frame(String) thì ta có thể dùng ID hay Name của iframe đó
ví dụ ở ảnh trên, ta có thể dùng
driver.switchTo().frame("IF1"); 
hay
driver.switchTo().frame("iframe1");

Ngoài ra chúng ta cũng có thể dùng cách truyền vào 1 WebElement như sau:

WebElement iframeElement = driver.findElement(By.id("IF1"));
driver.switchTo().frame(iframeElement); 

Sau khi đã thao tác trên iFrame xong, chúng ta cần chuyển về main page bằng lệnh sau:
driver.switchTo().defaultContent(); 

Link để các bạn thực hành: http://toolsqa.com/iframe-practice-page/

Qua bài viết này, chúng ta đã biết cách xử lý iframe với selenium ra sao. Hẹn gặp các bạn ở các bài viết sau!

Page Object Pattern using PageFactory Selenium 2026

Chào các bạn, đây là phiên bản cập nhật cho bài viết về Page Object Model (POM)PageFactory, phù hợp với các phiên bản Selenium mới nhất hiện nay (Selenium 4.x trở lên). Vào thời điểm 2026, Selenium đã có nhiều cải tiến mạnh mẽ giúp code gọn gàng và ổn định hơn.

Điểm mới trong cập nhật này:
  • Sử dụng Duration thay cho TimeUnit (đã cũ).
  • Giới thiệu Selenium Manager (tự động quản lý driver, không cần System.setProperty).
  • Tối ưu hóa Code với Fluent Interface.
  • Sử dụng WebDriverWait (Explicit Wait) chuẩn chỉnh hơn.

1. Cấu trúc Project

Chúng ta sẽ chia project thành các phần rõ ràng theo mô hình POM:

  • Pages: Chứa các class đại diện cho từng trang (LoginPage, HomePage...), nơi khai báo Element và Action.
  • Tests: Chứa các Test Case thực thi.

2. Class LoginPage (Trang Đăng Nhập)

Sử dụng @FindBy để định danh phần tử và PageFactory.initElements để khởi tạo.

package vn.haibgit.pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

public class LoginPage {
    
    private WebDriver driver;

    // Constructor: Khởi tạo PageFactory
    public LoginPage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    // Định nghĩa Element với @FindBy
    @FindBy(name = "uid")
    @CacheLookup // Cache element nếu nó không thay đổi để tăng tốc độ
    private WebElement txtUserName;

    @FindBy(name = "password")
    @CacheLookup
    private WebElement txtPassword;

    @FindBy(name = "btnLogin")
    @CacheLookup
    private WebElement btnLogin;

    @FindBy(name = "btnReset")
    private WebElement btnReset;

    // --- Action Methods ---

    public void setUserName(String name) {
        txtUserName.clear(); // Best practice: Clear trước khi nhập
        txtUserName.sendKeys(name);
    }

    public void setPassword(String password) {
        txtPassword.clear();
        txtPassword.sendKeys(password);
    }

    // Trả về HomePage sau khi login thành công (Fluent Interface)
    public HomePage clickLogin() {
        btnLogin.click();
        return new HomePage(driver);
    }

    /**
     * Phương thức Login gộp cho tiện sử dụng
     */
    public HomePage login(String userName, String password) {
        setUserName(userName);
        setPassword(password);
        return clickLogin();
    }
}

3. Class HomePage (Trang Chủ)

Ở đây chúng ta thêm xử lý đợi thông minh (Explicit Wait) để đảm bảo trang đã load xong.

package vn.haibgit.pages;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration; // Import mới cho Selenium 4+

public class HomePage {

    private WebDriver driver;

    @FindBy(className = "heading3")
    @CacheLookup
    private WebElement txtWelcome;

    public HomePage(WebDriver driver) {
        this.driver = driver;
        PageFactory.initElements(driver, this);
    }

    public boolean isPageLoaded() {
        // Sử dụng WebDriverWait với Duration (thay thế cho int/TimeUnit cũ)
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
        try {
            // Đợi cho element hiển thị rõ ràng
            wait.until(ExpectedConditions.visibilityOf(txtWelcome));
            
            String welcomeText = txtWelcome.getText();
            return welcomeText.contains("Welcome To Manager's Page of Guru99 Bank");
        } catch (Exception e) {
            return false;
        }
    }
}

4. Class TestPOM (Viết Test Case)

Lưu ý quan trọng: TimeUnit.SECONDS đã bị loại bỏ/deprecated trong các bản mới. Chúng ta chuyển sang dùng Duration.ofSeconds(...).

package vn.haibgit.tests;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import vn.haibgit.pages.HomePage;
import vn.haibgit.pages.LoginPage;
import java.time.Duration;

public class TestPOM {

    private WebDriver driver;
    // URL demo (có thể thay đổi tùy thời điểm)
    private String url = "http://demo.guru99.com/v4/"; 

    @BeforeMethod
    public void setUp() {
        // Selenium 4.x+: Không cần System.setProperty("webdriver.chrome.driver", ...)
        // Selenium Manager sẽ tự động tải driver tương thích.
        driver = new ChromeDriver();
        
        driver.manage().window().maximize();
        driver.get(url);

        // CẬP NHẬT QUAN TRỌNG: Sử dụng Duration thay vì TimeUnit
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
    }

    @Test
    public void testLoginSuccess() {
        LoginPage loginPage = new LoginPage(driver);

        // Thực hiện login và nhận về HomePage object
        HomePage homePage = loginPage.login("mngr588662", "YvUzUqa"); 

        // Verify kết quả
        Assert.assertTrue(homePage.isPageLoaded(), "Đăng nhập thất bại hoặc trang chủ chưa tải xong!");
    }

    @AfterMethod
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

5. Giải thích các thay đổi quan trọng (2026)

5.1. Duration thay cho TimeUnit

Trong các phiên bản Selenium cũ, chúng ta viết: driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Nhưng hiện tại, syntax chuẩn là: driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));

5.2. Selenium Manager

Bạn không cần phải tải thủ công chromedriver.exe và set path nữa. Thư viện Selenium sẽ tự động phát hiện trình duyệt Chrome trên máy và tải driver phù hợp nhất. Code gọn hơn rất nhiều!

5.3. Tại sao dùng @CacheLookup?

Vẫn giữ nguyên giá trị: Giúp Selenium lưu trữ element trong bộ nhớ cache sau lần tìm kiếm đầu tiên. Cực kỳ hữu ích cho các phần tử tĩnh (Logo, Menu, Input field cố định) giúp tăng tốc độ test.


Chúc các bạn áp dụng thành công Page Object Model vào dự án của mình!

How to get Auto Suggestion Text selenium

Khi bạn tìm kiếm 1 từ khóa thì google sẽ tự động gợi ý các từ khóa cho bạn. Làm thế nào để có thể lấy được các từ khóa gợi ý đó trong selenium?

Tư tưởng giải quyết vấn đề là gom tất cả các text đó vào 1 danh sách rồi in ra, hãy xem code mẫu dưới đây nhé :)

import java.util.List;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.WebElement;

import org.openqa.selenium.chrome.ChromeDriver;



public class AutoSuggestion{



 public static void main(String[] args) throws InterruptedException {

  // TODO Auto-generated method stub

  WebDriver driver = new ChromeDriver();

  driver.get("https://www.google.com.vn/");

  driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

  driver.findElement(By.id("lst-ib")).sendKeys("selenium");

  driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);

  List<WebElement> ls = driver.findElements(By.xpath("//div[contains(text(),'selenium')]"));

  for (int i = 0; i < ls.size(); i++) {

   String s = ls.get(i).getText();

   System.out.println(s);

  }

  driver.quit();

 }



}
Hãy so sánh kết quả xem đúng không các bạn nhé :D

Read Data from Excel File in Selenium Webdriver - Lấy dữ liệu từ excel với selenium


Chào các bạn, chúng ta lại gặp lại nhau trong bài viết đọc dữ liệu từ file excel.
Có thể các bạn đã nghe qua là dùng các thư viện như JXL hoặc Apache POI, nhưng trong bài này, chúng ta sẽ làm với 1 thư viện khác, mình thấy cũng khá hay , đó chính là Fillo, trang chủ và hướng dẫn của nó tại đây
Nhìn qua hướng dẫn, có thể thấy cách dùng câu lệnh select như trong SQL vậy :D
OK, bài này mình sẽ sử dụng file excle định dạng xls, với dữ liệu như trên:

TestCase của bài này là login với lần lượt name và pass tương ứng từng dòng trong excel
sẽ có 4 trường hợp xảy ra như trong data.

Để có name và pass hợp lệ thì các bạn đăng ký ở đây nhé, nhập email bất kỳ, sau đó copy lại name và pass. Dùng được trong vòng 20 ngày kể từ ngày đăng ký :)

Đầu tiên, các bạn tải thư viện của Fillo về , tiếp đó add chúng vào Build Path của project java.
Tất nhiên, cần add cả thư viện của selenium nữa chứ :D

OK, viết code thôi. Tư tưởng của mình là dùng vòng While để add các data của từng cột vào trong 1 mảng. Sau đó dùng vòng For để chạy từ phần tử đầu tiên, với mỗi phần tử đó - tức là name và pass tương ứng, thì chính là dữ liệu để login.
Sau đó so sánh title mong muốn với title hiện tại , cũng như so sánh lỗi trả về khi nhập sai name và pass.


package ReadEx;



import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.TimeUnit;



import org.openqa.selenium.Alert;

import org.openqa.selenium.By;

import org.openqa.selenium.NoAlertPresentException;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;



import com.codoid.products.exception.FilloException;

import com.codoid.products.fillo.Connection;

import com.codoid.products.fillo.Fillo;

import com.codoid.products.fillo.Recordset;



public class Test {

 static WebDriver driver;



 public static void main(String[] args) throws FilloException {

  String uName, uPass;

  String actualTitle, actualBoxtitle;



  // output mong muốn

  String EXPECT_TITLE = "Guru99 Bank Manager HomePage";

  String EXPECT_ERROR = "User or Password is not valid";

  String tc = "Test case số";



  Fillo fillo = new Fillo();

  Connection conn = fillo.getConnection("testData.xls");

  String query = "Select * from Data";

  Recordset record = conn.executeQuery(query);



  List<String> name = new ArrayList<>();

  List<String> pass = new ArrayList<>();

  // thêm name và pass vào mảng

  while (record.next()) {

   name.add(record.getField("username"));

   pass.add(record.getField("password"));

  }

  // mỗi vị trí i, lấy name và pass ở 2 cột tương ứng

  for (int i = 0; i < name.size(); i++) {

   uName = name.get(i);

   uPass = pass.get(i);



   setup();



   driver.findElement(By.name("uid")).clear();

   driver.findElement(By.name("uid")).sendKeys(uName);



   driver.findElement(By.name("password")).clear();

   driver.findElement(By.name("password")).sendKeys(uPass);



   driver.findElement(By.name("btnLogin")).click();

   try {



    Alert alt = driver.switchTo().alert();

    actualBoxtitle = alt.getText(); // lấy text của Alert

    alt.accept();

    // So sánh lỗi thực tế với lỗi mong đợi

    if (actualBoxtitle.contains(EXPECT_ERROR)) {

     System.out.println(tc + "[" + i + "]: Passed");

    } else {

     System.out.println(tc + "[" + i + "]: Failed");

    }

   } catch (NoAlertPresentException Ex) {

    actualTitle = driver.getTitle();

    // So sánh title thực tế với title mong đợi

    if (actualTitle.contains(EXPECT_TITLE)) {

     System.out.println(tc + "[" + i + "]: Login thành công");

    } else {

     System.out.println(tc + "[" + i + "]: Login lỗi");

    }



   }

   driver.close();

  }

  // đóng kết nối

  record.close();

  conn.close();

 }



 private static void setup() {

  driver = new ChromeDriver();

  driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);

  driver.get("http://www.demo.guru99.com/V4/");



 }



}

Hãy để ý trong code, những thành phần quan trọng:
File excel hãy copy vào thư mục gốc của Project
testData.xls : là tên và định dạng file excel ( excel có thể có đuôi xls, có thể có xlsx)
Select * from Data: Data là tên sheet mà chứa nội dung ta cần lấy (xem lại ảnh đầu tiên của bài)


Vậy là các bạn đã làm quen với việc đọc dữ liệu excel với selenium để viết code.
Các bạn có thể xem trên trang chủ của Fillo, để có thể biết thêm nhiều cách viết câu truy vấn với các điều kiện như dùng where...
Hẹn gặp các bạn ở bài viết tiếp theo :)

Page Object Model selenium 2026

Bài viết này hướng dẫn cách triển khai Page Object Model (POM) thuần (sử dụng By locators) thay vì dùng PageFactory, cập nhật theo chuẩn Selenium mới nhất năm 2026.

Tại sao nên dùng POM ("thuần") thay vì PageFactory?
Mặc dù PageFactory ('@FindBy') rất phổ biến, nhưng trong các dự án lớn, việc tự quản lý locator bằng đối tượng By giúp kiểm soát tốt hơn các vấn đề về StaleElementReferenceException và linh hoạt hơn khi xử lý các phần tử động (Dynamic Elements).

1. Tạo Class LoginPage (Quản lý đối tượng trang)

Thay đổi so với code cũ:

  • Dùng Encapsulation (private fields) để bảo vệ locator.
  • Hàm trả về đối tượng (return this) để hỗ trợ Chaining Method (viết code test liền mạch hơn).
package vn.haibgit.pages;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

public class LoginPage {
    
    private WebDriver driver;

    // 1. Khai báo Locators (Nên dùng private để đóng gói)
    private By txtUsername = By.name("uid");
    private By txtPassword = By.name("password");
    private By btnLogin = By.name("btnLogin");
    private By btnReset = By.name("btnReset");

    // 2. Constructor
    public LoginPage(WebDriver driver) {
        this.driver = driver;
    }

    // 3. Các Action Methods
    public LoginPage enterUsername(String username) {
        // Tốt nhất nên clear text trước khi sendKeys
        driver.findElement(txtUsername).clear();
        driver.findElement(txtUsername).sendKeys(username);
        return this; // Trả về chính nó để có thể gọi tiếp (Fluent Interface)
    }

    public LoginPage enterPassword(String password) {
        driver.findElement(txtPassword).clear();
        driver.findElement(txtPassword).sendKeys(password);
        return this;
    }

    public void clickLogin() {
        driver.findElement(btnLogin).click();
        // Sau khi click login có thể trả về HomePage object nếu cần
    }

    // Hàm Wrapper xử lý trọn vẹn 1 flow
    public void login(String username, String password) {
        this.enterUsername(username);
        this.enterPassword(password);
        this.clickLogin();
    }
}

2. Tạo Test Class (Thực thi kiểm thử)

Cập nhật quan trọng 2026:

  • Không cần set path cho driver: Selenium Manager tự động lo liệu việc download chromedriver.
  • Dùng Duration: Class TimeUnit đã cũ, hãy dùng Duration.ofSeconds().
package vn.haibgit.tests;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import vn.haibgit.pages.LoginPage;
import java.time.Duration;

public class LoginTest {

    private WebDriver driver;

    @BeforeMethod
    public void setUp() {
        // Selenium 4.x+: Tự động tải driver, không cần System.setProperty(...)
        driver = new ChromeDriver();
        
        driver.manage().window().maximize();
        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); // Syntax mới
        
        driver.get("http://demo.guru99.com/v4/");
    }

    @Test
    public void testValidLogin() {
        // Khởi tạo Page Object
        LoginPage loginPage = new LoginPage(driver);

        // Thực hiện hành động login
        // Cách viết Fluent: loginPage.enterUsername("user").enterPassword("pass").clickLogin();
        // Hoặc dùng hàm wrapper:
        loginPage.login("mngr588662", "YvUzUqa");

        // Verify title (Ví dụ)
        String expectedTitle = "Guru99 Bank Manager HomePage";
        String actualTitle = driver.getTitle();
        Assert.assertEquals(actualTitle, expectedTitle, "Tiêu đề trang không khớp!");
    }

    @AfterMethod
    public void tearDown() {
        if (driver != null) {
            driver.quit();
        }
    }
}

Việc áp dụng POM giúp code sạch sẽ, dễ bảo trì và dễ mở rộng (Scalability) hơn rất nhiều so với việc viết code Spag

Chuột phải trong selenium - Right Click in Selenium WebDriver

Chào các bạn!
Bài viết hôm nay chúng ta sẽ học về cách sử dụng chuột phải trong selenium.
Để click chuột phải vào một phần tử trong Selenium, chúng ta sử dụng lớp Actions. Lớp Actions được cung cấp bởi Selenium Webdriver được sử dụng để tạo các cử chỉ người dùng phức tạp bao gồm click chuột phải, click đúp chuột, kéo và thả...

Chúng ta sử dụng đoạn code sau để click chuột phải vào 1 element bất kỳ

Actions action = new Actions(driver);
WebElement element = driver.findElement(By.id("elementId"));
action.contextClick(element).perform();

OK, bây giờ chúng ta sẽ thực hành với 1 ví dụ đơn giản dưới đây:

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

public class RightClick {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  System.setProperty("webdriver.chrome.driver", "D:\\NVH\\selenium\\gecko\\chromedriver.exe");
  WebDriver driver = new ChromeDriver();
  driver.get("https://www.google.com.vn/");
  WebElement timkiem = driver.findElement(By.id("lst-ib"));
  timkiem.sendKeys("selenium");
  timkiem.sendKeys(Keys.ENTER);
  driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  Actions action = new Actions(driver);
  WebElement element = driver.findElement(By.xpath("//*[@id=\"rso\"]/div[1]/div/div/div/div/h3/a"));
  action.contextClick(element).perform();
 }

}

Bài 3 - Kiểm tra xem coupon giảm giá có hoạt động đúng không?

Hôm nay chúng ta sẽ tiếp tục viết testcase tiếp theo.
Bài này chúng ta sẽ kiểm tra xem coupon có hoạt động đúng như mong hay không, trong trường hợp này là 5%.

Hướng giải quyết vấn đề của mình như sau:
vào trang detail sản phẩm, sau đó mua hàng-> nhập mã giảm giá -> lấy số tiền cụ thể được giảm -> so sánh với số tiền thực tế(cái này tự tính).

package demo_thuchanh;


import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestCase1 {
 private WebDriver driver;
   private String url; 
   
 @BeforeTest
 public void setUp() throws Exception {
  System.setProperty("webdriver.chrome.driver","C:\\chrome\\chromedriver.exe");
     driver = new ChromeDriver();
     url = "http://live.guru99.com/";
     driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
     
   }
   
 @Test 
   public void TestCase() throws Exception {
  driver.get(url); 
     
     // 2. Click Mobile menu
     driver.findElement(By.linkText("MOBILE")).click(); 
  // 3. Click vào sản phẩm
     driver.findElement(By.id("product-collection-image-2")).click();
     // 4. thêm sp vào giỏ hàng
     driver.findElement(By.className("add-to-cart-buttons")).click();
     driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
     // 5. áp dụng mã giảm giá
     driver.findElement(By.id("coupon_code")).sendKeys("GURU50");
     driver.findElement(By.cssSelector("[title=\"Apply\"]")).click();
     // 6. lấy số tiền giảm giá (nó hiện là -$25.00) nên sẽ phải chuyển nó qua StringBuilder và cắt vị trí 0 tới 2-> sẽ thành 25.00, 
     //sau đó cắt tiếp từ vị trí 2-5> sẽ được 25
     String giamgia=driver.findElement(By.xpath("//*[@id=\"shopping-cart-totals-table\"]/tbody/tr[2]/td[2]")).getText();
     StringBuilder str=new StringBuilder(giamgia);
     str.delete(0, 2);
     str.delete(2, 5);
     // lấy giá 5% để so sánh với giá trên xem đúng không
     int giagiam=(500*5)/100;
     //so sánh, nếu đúng thì testcase pass, trái lại thì fail
     try {
                //chúng ta cần ép kiểu nó về String để so sánh, vì 1 thằng là int, 1 thằng là StringBuilder, không so sánh được
      Assert.assertEquals(String.valueOf(str), String.valueOf(giagiam)); 
       } catch (Exception e) {
        e.printStackTrace();
       }
   
   }
 
 
 
 @AfterTest
 public void tearDown() throws Exception {
  driver.quit();
   }

}


Sau khi chạy code thì kết quả ok, như mong muốn :D


Trong bài này, chúng ta học được

  • Cách ép kiểu khác như int...về String
  • Cách chuyển String về StringBuilder để dễ dàng cắt ký tự ở vị trí mong muốn
Hẹn gặp các bạn ở bài kế tiếp!




Bài 2: Xác nhận giá của sản phẩm trong list page and details page là bằng nhau

Chào các bạn, ở bài tập trước chúng ta đã học được 1 vài bước cơ bản rồi, hôm nay chúng ta sẽ làm bài số 2.
Vì một số lý do như có quá nhiều thông báo...nên mình sẽ không dùng trang web của adayroi nữa mà chuyển qua web của guru99 để thực hành.
Testcase của bài tập ngày hôm nay như sau:



Bây giờ chúng ta thực hành thôi, bài này mình sẽ sử dụng testNG để các bạn thấy được cấu trúc của nó. Bạn hãy chắc chắn rằng bạn đã cài testNG cho eclipse theo hướng dẫn ở đây

package demo_thuchanh;

import static org.testng.Assert.assertEquals;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

public class TestCase1 {
 private WebDriver driver;
   private String url; 
   
 @BeforeTest
 public void setUp() throws Exception {
  System.setProperty("webdriver.chrome.driver","C:\\chrome\\chromedriver.exe");
     driver = new ChromeDriver();
     url = "http://live.guru99.com/";
     driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
   }
   
   @Test
   public void TestCase() throws Exception {
  
  // 1. Go to http://live.guru99.com
     driver.get(url); 
     
     // 2. Click on Mobile menu
     driver.findElement(By.linkText("MOBILE")).click(); 
   
     // 3. In the list of all mobile , read the cost of Sony Xperia mobile (which is $100)             
     String gia_XPeria = driver.findElement(By.cssSelector("#product-price-1 > span.price")).getText();
    
     // 4. Click on Sony Xperia mobile     
     driver.findElement(By.id("product-collection-image-1")).click();
     
     // 5. Read the XPeria mobile price from details page
     String gia_Detail = driver.findElement(By.cssSelector("span.price")).getText();
          
     //  Product price in list and details page should be equal ($100)
     try {
         assertEquals(gia_XPeria, gia_Detail); 
       } catch (Exception e) {
        e.printStackTrace();
       }
   }
 
 @AfterTest
 public void tearDown() throws Exception {
  driver.quit();
   }

}


Hãy nhìn vào code, bạn sẽ thấy cú pháp @BeforeTest, @Test và @AfterTest.

  • Những thứ setup cần thiết, chúng ta sẽ nhét vào BeforeTest
  • Các bước thực hiện testcase, thì chúng ta sẽ cho vào Test
  • Sau cùng thì sẽ cho vào AfterTest, kiểu như close() hay quit() :D

Đây là kết quả sau khi chạy testcase này

Hẹn gặp các bạn ở bài tiếp theo.

Bài 1: tìm kiếm và sắp xếp kết quả - adayroi

Bài này chúng ta sẽ thực hành 1 vài yêu cầu cơ bản như sau:
Step 1. vào https://www.adayroi.com, in ra title của trang chủ
Step 2. tìm kiếm từ khóa điện thoại
Step 3. chọn sắp xếp theo Bán chạy nhất
Step 4. chụp ảnh màn hình để xem lại kết quả

Dưới đây là code của bài tập này

/* 

https://haibgit.blogspot.com/

Test Steps

Step 1. vào https://www.adayroi.com, in ra title của trang chủ

Step 2. tìm kiếm từ khóa điện thoại

Step 3. chọn sắp xếp theo Bán chạy nhất

Step 4. chụp ảnh màn hình để xem lại kết quả

*/



package BaiTap;



import java.io.File;

import java.io.IOException;

import java.util.concurrent.TimeUnit;

import org.openqa.selenium.By;

import org.openqa.selenium.OutputType;

import org.openqa.selenium.TakesScreenshot;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.chrome.ChromeDriver;

import org.apache.commons.io.FileUtils;





public class Ngay1 {

 public static void main(String[] args) throws IOException {

  String url = "https://www.adayroi.com";

  WebDriver  driver = new ChromeDriver();

  driver.get(url);

  System.out.println(driver.getTitle());

  //nhập từ khóa điện thoại và ô tìm kiếm

  driver.findElement(By.id("header__main__segment_search__form__input")).sendKeys("điện thoại");

  //sau đó click tìm kiếm

  driver.findElement(By.id("header__main__segment_search__form__submit")).click();

     driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);

     //tìm menu dropdown sắp xếp

     driver.findElement(By.id("products_list_order_by_container")).click();

     //click vào bán chạy nhất

     driver.findElement(By.id("a_order_1")).click();

     driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

     //chụp ảnh màn hình để xem kết quả

     File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);

  String png = ("C:\\Ngay1\\sap xep"  + ".png");

  FileUtils.copyFile(scrFile, new File(png));
            //đóng trình duyệt
  driver.close();

 }



}

Sau đây chúng ta hãy nhìn hình ảnh lưu trong C:\Ngay1


Hẹn gặp các bạn ở các bài tiếp theo!

Mở trình duyệt Edge với Selenium Webdriver

Qua các bài viết trước, chúng ta đã có thể chạy selenium bằng trình duyệt Firfox và Chrome.
Hôm nay chúng ta sẽ chạy selenium bằng trình duyệt Microsoft Edge trên Win10.
Trước tiên, cần mở Edge của bạn lên, xem phiên bản bao nhiêu bằng cách click vào nút ... sau đó chọn Settings->About


Sau đó vào link sau, tải bản tương ứng với trình duyệt Edge của bạn, trong bài là mình dùng bản phù hợp với Edge của máy mình.

Kế tiếp các bạn copy file vừa tải về vào đường dẫn mà chúng ta đã set patch trong bài hướng dẫn này.
Trong bài hướng dẫn của mình là ở đường dẫn C:\gecko


Sau khi đã copy xong, thì ta chỉ việc sử dụng code sau để khai báo biến cho driver

WebDriver driver=new EdgeDriver();


Sau đó chạy là ok thôi :D
Hẹn gặp lại các bạn ở bài tiếp theo

TestNG là gì? cài đặt và sử dụng

Bài viết ngày hôm nay chúng ta sẽ đi tìm hiểu xem:

  • TestNG là gì?
  • Tại sao chúng ta cần dùng nó?
  • Cài đặt và sử dụng với testcase đầu tiên.

TestNG là gì?

TestNG là một testing framework - nó cải tiến những hạn chế của một testing framework phổ biến khác gọi là JUnit. TestNG (Next Generation) có nghĩa là "Thế hệ kế tiếp".
Hầu hết người dùng Selenium sử dụng nó nhiều hơn Junit vì lợi ích của nó. Có rất nhiều tính năng của TestNG, nhưng chúng ta sẽ chỉ tập trung vào những thứ quan trọng nhất mà chúng ta có thể sử dụng trong Selenium.

Các tính năng của TestNG

  • Hỗ trợ cho các chú thích
  • Hỗ trợ tham số
  • Phương pháp thực hiện trước mà không yêu cầu phải tạo các bộ kiểm tra
  • Hỗ trợ kiểm tra dữ liệu bằng cách sử dụng Dataproviders
  • Cho phép người dùng thiết lập các ưu tiên thực hiện cho các phương pháp thử
  • Dễ dàng hỗ trợ tích hợp với các công cụ và plug-in khác nhau như công cụ xây dựng (Ant, Maven vv), Môi trường phát triển tích hợp (Eclipse).
  • Tạo báo cáo hiệu quả bằng ReportNG

TestNG so với JUnit

Có nhiều ưu điểm khác nhau làm cho TestNG vượt trội so với JUnit. Một số trong số đó là:
  • Chú thích dễ hiểu
  • Các mẫu thực thi có thể được thiết lập
  • Thực hiện kiểm thử song song
  • Có thể đặt các phụ thuộc cho trường hợp thử nghiệm
Chú thích được đặt trước bởi một biểu tượng "@" trong cả hai TestNG và JUnit.

Tại sao chúng ta cần dùng TestNG?

TestNG có thể tạo ra các báo cáo dựa trên kết quả kiểm tra Selenium.
Chú thích dễ hiểu, làm cấu trúc code dễ dàng hơn



Bắt đầu với phần cài đặt và thực hiện.

1.Chạy Eclipse lên, click vào Help trên menu



Sau đó tìm kiếm với từ khóa TestNG rồi cài đặt








Sau quá trình cài đặt, cần yêu cầu restart Eclipse. Sau khi khởi động lại Eclipse, chúng ta kiểm tra bằng cách vào menu Window -> Preferences



Viết testcase đầu tiên với TetsNG

Trong project hiện tại, cần add thư viện của TestNG vào bằng cách chuột phải vào tên project, chọn Properties


Trong package, tạo mới TestNG class bằng cách, chuột phải vào tên packge, chọn New->Other->TestNG class, đặt tên tùy ý rồi finish


OK, giờ sẽ bắt đầu kịch bản test đầu tiên:
click vào trang web https://haibgit.blogspot.com/ , sau đó xác nhận title của trang web
package demoguru99;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.Test;

public class NewTest {
  String url="https://haibgit.blogspot.com/";
  WebDriver driver;
  
   @Test
   public void verifyHomepageTitle() {
  System.setProperty("webdriver.chrome.driver","C:\\chrome\\chromedriver.exe");
   driver = new ChromeDriver();
    driver.get(url);
    //case pass khi title mong muốn = thực tế, vậy nên cần 2 biến để so sánh
    String title_mongmuon="Automation Testing Tutorials";
    //title thực tế: lấy title hiện có của trang web
    String title_thucte=driver.getTitle();
    //so sánh 2 title với nhau, nếu giống thì pass, còn không thì fail
   Assert.assertEquals(title_thucte, title_mongmuon);
    driver.close();
   }
 
   } 

Đoạn code trên cũng đơn giản, dễ hiểu. Nếu các bạn đã set patch theo hướng dẫn này thì không cần thêm dòng này nữa
System.setProperty("webdriver.chrome.driver","C:\\chrome\\chromedriver.exe");
Kết quả sau khi chạy testNG
Ngoài ra, chúng ta có thể nhìn thấy báo cáo của testNG bằng cách chuột phải vào Project, chọn Refresh
Sau đó sẽ nhìn thấy thư mục test-output được tạo ra


Chúng ta có thể click đúp vào file html để xem báo cáo.
Vậy là chúng ta đã tìm hiểu cơ bản về TestNG, và tại sao phải sử dụng nó kết hợp với selenium webdriver.
Hẹn gặp lại các bạn ở bài tiếp theo.




Selenium - khái niệm cơ bản 2026

Selenium là gì?

Selenium là bộ công cụ mã nguồn mở (Open Source) dùng để tự động hóa trình duyệt web (Browser Automation). Nó được sử dụng rộng rãi nhất trong lĩnh vực Automation Testing cho ứng dụng web.

Đặc điểm nổi bật:

  • Miễn phí, cộng đồng sử dụng rất lớn trên toàn thế giới.
  • Hỗ trợ đa trình duyệt: Chrome, Firefox, Edge, Safari.
  • Hỗ trợ đa hệ điều hành: Windows, macOS, Linux.
  • Hỗ trợ đa ngôn ngữ lập trình: Java, Python, C#, JavaScript, Ruby, Kotlin.
  • Tích hợp dễ dàng với các framework: TestNG, JUnit, pytest, NUnit, Mocha...

Các thành phần của Selenium (2026)

Tính đến thời điểm hiện tại, Selenium gồm 4 thành phần chính:

1. Selenium WebDriver

Đây là thành phần cốt lõi và quan trọng nhất. WebDriver cho phép bạn viết code để điều khiển trình duyệt theo lập trình (programmatically).

Những thay đổi quan trọng trong Selenium 4:

  • W3C WebDriver Protocol: Selenium 4 sử dụng chuẩn W3C thay vì JSON Wire Protocol cũ. Điều này giúp giao tiếp giữa code và trình duyệt ổn định, nhất quán hơn rất nhiều.
  • Options thay cho DesiredCapabilities: Không còn dùng DesiredCapabilities, thay vào đó sử dụng ChromeOptions, FirefoxOptions, EdgeOptions... để cấu hình trình duyệt.
  • ChromeDriver kế thừa ChromiumDriver: Kiến trúc class rõ ràng hơn, ChromeDriver và EdgeDriver giờ cùng kế thừa từ ChromiumDriver.
// Selenium 3 (CŨ - không nên dùng nữa)
DesiredCapabilities caps = new DesiredCapabilities();
caps.setBrowserName("chrome");
WebDriver driver = new RemoteWebDriver(caps);

// Selenium 4 (MỚI - cách chuẩn hiện tại)
ChromeOptions options = new ChromeOptions();
options.addArguments("--start-maximized");
WebDriver driver = new ChromeDriver(options);

2. Selenium IDE

Selenium IDE là công cụ Record & Playback cho phép ghi lại thao tác trên trình duyệt mà không cần viết code.

Có gì mới?

  • Selenium IDE đã được viết lại hoàn toàn, hiện là extension cho Chrome, FirefoxEdge.
  • Hỗ trợ control flow: if, else, while, times.
  • Có thể export test script sang nhiều ngôn ngữ (Java, Python, C#, JavaScript...).
  • Chạy test từ command line với selenium-side-runner (cần Node.js).
Lưu ý: Selenium IDE phù hợp để học và tạo test nhanh (prototype). Với dự án thực tế, bạn nên chuyển sang Selenium WebDriver để có khả năng tùy biến và bảo trì tốt hơn.

3. Selenium Grid

Selenium Grid cho phép bạn chạy test song song (parallel) trên nhiều máy, nhiều trình duyệt cùng lúc, giúp giảm đáng kể thời gian thực thi.

Grid trong Selenium 4 đã được thiết kế lại hoàn toàn:

  • Kiến trúc mới: Gộp Hub và Node vào một file JAR duy nhất; có thể chạy Standalone hoặc Distributed mode.
  • Hỗ trợ Docker & Kubernetes: Tích hợp native với Docker/K8s, dễ dàng deploy lên cloud.
  • Giao diện quản lý mới: UI trực quan hơn, xem được trạng thái node, session đang chạy, live preview.
  • Tối ưu parallel testing: Load balancing tốt hơn, phân phối test hiệu quả hơn.
# Chạy Grid Standalone (cách đơn giản nhất)
java -jar selenium-server-4.x.x.jar standalone

# Mở Grid UI tại: http://localhost:4444/ui

4. Selenium Manager

Đây là thành phần mới hoàn toàn trong Selenium 4 (không có trong bài viết cũ năm 2017).

  • Selenium Manager tự động tải và quản lý browser driver (chromedriver, geckodriver, msedgedriver...) phù hợp với version trình duyệt đang cài trên máy.
  • Bạn không cần tải driver thủ công hay sử dụng thư viện bên thứ 3 như WebDriverManager nữa.
  • Chỉ cần viết code và chạy — Selenium Manager sẽ lo phần còn lại.
Lưu ý quan trọng: Nếu bạn đọc tài liệu cũ (trước 2022), hầu hết sẽ hướng dẫn bạn tải chromedriver thủ công và đặt vào System PATH. Với Selenium 4 mới, bước này không còn cần thiết nữa.

Tính năng nổi bật của Selenium 4

Ngoài các thay đổi ở từng thành phần, Selenium 4 còn mang đến nhiều tính năng mạnh mẽ:

Relative Locators (Locator tương đối)

Cho phép tìm element dựa trên vị trí tương đối so với element khác, rất trực quan:

  • above() — phía trên
  • below() — phía dưới
  • toLeftOf() — bên trái
  • toRightOf() — bên phải
  • near() — gần
// Tìm element nằm bên dưới element có id="email"
WebElement password = driver.findElement(
    RelativeLocator.with(By.tagName("input")).below(By.id("email"))
);

Chrome DevTools Protocol (CDP)

Selenium 4 tích hợp native với CDP, mở ra nhiều khả năng nâng cao:

  • Giả lập mạng (Network emulation): test trên 3G, offline...
  • Giả lập vị trí địa lý (Geolocation)
  • Bắt console log, network request
  • Phân tích hiệu năng trang web (Performance metrics)

Quản lý Window/Tab mới

Mở tab hoặc window mới dễ dàng mà không cần tạo WebDriver object mới:

// Mở tab mới
driver.switchTo().newWindow(WindowType.TAB);

// Mở window mới
driver.switchTo().newWindow(WindowType.WINDOW);

So sánh nhanh: Selenium 3 vs Selenium 4

Tiêu chí Selenium 3 Selenium 4
Giao thức JSON Wire Protocol W3C WebDriver Protocol
Cấu hình browser DesiredCapabilities Browser Options (ChromeOptions...)
Driver management Thủ công hoặc WebDriverManager Selenium Manager (tự động)
Relative Locators Không có above(), below(), near()...
CDP Support Không có Tích hợp native
Selenium Grid Cấu hình phức tạp (Hub/Node riêng) Đơn giản, hỗ trợ Docker/K8s
Window/Tab management Phức tạp API newWindow(), newTab() đơn giản
Selenium IDE Chỉ Firefox, bị ngưng phát triển một thời gian Chrome, Firefox, Edge; viết lại hoàn toàn

Bắt đầu nhanh với Selenium 4 (Java)

Dưới đây là ví dụ đơn giản để bạn chạy thử ngay:

Bước 1: Thêm dependency (Maven)

<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>4.33.0</version>
</dependency>

Bước 2: Viết test đầu tiên

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.By;

public class FirstTest {
    public static void main(String[] args) {
        // Selenium Manager tự động tải chromedriver - không cần setup thủ công!
        ChromeOptions options = new ChromeOptions();
        options.addArguments("--start-maximized");

        WebDriver driver = new ChromeDriver(options);

        // Mở trang web
        driver.get("https://www.google.com");

        // Tìm ô search và nhập text
        driver.findElement(By.name("q")).sendKeys("Selenium WebDriver tutorial");

        // In ra title
        System.out.println("Page title: " + driver.getTitle());

        // Đóng trình duyệt
        driver.quit();
    }
}

Tài liệu tham khảo chính thức


Bài viết được cập nhật tháng 02/2026. Nếu bạn thấy thông tin nào đã lỗi thời, hãy để lại comment bên dưới nhé!

Chọn Option trong DropDown sử dụng Selenium Webdriver

Bài viết trước, chúng ta đã tìm hiểu về cách để lấy các element của 1 trang web.
Trong bài viết này, chúng ta sẽ tìm hiểu cách để chọn dữ liệu khi gặp phải dropdown.
kịch bản code ngày hôm nay, chúng ta sẽ vào trang đăng ký user, điền các thông tin cần thiết, sau đó click nút Submit. Ví dụ dưới đây sử dụng link demo của guru99 - http://demo.guru99.com/selenium/newtours/register.php

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.ui.Select;
public class demo_acc {

 public static void main(String[] args) {
  // TODO Auto-generated method stub
  WebDriver driver=new ChromeDriver();
  driver.get("http://demo.guru99.com/selenium/newtours/register.php");
  
  driver.findElement(By.name("firstName")).sendKeys("nguyen");
  driver.findElement(By.name("lastName")).sendKeys("van hai");
  driver.findElement(By.name("phone")).sendKeys("0123456");
  driver.findElement(By.name("userName")).sendKeys("haibgit@gmail.com");
  driver.findElement(By.name("address1")).sendKeys("hai ba trung");
  driver.findElement(By.name("city")).sendKeys("Ha noi");
  driver.findElement(By.name("state")).sendKeys("100000");
  driver.findElement(By.name("postalCode")).sendKeys("12345");
  //khai báo biến con_country để tìm phần tử có name=country
  //sau đó chọn giá trị AMERICAN SAMOA để đăng ký
  Select chon_country=new Select(driver.findElement(By.name("country")));
  chon_country.selectByVisibleText("AMERICAN SAMOA");
  
  driver.findElement(By.name("email")).sendKeys("haibgit");
  driver.findElement(By.name("password")).sendKeys("123456");
  driver.findElement(By.name("confirmPassword")).sendKeys("123456");
  driver.findElement(By.name("submit")).click();
 }

}
Trong code bên trên, cũng đã giải thich cho các bạn hiểu hơn. chú ý nên sử dụng lệnh import bên dưới để có thể dùng lệnh Select
import org.openqa.selenium.support.ui.Select;

Sau khi chạy code thành công, sẽ ra màn hình đăng ký thành công.

Hẹn gặp lại các bạn ở bài tiếp theo.
Nguồn: bài viết với kiến thức tìm tòi trên mạng, có mượn link của guru99 để test :D