Cách xử lý các Exceptions trong Selenium WebDriver

Selenium WebDriver là một công cụ mạnh mẽ để tự động hóa các tương tác của trình duyệt web, hỗ trợ Tester kiểm thử tự động trên website dễ dàng. Tuy nhiên, trong quá trình tự động hóa, bạn có thể gặp phải nhiều ngoại lệ khác nhau (Exceptions) có thể ảnh hưởng đến việc thực hiện thử nghiệm.

Ngoại lệ trong Selenium đề cập đến lỗi hoặc sự cố xảy ra khi thực thi tập lệnh tự động hoặc chạy thử nghiệm Test Automation với Selenium WebDriver. Những ngoại lệ này thường do các sự kiện hoặc điều kiện bất ngờ gây gián đoạn luồng bình thường trong script của bạn.

Bài viết này Anh Tester cung cấp cho các bạn tổng quan toàn diện về các ngoại lệ phổ biến trong Selenium WebDriver, cùng với các giải thích, giải pháp và ví dụ mã code cho từng trường hợp ngoại lệ.

Sau đây là tất cả các ngoại lệ trong Selenium WebDriver:


1. NoSuchElementException:

- Giải thích: Không thể tìm thấy một phần tử trong DOM.
- Nguyên nhân có thể: Bộ định vị không chính xác hoặc vấn đề về thời gian.
- Giải pháp: Kiểm tra lại bộ định vị và thực hiện chờ đợi rõ ràng theo điều kiện phù hợp (explicit waits).
- Ví dụ code Selenium Java:

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("elementId")));



2. TimeoutException:

- Giải thích: Không thể thực hiện hành động trong khoảng thời gian quy định.
- Nguyên nhân có thể: Phần tử không thể tương tác hoặc độ trễ mạng.
- Giải pháp: Tăng thời gian chờ và tối ưu hóa điều kiện mạng. Cần setup chạy lại cho những trường hợp như này. 
- Ví dụ code Selenium Java:

WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("button")));



3. ElementNotVisibleException:

- Giải thích: Cố gắng tương tác với một phần tử không hiển thị.
- Nguyên nhân có thể: Phần tử bị ẩn hoặc bị che khuất.
- Giải pháp: Đảm bảo phần tử hiển thị và kiểm tra các sự kiện CSS/JS.
- Ví dụ code Selenium Java:

JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("arguments[0].scrollIntoView(true);", element);



4. StaleElementReferenceException:

- Giải thích: Cố gắng tương tác với một phần tử cũ.
- Nguyên nhân có thể: DOM được làm mới hoặc các cập nhật không đồng bộ. Đã load gặp rồi xong loading của web/app làm biến mất. Ví dụ cái kết quả search nó change giá trị liên tục khi vừa nhập vừa tìm kết quả đang hiện chẳng hạn.
- Giải pháp: Định vị lại phần tử và sử dụng đợi rõ ràng (explicit waits).
- Ví dụ code Selenium Java:

driver.navigate().refresh();
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.stalenessOf(element));

Hoặc

WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.refreshed(ExpectedConditions.visibilityOfElementLocated(By.id("elementId"))));
// Thực hiện các hành động trên phần tử


Hoặc

- Đợi trang load xong mới thao tác (waitForPageLoaded)
- Sau đó tìm kiếm lại phần tử đó một lần nữa cho chắc, cần thiết thì kết hợp sleep vào cố định khoảng thời gian 1 2s chẳng hạn



5. ElementNotInteractableException:

- Giải thích: Một phần tử bị che bởi một phần tử khác, không thao tác hành động được.
- Nguyên nhân có thể: Các phần tử chồng lên nhau hoặc các sự kiện JS làm che element cần thao tác.
- Giải pháp: Cuộn phần tử bị che khuất ấy vào tầm nhìn hoặc sử dụng JS executor để hành động.
- Ví dụ mã:

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



6. NoSuchWindowException:

- Giải thích: Cố gắng chuyển sang một cửa sổ không tồn tại.
- Nguyên nhân có thể: Cửa sổ bị đóng hoặc xử lý sai.
- Giải pháp: Xác minh sự tồn tại của cửa sổ (nhìn mắt theo dõi) và sự chính xác trong code xử lý cho chuẩn.
- Ví dụ mã: in cái giá trị windowHandles để biết có tổng số bao nhiêu cửa sổ đang tồn tại

Set<String> windowHandles = driver.getWindowHandles();
if (windowHandles.size() > 1) {
   driver.switchTo().window(windowHandles.toArray()[1].toString());
}



7. UnhandledAlertException:

