Selenium: Chọn ngày tháng từ calendar

1361

Bài viết được sự cho phép của tác giả To Thi Van Anh

Sau một thời gian trôi nổi qua các chủ đề, hôm nay mình lại quay lại Selenium đây 😀 thỉnh thoảng đảo gió cho có thêm nguồn năng lượng mới cái!.

  Các kiểu “đợi chờ” trong Selenium Webdriver: Implicit wait, Explicit wait và Fluent wait
  Làm quen: Tóm tắt cơ bản về Selenium

Có một loại element bạn sẽ rất hay gặp ở một số trang như đặt vé máy bay hoặc là đặt phòng khách sạn nhà hàng, vầng đó là chọn ngày tháng năm. Trên trang web sẽ có một hay một vài trường khi mà bạn click vào đó nó sẽ hiện ra một bảng ngày tháng (gọi là calendar), việc của bạn là chọn một giá trị ngày tháng bất kì nào đó, và thay vì bạn chọn bằng tay lần này qua lần khác, thì bây giờ sẽ là viết code selnium để nó chọn cho bạn mỗi lần bạn chạy test. Bạn sẽ làm như thế nào?

calendar_ex

Tìm hiểu vấn đề

Lướt sơ qua một số các nhập dữ liệu kiểu này, thì có thể có hai trường hợp và thực hiện như sau:

1. Bạn có thể sendkey trực tiếp vào trường ngày tháng đó một giá trị bất kỳ nào đó đúng format quy định là được.

2. Click vào trường đó, thực hiện next, back tháng tùy ý, sau đó chọn 1 giá trị ngày bất kỳ nào đó của tháng, dữ liệu sẽ được fill theo đúng giá trị bạn vừa chọn vào ô text.

Với cách đầu tiên thì quá đơn giản rồi, mình không nói đến nữa, vì nếu làm cách đó thì việc duy nhất bạn cần phải chú ý chỉ là nhập đúng format của ngày tháng cho trường đó là được, nhưng phải lưu ý là không phải chỗ nào cũng dùng cách đó được đâu nha, vì vậy trước khi quyết định phải xem các thuộc tính, kiểu html của trường dữ liệu trước đã nhé! 😀

Với cách thứ hai, cũng có nhiều hướng giải quyết, nhưng hôm nay mình sẽ chia sẻ với các bạn một cách mà mình nghĩ rằng nó cũng khá ổn, thông qua ví dụ cụ thể dưới này.

Giải quyết vấn đề

Để minh họa cho cách làm thứ hai, mình sẽ sử dụng trang web về du lịch có link nhu sau: https://www.path2usa.com/travel-companions

Đầu tiên, thực hiện click vào trường Date với cú pháp:

driver.findElement(By.id("travel_date")).click();

Tiếp theo, nhấn next chọn tháng – ở đây mình sẽ giả định trường hợp là chúng ta sẽ chọn ngày tháng sau ngày tháng hiện tại nên chỉ thực hiện nhấn next thôi, đối với các trường hợp khác thì bạn có thể kế hợp thêm một số các điều kiện cụ thể nào đó, để back, next cho phù hợp thôi.

Inspect element, ta có html, cssClass như phía dưới:

date

Và giờ sẽ làm gì với chỗ này, ta có thể lấy thông tin tháng đang hiển thị trên trang để thực hiện so sánh với giá trị tháng ta muốn chọn. Nếu giá trị lấy ra này không bằng giá trị mong muốn thì ta sẽ thực hiện nhấn next cho đến khi đúng thì thôi 😀

Mình muốn chọn tháng đi là tháng 5 (May) – lưu ý trên web hiển thị như thế nào thì mình sử dụng giá trị với kiểu viết như thế nha, ở đây các tháng hiển thị theo tên tiếng anh thì mình sẽ dùng đúng tên tiếng anh của tháng 5 – May.

Mình sẽ thực hiện nhấn next cho đến khi nào giá trị tháng mong muốn lấy ra đúng thì thôi, nên là mình sẽ dùng vòng lặp while. Đơn giản dễ hiểu hơn đó là: vòng while cứ lặp đi lặp lại, và nếu như đoạn text lấy ra được vẫn khác May sau mỗi lần lặp thì lại click nút next 1 lần, sau đó lại getText rồi lại so sánh:

While (!driver.findElement(By.cssSelector 
         (".datepicker-days .datepicker-switch")).getText().contains("May"))
{
   btnNext.click();
}

Vòng lặp này sẽ dừng khi mà nó tìm được đúng tên tháng của mình ở trên kia – là May. 😀

Sau khi chọn được tháng rồi, thì chọn ngày trong tháng đó. Các bạn xem html dưới này nhé:

day

Ta có thứ, tuần nằm trong thẻ <tr>, và với ngày cụ thể sẽ nằm trong thẻ <td> tương ứng với <tr>. Các bạn có thể thực hiện inspect trực tiếp trên trình duyệt của các bạn để xem cho trực quan.

Công việc của chúng ta ở bước này chỉ là thực hiện click vào một ngày cụ thể nào đó, tuy nhiên vấn đề là không có id duy nhất cho từng ngày, mà chỉ có thông tin về class thôi. Muốn chọn được một ngày duy nhất nào đó, các bạn có thể sử dụng xpath tuyệt đối của nó, nhưng mình không khuyến khích cách này đâu! 😀

Ở đây thì mình sẽ thực hiện như sau:

1. Ta sẽ lấy ra danh sách các ngày của tháng này theo cssClass:

List<WebElement> dates = driver.findElements(By.cssSelector(".day"));
int count = dates.size();

2. Sau đó duyệt qua tất cả các ngày lấy được, so sánh với giá trị ngày mong muốn, nếu nó đúng là ngày cần lấy rồi thì thực hiện click vào ngày đó, như phía dưới này của mình là ngày 10 – các bạn cũng có thể sử dụng biến và cho nó ra ngoài, rồi thay bằng giá trị khác tùy ý:

for (int i = 0; i < count; i++){ 
    String text = driver.findElements(By.cssSelector(".day"))
        .get(i).getText();
    if (text.equalsIgnoreCase("10")){
         driver.findElements(By.cssSelector(".day")).get(i).click();
         break;
     }
}

Khi đã tìm được rồi thì không cần phải tìm tiếp nữa, nên sẽ dùng break để ra khỏi vòng lặp for luôn nhé!

Code đầy đủ thì bạn chỉ cần copy theo từng đoạn trên này rồi ghép lại, thêm thư viện là chạy được thôi ah. 😀

Vậy là chỉ với những bước đơn giản như trên bạn đã có thêm một cách để chọn ngày tháng từ calendar rồi, 😀 Hi vọng bài viết này hữu ích trong quá trình thực hành và sử dụng selenium cho tất cả các bạn! hehe

Tuần mới nhiều niềm vui nhé!

Bài viết gốc được đăng tải tại vananhtooo.wordpress.com

Có thể bạn quan tâm:

Xem thêm Việc làm Developer hấp dẫn trên TopDev