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 đến các bạn cách xử lý khi gặp lỗi Stale Element Referent Exception trong quá trình làm automation. Đây là 1 lỗi rất thường hay xảy ra trong automation và mất khá nhiều thời gian để xử lý nó. Vậy lỗi này xảy ra khi nào?
- Lúc đầu, khi bạn tương tác vào DOM của trang web, selenium sẽ lưu lại reference của element đó. Ví dụ:
x --> WebElement A
, x ở đây là reference. - Khi trang web bị refresh thì DOM sẽ được tạo lại, dẫn đến tình trạng reference sẽ bị stale (hỏng), có nghĩa là reference
x
này không trỏ đếnWebElement A
mới mà đang trỏ vào cáiWebElement A
cũ. - Khi bạn dùng
x
như click() hoặc getText() thì có nghĩa bạn đang trỏ vào thằngWebElement A
cũ –> bị Stale Element Reference Exception.
Các cách để fix lỗi này:
Nội dung
1. Thêm wait time
Cách đơn giãn nhất là bạn hãy đợi 1 khoảng thời gian để cho DOM render xong. Ví vụ như: Thread.sleep(3000)
–> đợi 3s. Rồi get lại Element mà mình muốn tương tác:
Cách này có điểm dở là:
- Có khi thời gian đợi không đủ, có khi 2s, có khi là 5s. Khi nó chỉ cần 2s mà mình đợi 3s thì đợi thừa mất 1s, còn khi nó cần đến 5s mà mình chỉ đợi 3s sẽ vẫn bị Stale Element Reference Exception
2. Kết thúc hành động ở trạng thái ready
Khi 1 hành động tương tác với DOM, hãy đợi đến khi trang web refresh xong, hoàn thành việc render.
Ví dụ:
- Click button A –> refresh 1 phần của trang web –> hãy đợi đến khi 1 Element nào đó thay đổi trạng thái, đừng wait chính cái element mà đang bị Stale Element Reference Exception. Giả sử bạn đang muốn lấy
Item Two
thì đừng kiểm traItem Two
mà hãy kiểm tra elementText X
@Test
void checkItemTwo(){
clickA();
wait.util(ExpectedConditions.invisibilityOfElementLocated(TextX));
getItemTwo();
}
Vì mục tiêu là để web ở trạng thái ready sau khi 1 hành động được diễn ra, nên wait kia nên đặt vào trong method clickA()
.
@Test
void checkItemTwo(){
clickA();
getItemTwo();
}
void clickA(){
...
wait.util(ExpectedConditions.invisibilityOfElementLocated(TextX));
}
3. Retry đến khi tương tác được thì thôi
Flow có thể như sau:
- Get
Item Two
, nếu bị StaleElementReferenceException thì tiếp tục get lại thêm 1 lần nữa, giữa 2 lần tương tác sẽ đợi tầm 500ms. Hết n lần retry mà không được khi throw ra RuntimeException.
public String retryGetText(By by) {
int attempts = 0;
while (attempts < 5) {
try {
return driver.findElement(by).getText();
} catch (StaleElementReferenceException e) {}
attempts++;
waitIn(500);
}
throw new RuntimeException("Cannot get text from element: " + by);;
}
private void waitIn(long mili){
try {
Thread.sleep(mili);
} catch (Exception ignored) {}
}
4. Kết
Như vậy chúng ta đã tìm hiểu qua cách xử lý khi gặp lỗi Stale Element Referent Exception trong quá trình làm automation. Vì phần này hơi khó nên các bạn hãy đọc kỹ lại nhé. Mình hy vọng bài viết này sẽ hữu ích cho các bạn. Cảm ơn các bạn đã theo dõi bài viết của mình. Hẹn gặp lại các bạn ở những chủ đề tiếp theo.
Nguồn:
https://giangtester.com/cach-xu-ly-stale-element-reference-exception-trong-selenium/