- Giải thích: Gặp một cảnh báo chưa được xử lý trên trang.
- Nguyên nhân có thể: Cảnh báo hoặc nhắc nhở của JavaScript hiện mà chưa xử lý được nó.
- Giải pháp: Xử lý cảnh báo bằng giao diện Alert của WebDriver.
- Ví dụ mã:

try {
    driver.findElement(By.id("myButton")).click();
} catch (UnhandledAlertException f) {
    try {
        Alert alert = driver.switchTo().alert();
        String alertText = alert.getText();
        System.out.println("Alert Text: " + alertText);
        alert.accept();
    } catch (NoAlertPresentException e) {
        e.printStackTrace();
    }
}



8. UnexpectedTagNameException:

- Giải thích: Gặp tên thẻ không đúng mong đợi khi khởi tạo lớp Select.
- Nguyên nhân có thể: Thẻ phần tử web không đúng hoặc sử dụng không đúng.
- Giải pháp: Khởi tạo lớp Select với thẻ <select>.
- Ví dụ mã:

WebElement dropdown = driver.findElement(By.tagName("select"));
Select select = new Select(dropdown);



9. InvalidSelectorException:

- Giải thích: Bộ chọn không hợp lệ được sử dụng để tìm phần tử.
- Nguyên nhân có thể: Lỗi cú pháp hoặc bộ chọn không được hỗ trợ.
- Giải pháp: Kiểm tra cú pháp của bộ chọn và sử dụng các bộ chọn được hỗ trợ.
- Ví dụ mã:

WebElement element = driver.findElement(By.cssSelector("invalidSelector"));



10. SessionNotCreatedException:

- Giải thích: Không thể tạo phiên session driver mới với máy chủ WebDriver.
- Nguyên nhân có thể: Máy chủ WebDriver không truy cập được hoặc phiên bản không tương thích.
- Giải pháp: Khởi động lại máy chủ WebDriver và đảm bảo tính tương thích. Hoặc tắt IDE chạy lại.
- Ví dụ mã: Selenium 3 có thể dùng thư viện bổ trợ WebDriverManager hoặc nếu Selenium 4 thì không cần dùng WebDriverManager.

**Selenium 3:

WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();

** Selenium 4:

WebDriver driver = new ChromeDriver();



11. MoveTargetOutOfBoundsException:

- Giải thích: Cố gắng di chuyển con trỏ chuột ra ngoài giới hạn của cửa sổ trình duyệt.
- Nguyên nhân có thể: Cung cấp tọa độ không hợp lệ cho việc di chuyển chuột.
- Giải pháp: Đảm bảo tọa độ nằm trong khu vực hiển thị và cuộn nếu cần.
- Ví dụ mã:

Actions actions = new Actions(driver);
actions.moveToElement(element, xOffset, yOffset).perform();



12. InvalidCookieDomainException:

- Giải thích: Cố gắng thêm một cookie với miền không hợp lệ.
- Nguyên nhân có thể: Không khớp miền hoặc định dạng miền không đúng.
- Giải pháp: Xác minh miền của cookie và đảm bảo là đúng.
- Ví dụ mã:

Cookie cookie = new Cookie("cookieName", "cookieValue", "invalidDomain", "/");
driver.manage().addCookie(cookie);



13. InvalidCoordinatesException:

- Giải thích: Cung cấp tọa độ không hợp lệ cho một hành động.
- Nguyên nhân có thể: Tọa độ vượt ra ngoài giới hạn hoặc sử dụng không đúng.
- Giải pháp: Kiểm tra giá trị tọa độ và đảm bảo tính đúng đắn. Nằm trong vùng màn hình.
- Ví dụ mã: chú ý cái kích cỡ màn hình bao nhiêu pixel

Actions actions = new Actions(driver);
actions.moveByOffset(xOffset, yOffset).perform();



14. ScriptTimeoutException:

- Giải thích: Thời gian chờ thực thi kịch bản vượt quá thời gian cài đặt.
- Nguyên nhân có thể: Mã JavaScript chạy lâu hoặc vòng lặp vô hạn.
- Giải pháp: Tối ưu hóa mã JavaScript và tăng thời gian chờ nếu cần.
- Ví dụ mã:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState"));



15. InvalidElementStateException:

- Giải thích: Phần tử không ở trạng thái hợp lệ cho hoạt động.
- Nguyên nhân có thể: Phần tử bị vô hiệu hóa hoặc chỉ đọc. Element có thể bị disable.
- Giải pháp: Đảm bảo phần tử được kích hoạt và kiểm tra các sự kiện JS phải load xong.
- Ví dụ mã: nên viết hàm waitForPageLoad để chờ đợi trang load xong mới thao tác sau.

