I. Wait
1. Tổng quan về wait
- Trong automation có rất nhiều hành động, nó chia ra các action, các action này sẽ phải load và đơi các element xuất hiện, sau đó mới làm việc tiếp được ví dụ như chúng ta click login thì phải đơi login xong thì mới làm việc được, còn nếu chưa login xong thì element nó sẽ chưa xuất hiện, nếu chúng ta thực hiện hành động tìm kiếm thì nó sẽ bị lỗi, để tránh các trường hợp như vậy, chúng ta phải có các hành động đợi cho các element xuất hiện.
- Cách đơn giản nhất để chúng ta wait đó là dùng thread.sleep(truyền vào thời gian tính theo mili giây), nó sẽ tạm dừng script của chúng ta lại, và hết khoảng thời gian này nó mới chạy tiếp, mặc dù đây là cách đơn giản nhất nhưng nó lại là cách dở nhất vì nó fix cứng khoảng thời gian wait mà bình thường thời gian wait không cố định, phụ thuộc rất nhiều yếu tố như tốc độ mạng, cấu hình máy....., nếu chúng ta fix cứng khoảng thời gian lớn quá thì sẽ rất lãng phí thời gian, ngược lại nếu thời gian wait không đủ thì nó lại bị lỗi, vì vậy chúng ta tuyệt đối không dùng thread.sleep(), chỉ dùng trong trường hợp debug để test xem thời gian chờ có đủ hay không thôi.Hình 1: WebDriver Wait trong Selenium
2. Các loại wait
a. Implicit wait
- Cú pháp: driver.manage().timeouts().implicitlyWait(Khoảng thời gian, Đơn vị giây hay mili giây...);
- Chúng ta chỉ cần set 1 lần sau khi khởi tạo browser, thì lúc này nó sẽ 1 thời gian implicit wait, lúc này khi chúng ta tìm element, nếu nó không tìm ra element thì nó sẽ throw ra một các exception, tuy nhiên khi chúng ta sử dụng implicit wait thì mỗi khi tìm các element mà nó không tìm thấy element thì nó sẽ liên tục cái element đấy, nếu như trong khoảng thời gian timeout mà nó tìm thấy element thì nó sẽ chạy tiếp không wait nữa, còn hết khoảng thời gian timeout rồi mà nó không tìm thấy element thì nó mới có exeption xảy ra.
- Ưu điểm: Nó đảm bảo được lúc nào chúng ta tìm element thì nó đều có wait, tránh được exception khi chúng ta tìm element.
- Nhược điểm: Nó set chung cho cả project, mà có chỗ thì chúng ta wait lâu, có chỗ chúng ta wait nhanh, cho nên nó sẽ không phù hợp với project có nhiều khoảng thời gian wait.
- Implicit wait chủ yếu được sử dụng trong những trang sử dụng công nghệ ajax vì công nghệ ajax.
b. Explicit wait
- Explicit wait nó sẽ khắc phục được các nhược điểm của implicit wait, nó có thể set các khoảng thời gian timeout khác nhau và theo một điều kiện nào đó, nếu trong khoảng thời gian timeout mà cái điều kiện đó thỏa mãn thì nó sẽ chạy tiếp, còn hết khoảng thời gian timeout mà điều kiện vẫn không thỏa mãn thì nó sẽ báo lỗi.
- Để sử dụng được Explicit wait thì chúng ta phải khai báo ra một WebDriverWait: WebDriverWait wait = new WebDriverWait(driver, Khoảng thời gian timeout tính theo giây), sau đó khi nào chúng ta muốn wait thì chúng ta sẽ gọi đến wait.until(ExpectedConditions. cái điều kiện đã được định nghĩa sẵn);
- Chúng ta có thể khai báo nhiều cái WebDriverWait khác nhau cho các khoảng thời gian timeout khác nhau với các điều kiện khác nhau, chỉ khi nào gọi wait thì nó mới wait.
- Chúng ta có rất nhiều các điều kiện truyền vào đã được định nghĩa sẵn, tuy nhiên mình chỉ liệt kê ra những cái hay dùng nhất ở dưới đây, những cái còn lại, các bạn có thể tìm hiểu thêm trên internet.
elementToBeClickable(): Nó sẽ wait cho đến khi element có thể click vào được.
c. Custom-expected conditions
- Tự tạo ra điều kiện để wait, trong trường hợp các điều kiện có sẵn không thoải mãn các điều kiện của chúng ta thì chúng ta có thể tự tạo ra các condition.- Để tạo ta condition riêng của chúng ta thay vì gọi wait.until(ExpectedConditions.Cái điều kiện có sẵn) thì ở đây chúng ta sẽ gọi đến đến wait.until(new ExpectedCondition<Boolean>()) và khai báo 1 method có kiểu trả về là boolean, trong method này sẽ truyền vào driver và trả về 1 giá trị boolean, khi chúng ta chạy gọi đến cái wait này thì nó kiểm tra chạy hàm apply này, nếu hàm này trả về giá trị là true thì nó sẽ không wait nữa và chạy tiếp, còn nếu hàm này trả về giá trị là false thì nó sẽ tiếp tục gọi đến hoàn apply cho đến khi trả về giá trị là true, còn quá thời gian timeout nó sẽ trả về giá trị là false.
- Ví dụ:
- (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>()
{
public Boolean apply(WebDriver d) {
return d.findElement(By.id("userName")).
getAttribute("readonly").contains("true");
}});
d. Kiểm tra trạng thái của element
- Kiểm tra element có tồn tại hay không thì chúng ta có thể tạo ra 1 method, bình thường trong selenium RC thì nó hỗ trợ hàm này, tuy nhiên trong selenium web driver thì nó không hỗ trợ hàm này nữa, nếu chúng ta muốn kiểm tra element có tồn tại hay không thì chúng dùng driver.findElement() để tìm đến element đó quản lý trong 1 try catch, nếu như có ngoại lệ xảy ra thì element đó không tồn tại và ngược lại
- Ví dụ: private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
}
- Một số method để trả về trạng thái của element đó là:
isEnabled (): Phương thức này kiểm tra xem một element có được enalble hay không. Trả về true nếu enable, ngược lại trả về false nếu disable
isSelected (): Phương thức này kiểm tra xem element có được chọn hay không (radio button, checkbox, v.v.). Nó sẽ trả về true nếu được chọn, còn lại là false nếu không được chọn
isDisplayed (): Phương thức này kiểm tra xem phần tử có được hiển thị hay không.
e. Làm việc với pop up window
- Khi chúng ta click vào 1 link hay một button nào đó, nó sẽ mở cho chúng ta 1 cửa sổ mới, hay browser mới, thì cái đó gọi là popup
- By Name
- Sau khi chúng ta click vào các button để chúng ta mở các pop up thì chúng ta sẽ phải switch đến các pop up đó để chúng ta làm việc. Vì vậy chúng ta phải dùng cú pháo driver.switchTo().window() để chúng ta chuyển đến các window đó và ở đây như ví dụ chúng ta phải truyền vào "HelpWindow".
- Ví dụ:
try
{
//Switch to the Help Popup Browser Window
driver.switchTo().window("HelpWindow");
} catch (NoSuchWindowException e) {
e.printStackTrace();
}
- By Title
Có vấn đề xảy ra đó là có rất nhiều window làm sao chúng ta tìm được đến window chúng ta cần, cách làm là chúng ta switch đến tất cả các window mà driver này đang quản lý và sau đó chúng ta kiểm tra xem, window đó có phải window chúng ta cần hay không, dựa theo 1 số các yếu tố như title hay cái text nào đó trong window, chúng ta cứ switch đến khi nào đúng cái window chúng ta cần mới làm việc. Để làm được điều đó chúng ta phải get được cái danh sách window handle mà cái driver nó đang quản lý thông qua câu lệnh driver.getWindowHandles() nó sẽ trả về tập hợp các window handle Set<String>, và sau đó chúng ta sẽ lọc đến từng cái window id, chúng ta dùng driver.switchTo().window(windowId).getTitle() để chúng ta chuyển đến cái window đó, trong ví dụ dưới chúng ra dùng hàm getTitle().equals("Visit Us") để kiểm tra tille có chứa cái Visit us hay không, sau khi chúng ta làm việc với window đó xong thì chúng ta phải đóng driver lại và dùng break để bỏ qua các window khác. Sau khi làm việc xong với pop up rồi chúng ta phải quay lại làm việc với window cũ, quay về với window cũ chúng ta phải lưu cái window handle của window cũ lại bằng cách khi báo 1 string ví dụ như String parentWindowId = driver.getWindowHandle(); lưu ý là nếu là windowHandle không có S thì nó sẽ trả về cho cái window hiện tại, còn nếu có S thì nó sẽ trả về tất cả các window handle của driver.
- Ví dụ:
//Get Handles of all the open Popup Windows
//Iterate through the set and check if tile of each window matches
//with expected Window Title
Set<String> allWindows = driver.getWindowHandles();
if(!allWindows.isEmpty()) {
for (String windowId : allWindows) {
try {
if(driver.switchTo().window(windowId).getTitle().
equals("Visit Us")) {
//Close the Visit Us Popup Window
driver.close();
break;
}
}
catch(NoSuchWindowException e) {
e.printStackTrace();
}
}
}
//Move back to the Parent Browser Window
driver.switchTo().window(parentWindowId);
- By Content
- Ví dụ:
Set<String> allWindows = driver.getWindowHandles();
if(!allWindows.isEmpty()) {
for (String windowId : allWindows) {
driver.switchTo().window(windowId);
if(driver.getPageSource().contains("Build my Car Configuration - Online Chat")) {
try {
//Find the Close Button on Chat Popup Window and close the Popup
//by clicking Close Button instead of closing it directly
WebElement closeButton = driver.findElement(By.
id("closebutton"));
closeButton.click();
break;
} catch(NoSuchWindowException e) {
e.printStackTrace();
}
}
}
}
//Move back to the Parent Browser Window
driver.switchTo().window(currentWindowId);
f. Làm việc với Alert
Alert là message hiển thị trên màn hình, được tạo ra bởi java script. Chúng ta quản lý cái Alert này thông qua class Alert, chúng ta sẽ khi báo một cái Alert alert = driver.switchTo().alert(); lúc này nó sẽ chuyển tới cái alert đang hiển thị trên màn hình và sau đó chúng ta có thể làm việc với cái alert này thông qua class aleart, chúng ta có thể gọi alert.accept(); để click vào cái OK button hoặc alert.dismiss(); để click vào cái cancel button, hoặc chúng ta có thể get text của alert bằng alert.getText();....
Sẽ có một số loại aleart sau:
- Simple alert: Nó chỉ có 1 cái út OK
//Get the Alert
Alert alert = driver.switchTo().alert();
//Get the Text displayed on Alert using getText() method of
Alert class
String textOnAlert = alert.getText();
//Click OK button, by calling accept() method of Alert Class
alert.accept();
//Verify Alert displayed correct message to user
assertEquals("Hello! I am an alert box!",textOnAlert);
} catch (NoAlertPresentException e) {
e.printStackTrace();
}
- Confirm alert: Nó có 2 nút là OK và Cancel
Ví dụ: try {
//Get the Alert
Alert alert = driver.switchTo().alert();
//Click OK button, by calling accept() method of Alert
//Class
alert.accept();
//Verify Page displays correct message on Accept
WebElement message = driver.findElement(By.id("demo"));
assertEquals("You Accepted Alert!", message.getText());
} catch (NoAlertPresentException e) {
e.printStackTrace();
}
- Prompt alert: Ngoài 2 nút OK và Cancel nó còn bắt chúng ta nhập text vào.
Ví dụ: try {
//Get the Alert
Alert alert = driver.switchTo().alert();
//Enter some value on Prompt by calling sendKeys() method of
//Alert Class
alert.sendKeys("Foo");
//Click OK button, by calling accept() method of Alert Class
alert.accept();
//Verify Page displays message with value entered in Prompt
WebElement message = driver.findElement(By.id("prompt_demo"));
assertEquals("Hello Foo! How are you today?", message.
getText());
} catch (NoAlertPresentException e) {
e.printStackTrace();
}
Chúng ta có thể vào link sau để tham khảo một số Alert: https://demoqa.com/alerts
g. Làm việc với Frame và iFrame
- Thông thường, trong các trang web nó hay có frame và iframe để nó chia trang web của chúng ta ra thành nhiều trang web nhỏ khác nhau, việc load từng trang web nhỏ sẽ không ảnh hưởng đến trang web lớn, trang web lớn có thể load xong rồi, nhưng trang web nhỏ có thể vẫn đang load, hiện nay chủ yếu dùng iframe chứ ít khi dùng frame.
- Thông thường khi chúng ta tìm các element trong Iframe thì chúng ta sẽ không tìm được, muốn tìm được thì chúng ta phải switch đến cái iFrame đó chúng ta mới làm việc được,
- Để làm việc với iFrame chúng ra phải dùng lệnh driver.switchTo().frame() đề chúng ta di chuyển cái frame mà ta cần, frame và iframe đều làm việc giống nhau, sau khu switch đến frame đó mà muốn trở về frame cũ ta dùng driver.switchTo().parentFrame()
- Nếu Frame trong Frame thì chúng ta phải switch làm nhiều lần.








0 Bình luận:
Đăng nhận xét