Chào các bạn đã đến với chủ đề tiếp theo của mình. Hôm nay, mình sẽ tiếp tục giới thiệu về cách xử lý với Window/Tab. Khi bạn mở 1 trang web bất kỳ và click vào 1 cái link nào đó (ví dụ như link facebook or quảng cáo). Lúc đó, 1 tab mới sẽ được hiển thị.
Ví dụ như hình trên, khi bạn click vào Click Here link or Elemental Selenium link, 2 cửa sổ mới sẽ được hiển thị. Trong auto, mặc định mọi thao tác chỉ có thể thực hiện trên page đầu tiên. Để thao tác với 2 tab bạn vừa mở, bạn phải switch sang 2 cửa sổ đó mới có thể thao tác được. Nào, chúng ta hãy bắt đầu đi vào nội dung chính nhé.
Nội dung
1. Các hàm thường sử dụng cho Window/Tab
1.1. Hàm getWindowHandle()
Hàm này sẽ giúp bạn lấy được window handle của cửa sổ hiện tại (hay ta có thể gọi là original window hoặc là cửa sổ cha – parent window).
Window handle là một ID duy nhất chứa địa chỉ của 1 window/tab. Về cơ bản, đây là một con trỏ trỏ tới window/tab đó, và nó sẽ trả về giá trị chuỗi.
String handle = driver.getWindowHandle();
1.2. Hàm getWindowHandles()
Hàm này sẽ giúp bạn lấy IDs của tất cả các cửa sổ đang mở. Bạn lưu ý là Window Handle không phân biệt tab hay window nhé, nó chỉ biết hiện tại có bao nhiêu cửa số và các tab đang mở.
Chúng ta cũng sẽ sử dụng phương thức Set để chứa tất cả các window handle theo kiểu String nhé
Set<String> allWindowIds = driver.getWindowHandles();
1.3. Hàm switchTo window
Hàm này sẽ giúp chúng ta di chuyển qua lại giữa các cửa sổ.
driver.switchTo().window(target_window);
Thông thường sẽ có 2 các để di chuyển qua lại giữa các cửa sổ:
- Sử dụng window id
- Sử dụng window title
Mình sẽ hướng dẫn cụ thể thông qua ví dụ bên dưới.
1.4. Hàm wait numberOfWindowsToBe()
Hàm này sẽ giúp chúng ta đợi cho đến khi tab mới được mở lên. Tham số truyền vào là số lượng cửa sổ đang mở.
// Wait up to 5 seconds to the second tab to be opened
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.numberOfWindowsToBe(2));
2. Ví dụ
2.1. Sử dụng window ID
- Cách này thường được sử dụng khi chúng ta đã biết được ID của cửa sổ đang active.
- Ví dụ:
- Open https://the-internet.herokuapp.com/windows (Đây là cửa sổ cha – parent window)
- Click on Click Here button (Lúc này, tab “New Window” sẽ được mở. Mình tạm gọi là cửa sổ 1)
- Back to parent window, click on button Elemental Selenium. (cửa sổ 2 sẽ được mở)
@Test
public void TC_01_SwitchByWindowID() throws InterruptedException {
driver.get("https://the-internet.herokuapp.com/windows");
// Get ID of parent window
String parentWindowId = driver.getWindowHandle();
// Click on Click Here button
driver.findElement(By.xpath("//a[text()='Click Here']")).click();
// Wait for new window opened
explicitWait.until(ExpectedConditions.numberOfWindowsToBe(2));
Thread.sleep(3000);
// Back to parent window, click on button Elemental Selenium.
driver.switchTo().window(parentWindowId);
Thread.sleep(3000);
driver.findElement(By.xpath("//a[text()='Elemental Selenium']")).click();
// Wait for new window opened
explicitWait.until(ExpectedConditions.numberOfWindowsToBe(3));
Thread.sleep(3000);
// Back to parent window
driver.switchTo().window(parentWindowId);
Thread.sleep(3000);
}
Kết quả
2.2. Sử dụng window title
- Cách này thường được sử dụng khi chúng ta mở nhiều cửa sổ và biết được title của mỗi cửa sổ tương ứng. Nếu muốn biết title của window đang active là gì thì các bạn bật F12 lên, nó sẽ nằm trong thẻ html -> head -> title
- Lưu ý: Chúng ta sẽ sử dụng cách này khi title của mỗi cửa sổ là duy nhất, không trùng tên. Nếu trùng title, bản thân driver sẽ không biết switch vào cửa sổ nào -> sẽ dẫn đến failed test case.
- Ví dụ:
- Open https://the-internet.herokuapp.com/windows (Đây là cửa sổ cha – parent window)
- Verify header “Opening a new window” displayed in parent window
- Click on Click Here button (Lúc này, tab “New Window” sẽ được mở. Mình tạm gọi là cửa sổ con 1)
- Switch to window 1 by title “New Window”
- Verify header “New Window” displayed on child window (window1)
- Back to parent window, click on button Elemental Selenium. (cửa sổ con 2 sẽ được mở)
- Switch to window 2 by title “Elemental Selenium | Elemental Selenium”
- Verify header “Make sure your code lands” displayed con child window (window2)
- Verify that total window opened = 3
@Test
public void TC_02_SwitchByWindowTitle() throws InterruptedException {
driver.get("https://the-internet.herokuapp.com/windows");
// Get ID of parent window
String parentWindowId = driver.getWindowHandle();
System.out.println("Parent window ID: " + parentWindowId);
// Verify header "Opening a new window" displayed on parent window
String header1 = driver.findElement(By.tagName("h3")).getText();
Assert.assertEquals(header1, "Opening a new window");
// Click on Click Here button
driver.findElement(By.xpath("//a[text()='Click Here']")).click();
// Wait for new window opened
explicitWait.until(ExpectedConditions.numberOfWindowsToBe(2));
Thread.sleep(3000);
// Switch to window 1 by title "New Window"
switchToWindowByTitle("New Window");
// Get ID of child window 1
String childWindow1 = driver.getWindowHandle();
System.out.println("Child window 1 ID: " + childWindow1);
// Verify header "New Window" displayed on child window (window1)
String header2 = driver.findElement(By.tagName("h3")).getText();
Assert.assertEquals(header2, "New Window");
Thread.sleep(3000);
// Back to parent window, click on button Elemental Selenium.
driver.switchTo().window(parentWindowId);
Thread.sleep(3000);
driver.findElement(By.xpath("//a[text()='Elemental Selenium']")).click();
// Wait for new window opened
explicitWait.until(ExpectedConditions.numberOfWindowsToBe(3));
Thread.sleep(3000);
// Switch to window 2 by title "Elemental Selenium | Elemental Selenium"
switchToWindowByTitle("Elemental Selenium | Elemental Selenium");
// Get ID of child window 2
String childWindow2 = driver.getWindowHandle();
System.out.println("Child window 2 ID: " + childWindow2);
// Verify header "Make sure your code lands" displayed con child window (window2)
String header3 = driver.findElement(By.tagName("h1")).getText();
Assert.assertEquals(header3, "Make sure your code lands");
Thread.sleep(3000);
// Verify that total window opened = 3
assert driver.getWindowHandles().size() == 3;
// Back to parent window
driver.switchTo().window(parentWindowId);
Thread.sleep(3000);
}
public void switchToWindowByTitle(String expectedWindowTitle) {
// Get all opened window id
Set<String> allWindowIds = driver.getWindowHandles();
System.out.println("Number of window opened: " + allWindowIds.size());
for(String windowId : allWindowIds) {
// Switch to each window/tab
driver.switchTo().window(windowId);
// Get ra title cua tuang window/tab
String actualWindowTitle = driver.getTitle();
// Check if title of current window match with expected -> stop
if(actualWindowTitle.equals(expectedWindowTitle)) {
break;
}
}
}
Kết quả:
2.3. Close all windows except parent
- Sau khi open nhiều cửa sổ, và đã xử lý xong rồi thì mình hãy close bớt cửa sổ để nhìn bớt rối hơn nhé.
- Ở đây mình sẽ sử dụng lại ví 2.1 ở trên:
- Open https://the-internet.herokuapp.com/windows (Đây là cửa sổ cha – parent window)
- Click on Click Here button (Lúc này, tab “New Window” sẽ được mở. Mình tạm gọi là cửa sổ 1)
- Back to parent window, click on button Elemental Selenium. (cửa sổ 2 sẽ được mở)
- Close all child windows except parent
public void TC_03_CloseAllWindowsExceptParent() throws InterruptedException {
driver.get("https://the-internet.herokuapp.com/windows");
// Get ID of parent window
String parentWindowId = driver.getWindowHandle();
// Click on Click Here button
driver.findElement(By.xpath("//a[text()='Click Here']")).click();
Thread.sleep(3000);
// Back to parent window, click on button Elemental Selenium.
driver.switchTo().window(parentWindowId);
driver.findElement(By.xpath("//a[text()='Elemental Selenium']")).click();
Thread.sleep(3000);
// Close all child windows except parent
closeAllWindowsExceptParent(parentWindowId);
Thread.sleep(3000);
}
public void closeAllWindowsExceptParent(String parentId) throws InterruptedException {
// Get all opened window id
Set<String> allWindowIDs = driver.getWindowHandles();
for(String windowId : allWindowIDs) {
if(!parentId.equals(windowId)) {
// Switch to each window/tab
driver.switchTo().window(windowId);
driver.close();
Thread.sleep(2000);
}
}
driver.switchTo().window(parentId);
}
Kết quả:
3. Lời kết
Như vậy chúng ta đã tìm hiểu qua 1 vài ví dụ để xử lý cho window/tab. Cảm ơn các bạn đã theo dõi bài viết của mình. Chúc các bạn thành công. Hẹn gặp lại các bạn ở những chủ đề tiếp theo. Bái bai.