WebElement element = driver.findElement(By.id("elementId"));
if (element.isEnabled()) {
    // Thực hiện hành động
}



16. InvalidSessionIdException:

- Giải thích: ID phiên không hợp lệ được sử dụng cho tương tác WebDriver.
- Nguyên nhân có thể: Phiên hết hạn hoặc ID phiên không đúng. Có thể do chạy song song nó tắt các luồng chưa đúng, hoặc setup code đã close driver mà còn thao tác bước khác đang dùng đến driver trong khi đã bị tắt trước đó.
- Giải pháp: Khởi động lại phiên WebDriver hoặc kiểm tra ID phiên.

17. NoAlertPresentException:

- Giải thích: Không tìm thấy Alert hiện trên trang.
- Nguyên nhân có thể: Cảnh báo hoặc nhắc nhở của JavaScript chưa kịp hiện mà đã thao tác xử lý nó.
- Giải pháp: Chờ đợi có Alert xuất hiện mới thao tác. Sau đó xử lý cảnh báo bằng giao diện Alert của WebDriver.
- Ví dụ mã:

// Đợi cho đến khi cảnh báo xuất hiện
WebDriverWait wait = new WebDriverWait(driver, 10);
Alert alert = wait.until(ExpectedConditions.alertIsPresent());
try {
   Alert alert = driver.switchTo().alert();
   // Thực hiện hành động
} catch (NoAlertPresentException e) {
   // Xử lý ngoại lệ hoặc ghi lại thông báo lỗi
}

 

18. NoSuchFrameException:

- Giải thích: Không tìm thấy thẻ IFrame chỉ định trên trang.
- Nguyên nhân có thể: IFrame chưa kịp hiện mà đã switch sang nó. Hoặc giá trị IFrame không tồn tại.
- Giải pháp: Chờ đợi có IFrame xuất hiện mới thao tác. Sau đó xử lý chuyển đến IFrame cho đúng.
- Ví dụ mã:

// Đợi cho đến khi IFrame xuất hiện và chuyển sang IFrame đó
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt(By.id("iframeId")));

// Thực hiện các thao tác bên trong IFrame
WebElement elementInsideIframe = driver.findElement(By.id("elementIdInsideIframe"));
elementInsideIframe.click();

// Chuyển trở lại khung (frame) mặc định nếu cần
driver.switchTo().defaultContent();

 

19. NullPointerException:

- Giải thích: Giá trị WebDriver bị null. Hoặc các đối tượng class khác bị null.
- Nguyên nhân có thể: WebDriver chưa được khởi tạo đúng cách, hoặc đúng cách mà lại truyền driver không đúng cũng dẫn đến sai giá trị thì bị null. Nhất class khi kế thừa class dùng chung driver hoặc khi thiết kế driver toàn cục.
- Giải pháp: xem driver tại vị trí khởi tạo trước, xong xem luồng truyền driver đến vị trí đang dùng có phải là một driver hay không. In ra xem có giá trị không. Cố gắng lần theo code mà kiểm tra.

20. NoSuchSessionException:

- Giải thích: giá trị của driver hiện tại không còn mang giá trị dẫn đến không tìm thấy phiên làm việc hiện tại.
- Nguyên nhân có thể:

  • Phiên làm việc đã bị kết thúc.
  • Phiên làm việc chưa được khởi tạo.
  • WebDriver đã bị đóng trước khi thao tác một vài hành động khác còn lại.

- Giải pháp:

  • Đảm bảo driver được khởi tạo đúng cách trước khi thực hiện bất kỳ thao tác nào.
  • Kiểm tra và đảm bảo rằng WebDriver không bị đóng hoặc thoát trước khi tất cả các thao tác khác hoàn thành.
  • Sử dụng khối try-catch để đảm bảo WebDriver được quản lý đúng cách.

- Ví dụ mã:

// Đóng trình duyệt sau khi hoàn thành các thao tác
// Cần kiểm tra giá trị driver trước khi đóng
if (driver != null) {
    try {
        driver.quit();
    } catch (NoSuchSessionException e) {
        System.out.println("NoSuchSessionException khi cố gắng đóng trình duyệt: Phiên làm việc đã kết thúc.");
    }
}

 

Kết luận:

Hiểu và xử lý hiệu quả các ngoại lệ trong Selenium WebDriver là rất quan trọng để kiểm thử tự động thành công. Bằng cách xác định nguyên nhân và áp dụng các giải pháp phù hợp cho các ngoại lệ này, Tester có thể tạo ra các bài kiểm thử tự động chạy suôn sẻ và đáng tin cậy hơn.

  • Anh Tester

    Đườ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