Sử dụng Loadable Component trong Page Object

I. Vì sao lại cần Loadable Component?

Như trong bài về Page Object mình đã có nói là ta mô hình hóa mỗi page hoặc mỗi phần của 1 page thành 1 object riêng biệt để quản lý, tránh duplicate code. Page Object rất tốt nhưng vẫn còn thiếu 1 chút, đó là cách đồng bộ ready state trước khi làm việc với 1 page hoặc component. Hơi khó hiểu nhỉ?

Hãy nghĩ đến trường hợp này:

  1. Bạn thường xuyên phải sử dụng WebdriverWait để làm việc với 1 số WebElements, liên tục từ method này qua mehod khác.
  2. Bạn open 1 page mới nhưng không biết khi nào page mới render xong để bạn có thể sẵn sàng thực hiện action lên nó.

–> Cả 2 trường hợp đều thiếu 1 thứ đó là “1 cơ chế cho ta biết là khi nào page / component đã ở trạng thái sẵn sàng (ready state) để có thể thực hiện actions

Và đó chính là cái Loadable Component hướng đến, nó cung cấp cho ta 1 cách làm việc chung, phần việc của chúng ta là điền cái điều kiện (condition) để cho biết thế nào là ready state.

II. Cách sử dụng Loadable Component như thế nào

Sơ qua về LoadableComponent:

  • LoadableComponent nằm trong package org.openqa.selenium.support.ui. Đây là package có chứa nhiều Classes rất là hữu dụng cho quá trình làm selenium. (Mình sẽ viết thêm các bài về package này sau)
  • LoadableComponent là 1 abstract class, trong nó có chứa 3 methods:
    • load();
    • isLoaded() throws Error
    • public get()

Dưới đây là 1 page object có sử dụng LoadableComponent:

Dưới đây là 1 số lưu ý khi implement:

  • Class Page Object phải extend từ class LoadableComponent<T extends LoadableComponent<T>>. Trong đó T chính là tên class Page Object.
  • Phải Override lại 2 methods: load() và isLoaded().
    • Load(): dùng để navigate to page. Nếu áp dụng cho component thì có thể không cần implement gì cả
    • isLoaded(): dùng để xác định xem đã ở đúng page hoặc component cần tương tác đã đạt trạng thái ready state hay chưa.

ở trong ví dụ này, mình để điều kiện xác định trang web có được load hay chưa là “URL có chứa keyword practice

Test file sẽ trông như thế này:

Điều lưu ý duy nhất là sử dụng:

  • Nhớ call method get() trong phần Test vì nó sẽ gọi đến 2 method load() và isLoaded()

Bạn cũng hoàn toàn có thể viết thế này:

III. Cơ chế của Loadable Component

Khi get() method được gọi thì nó sẽ:

  • Gọi vào method isLoaded(). Mặc dù method isLoaded() giống như trả về Boolean nhưng nó sẽ thực hiện 1 series các Assertions. Bạn có thể add 1 hoặc nhiều Assertions ở trong isLoaded(). Việc thêm assert sẽ giúp có thông tin chuẩn xác hơn khi debug tests.
  • Nếu isLoaded() pass –> step (4) —> step (5) –> return về Test method.
  • Nếu isLoaded() failed –> sẽ văng ra Error –> nhảy vào Catch block. Ở Catch block sẽ gọi đến method load() step 3. Ở Step 3, sẽ load lại page 1 lần nữa.
  • Hết Step 3 –> chuyển sang step 4 –> step 4 mà fail thì Test fail với dòng Assertion mình đã viết ở trong isLoaded().
  • Nếu step 4 pass –> step 5 –> return về Test method –> Kết thúc công việc của LoadableComponent.

IV. Tổng kết

Mình nghĩ là LoadableComponent đã cung cấp 1 phương thức làm việc khá hiệu quả mà lâu nay mình không để ý đến. Hi vọng có ích cho bạn khi áp dụng Page Object vào làm Selenium.

0 0 votes
Article Rating
Subscribe
Notify of
guest
5 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Tintin
Tintin
2 years ago

Anh Giang ơi, cho em hỏi chút về cái .get()
– như bài a viết thì:
PageA comp_1 = new PageA().get();
comp_1.doSomething();
– Nhưng framework em thì tất cả method là static nên ko khởi tạo object như vậy mà gọi luôn:
PageA.doSomething();
vậy có cách nào xài cái get(); này trong framework của em ko a?

Tintin
Tintin
2 years ago
Reply to  Giang Nguyen

Dạ thanks anh, em mới vào cty được gần 2 tuần thì phải tiếp nhận project auto đã viết sẵn này. em quan sát thì thấy:
– phần method thì gần như 100% là static
– phần biến của class thì ko có nhiều, nếu có thì nó ở dạng non-static (có thể em chưa xem kĩ hết)

Vậy liệu method static, còn biến của class giả sử ko dùng luôn thì liệu có ổn không a? em đang bị force viết khá nhiều test cases để kịp build, nhưng em cũng suy nghĩ theo hướng OOP như anh nói, vì giờ viết cho kịp build, mốt refactor lại cũng mệt mỏi