Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Đóng cửa sổ con (Child Browser Window) với Selenium WebDriver Java

Khi click link/button mở cửa sổ mới (popup, tab mới), Selenium coi đó là child window. Để đóng child window và quay về parent, ta dùng getWindowHandles() và Iterator.

Quy trình chuẩn

  1. Lưu parent handle: String parent = driver.getWindowHandle();
  2. Thao tác mở child window.
  3. Lấy tất cả handles: Set handles = driver.getWindowHandles();
  4. Dùng Iterator lấy 2 handle đầu (parent, child).
  5. Switch sang child → driver.close();
  6. Switch về parent.

Ví dụ hoàn chỉnh

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Iterator;
import java.util.Set;

public class CloseChildWindow {
    public static void main(String[] args) {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        
        try {
            driver.get("https://secure.example.com/login");
            
            // 1. Parent handle
            String parentWindow = driver.getWindowHandle();
            System.out.println("Parent: " + driver.getTitle());
            
            // 2. Mở child window
            driver.findElement(By.id("login-google-button")).click();
            
            // 3. Chờ child window (nên dùng WebDriverWait)
            Thread.sleep(2000);
            
            // 4. Lấy handles và dùng Iterator
            Set handles = driver.getWindowHandles();
            Iterator it = handles.iterator();
            
            String childWindow = it.next(); // Handle đầu tiên
            String parentWindowCheck = it.next(); // Handle thứ hai
            
            // Lưu ý: Thứ tự iterator không đảm bảo parent là đầu tiên!
            // Cách an toàn hơn: so sánh với parentWindow đã lưu
            
            // 5. Switch sang child và đóng
            driver.switchTo().window(childWindow);
            System.out.println("Child window title: " + driver.getTitle());
            driver.close(); // Đóng child
            
            // 6. Switch về parent
            driver.switchTo().window(parentWindow);
            System.out.println("Quay về parent: " + driver.getTitle());
            
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            driver.quit();
        }
    }
}

Cách an toàn hơn (Không phụ thuộc thứ tự Iterator)

String parent = driver.getWindowHandle();
Set allHandles = driver.getWindowHandles();

for (String handle : allHandles) {
    if (!handle.equals(parent)) {
        driver.switchTo().window(handle);
        System.out.println("Đóng child: " + driver.getTitle());
        driver.close();
        break; // Chỉ đóng 1 child
    }
}
driver.switchTo().window(parent);

Đóng TẤT CẢ child windows

String parent = driver.getWindowHandle();
for (String handle : driver.getWindowHandles()) {
    if (!handle.equals(parent)) {
        driver.switchTo().window(handle);
        driver.close();
    }
}
driver.switchTo().window(parent);

Lưu ý quan trọng

  • Thứ tự Iterator không đảm bảo – không giả định handle đầu tiên là parent/child.
  • Sau driver.close() trên child, handle child trở nên invalid.
  • Nếu có nhiều child window, duyệt qua tất cả handles trước khi đóng (lưu vào List) để tránh ConcurrentModificationException.
  • driver.quit() đóng tất cả cửa sổ và kết thúc session – dùng ở cuối test.

Debug tip

// In tất cả window handles và title để debug
for (String h : driver.getWindowHandles()) {
    driver.switchTo().window(h);
    System.out.println("Handle: " + h + " | Title: " + driver.getTitle());
}