การปิด Child Window (popup/หน้าต่างใหม่) ต้องสลับ context ไปที่ child window ก่อน แล้วจึง close() และสลับกลับ parent
ขั้นตอนหลัก
- เก็บ parent window handle ไว้ก่อน
- ทำ action ที่เปิด child window
- ได้ all window handles มา iterate
- สลับไป child window →
close() - สลับกลับ parent window
ตัวอย่างโค้ดสมบูรณ์
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class CloseChildWindow {
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver",
"C:\\Users\\ghs6kor\\Desktop\\Java\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
driver.manage().window().maximize();
try {
driver.get("https://secure.indeed.com/account/login");
// 1. เก็บ parent handle
String parentHandle = driver.getWindowHandle();
System.out.println("Parent window: " + parentHandle);
// 2. คลิกเปิด child window (Google login)
driver.findElement(By.id("login-google-button")).click();
// 3. รอ child window เปิด
Thread.sleep(3000);
// 4. ได้ handles ทั้งหมด
Set handles = driver.getWindowHandles();
System.out.println("Total windows: " + handles.size());
// 5. Iterate หา child window (ใช้ Iterator)
Iterator iterator = handles.iterator();
String childHandle = null;
while (iterator.hasNext()) {
String handle = iterator.next();
if (!handle.equals(parentHandle)) {
childHandle = handle;
break;
}
}
// 6. สลับไป child และปิด
if (childHandle != null) {
driver.switchTo().window(childHandle);
System.out.println("Child window title: " + driver.getTitle());
driver.close(); // ปิด child window
System.out.println("Child window closed");
}
// 7. สลับกลับ parent (สำคัญมาก!)
driver.switchTo().window(parentHandle);
System.out.println("Back to parent: " + driver.getTitle());
} catch (Exception e) {
e.printStackTrace();
} finally {
driver.quit();
}
}
}
วิธีที่ 2: ใช้ Stream API (Java 8+) - สั้นกว่า
String parentHandle = driver.getWindowHandle();
// ... action ที่เปิด child window ...
// หา child handle และปิด
driver.getWindowHandles().stream()
.filter(h -> !h.equals(parentHandle))
.findFirst()
.ifPresent(childHandle -> {
driver.switchTo().window(childHandle);
System.out.println("Closing: " + driver.getTitle());
driver.close();
driver.switchTo().window(parentHandle);
});
วิธีที่ 3: ปิด Child Windows ทั้งหมด (ถ้ามีหลายตัว)
String parentHandle = driver.getWindowHandle();
for (String handle : driver.getWindowHandles()) {
if (!handle.equals(parentHandle)) {
driver.switchTo().window(handle);
driver.close();
}
}
driver.switchTo().window(parentHandle);
⚠️ ข้อผิดพลาดที่พบบ่อย
| ผิด | ถูกต้อง |
|---|---|
driver.close(); แล้วไม่ switch กลับ | ต้อง driver.switchTo().window(parentHandle); หลัง close |
Iterate getWindowHandles() ขณะกำลัง close | เก็บ handles ไว้ใน list ก่อน แล้วค่อย iterate |
| คิดว่า handle คงที่ | Handle สุ่มใหม่ทุก session ไม่ควร hardcode |
ความแตกต่าง: close() vs quit()
close()- ปิดหน้าต่าง/แท็บ **ปัจจุบัน** เท่านั้นquit()- ปิด **ทุกหน้าต่าง** และจบ WebDriver session
Best Practice: Wrapper Method
public void closeChildWindows(WebDriver driver) {
String parent = driver.getWindowHandle();
driver.getWindowHandles().stream()
.filter(h -> !h.equals(parent))
.forEach(h -> {
driver.switchTo().window(h);
driver.close();
});
driver.switchTo().window(parent);
}