[Selenium Java] Bài 18: Sử dụng Page Factory trong POM

Page Factory là phần mở rộng của Page Object Model, nó giúp khởi tạo các đối tượng WebElement tối ưu hơn và giảm thiểu code ngắn gọn hơn.

Giới thiệu Page Factory

Page Factory là phần mở rộng của Page Object Model, nó giúp khởi tạo các đối tượng WebElement tối ưu hơn và giảm thiểu code ngắn gọn hơn.

Nó được sử dụng để khởi tạo các đối tượng Trang hoặc để khởi tạo chính đối tượng Trang. Nó cũng được sử dụng để khởi tạo các hành động xử lý mà không cần sử dụng cú pháp driver.findElement / driver.findElements.

Có hai bước đơn giản để sử dụng Page Factory trong các dự án Selenium:

1. Sử dụng chú thích @FindBy - Không giống như cách tiếp cận thông thường để khởi tạo các phần tử trang web bằng FindElement hoặc FindElements , Page Factory sử dụng chú thích @FindByCác chú thích này được sử dụng trong Page Factory mang tính mô tả. Hơn nữa, chúng giúp cải thiện khả năng đọc mã mà chúng ta sẽ thảo luận trong phần tiếp theo. Nó cung cấp cú pháp sau để xác định vị trí các phần tử web:


2 . Khởi tạo các phần tử bằng initElements ()
- Đây là một phương thức tĩnh được sử dụng để khởi tạo các phần tử web mà chúng định vị bằng cách sử dụng @FindBy trên hoặc (các) chú thích khác, đặt nó vào chổ hàm xây dựng khởi tạo lớp trang.

PageFactory.initElements(WebDriver driver, java.lang.Class.pageObjectClass);
Java


Sử dụng Page Factory trong POM


Chúng ta thấy class SignInPage bài trước khi chưa dùng Page Factory:

public class SignInPage {

	private WebDriver driver;

	private By headerPageText = By.xpath("//a[normalize-space()='Forgot Username/Password?']");
	private By emailInput = By.id("EmailInputEmail");
	private By passwordInput = By.id("PasswordInputPassword");
	private By signinBtn = By.id("SignInButton");
	private By errorMsgText = By.id("signInError");

	private By pinInput = By.id("Pin");
	private By submitBtn = By.id("RequestPinForm_SubmitButton");
	private By backBtn = By.id("RequestPinForm_Back");
	private By resetPintBtn = By.id("RequestPinForm_ResetPin");

	// Khởi tạo class khi được gọi và truyền driver vào để các thành phần trong
	public SignInPage(WebDriver driver) {
		this.driver = driver;
	}

	// Sau khi thực hiện click Submit thì khởi tạo trang DashboardPage
	public void signin(String username, String password, String Pin) throws Exception {
		enterEmail(username);
		enterPassword(password);
		clickSignIn();
		Thread.sleep(1000);
		enterPin(Pin);
		clickSubmit();
	}

     public void enterEmail(String email) {
		WebElement emailTxtBox = driver.findElement(emailInput);
		if (emailTxtBox.isDisplayed())
			emailTxtBox.sendKeys(email);
	}

	public void enterPassword(String password) {
		WebElement passwordTxtBox = driver.findElement(passwordInput);
		if (passwordTxtBox.isDisplayed())
			passwordTxtBox.sendKeys(password);
	}

	public void clickSignIn() {
		WebElement signin = driver.findElement(signinBtn);
		if (signin.isDisplayed()) {
			signin.click();
		}
	}

	public void clickSubmit() {
		WebElement submit = driver.findElement(submitBtn);
		if (submit.isDisplayed()) {
			submit.click();
		}
	}

	public void enterPin(String PIN) {
		driver.findElement(pinInput).sendKeys(PIN);
	}

	public void clickBack() {
		driver.findElement(backBtn).click();
	}

	public void clickResetPin() {
		driver.findElement(resetPintBtn).click();
	}

}
Java


Khi chúng ta áp dụng dùng Page Factory thì nó sẽ như này:

public class SignInPageFactory {

	private WebDriver driver;

	@FindBy(xpath = "//a[normalize-space()='Forgot Username/Password?']")
	private WebElement headerPageText;

	@FindBy(id = "EmailInputEmail")
	private WebElement emailInput;

	@FindBy(id = "PasswordInputPassword")
	private WebElement passwordInput;

	@FindBy(id = "SignInButton")
	private WebElement signinBtn;

	@FindBy(id = "signInError")
	private WebElement errorMsgText;

	@FindBy(id = "Pin")
	private WebElement pinInput;
	@FindBy(id = "RequestPinForm_SubmitButton")
	private WebElement submitBtn;
	@FindBy(id = "RequestPinForm_Back")
	private WebElement backBtn;
	@FindBy(id = "RequestPinForm_ResetPin")
	private WebElement resetPintBtn;

	// Khởi tạo class khi được gọi và truyền driver vào để các thành phần trong
	// Và khởi tạo initElements
	public SignInPageFactory(WebDriver driver) {
		this.driver = driver;
		PageFactory.initElements(driver, this);
	}

	// Chúng ta viết hàm signin không cần dùng các hàm bổ trợ enter hay click nữa
	public void signin(String username, String password, String Pin) throws Exception {
		emailInput.sendKeys(username);
		passwordInput.sendKeys(password);
		signinBtn.click();
		Thread.sleep(1000);
		pinInput.sendKeys(Pin);
		submitBtn.click();
	}
}
Java

 

Vậy là xong. Gọn ràng hơn chứ hả.

Ta thấy cách khai báo một WebElement khá rõ ràng

@FindBy(id = "EmailInputEmail")
private WebElement emailInput;
Java

Nếu dùng xpath hay name hay classname thì chứ thay vào chổ "id" là xong.

Hàm khởi tạo (constructor) sẽ thay đổi thêm 1 dòng khởi tạo initElements vì bây giờ sẽ sử dụng thêm PageFactory.

public SignInPageFactory(WebDriver driver) {
	this.driver = driver;
	PageFactory.initElements(driver, this);
}
Java


Diễn giải thêm chổ Page Factory:


Vậy thì chính xác là Page Factory làm gì?

Sau khi khai báo WebElement và Locator, thì 2 cái này phải được liên kết với nhau. Có nghĩa là WebElement sẽ luôn luôn được tìm thấy sử dụng bởi Locator thông qua annotation @FindBy. Và thực hiện công việc trên, ta cần khởi tạo Element thông qua constructor:

PageFactory.initElements(driver, this);
Java

 

- Các WebElement sẽ KHÔNG được tìm thấy ngay khi khởi tạo. Khởi tạo chỉ để tạo ra LIÊN KẾT giữa WebElement và Locator. Khi nào WebElement đó được sử dụng thì chúng mới được tìm kiếm dựa trên các biến loại WebElement đã được khai báo ở trên.


-
Nếu WebElement đó được sử dụng nhiều lần thì nó tiếp tục tìm kiếm nhiều lần hay sao đây??

Chính xác là như vậy, nó sẽ được tìm kiếm mỗi lần sử dụng. Tuy nhiên, có 1 cách để chỉ tìm 1 lần rồi sử dụng lại, đó là sử dụng annotation @CacheLookup. Ví dụ:

@FindBy(id = "EmailInputEmail")
@CacheLookup
private WebElement emailInput;
Java

Ngoài ra, bạn có thể sử dụng @FindAll với nhiều chú thích @FindBy để tìm kiếm các phần tử khớp với bất kỳ bộ định vị nào đã cho:

@FindAll({@FindBy(how=How.ID, using="username"),
	@FindBy(className="username-field")})
private WebElement user_name;
Java


Hoặc khi cần tìm danh sách các phần tử trên một trang (findElements) thì chúng ta dùng @FindBys như sau:

@FindBys(@FindBy(css="div[class='yt-lockup-tile yt-lockup-video']")))
private List<WebElement> videoElements;
Java

Và cách khác để viết đơn giản hơn nữa là:

@FindBy(how=How.CSS,using="div[class='yt-lockup-tile yt-lockup-video']")
private List<WebElement> videoElements;
Java


==> Vậy là xong rồi.

Phần DashboardPage viết tương tự thôi nào =))

  • 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

A PHP Error was encountered

Severity: Notice

Message: Undefined variable: new

Filename: post/post_detail.php

Line Number: 384

Backtrace:

File: /home/anhtest2/public_html/application/views/frontend/post/post_detail.php
Line: 384
Function: _error_handler

File: /home/anhtest2/public_html/application/views/frontend/layout/layout_view.php
Line: 370
Function: view

File: /home/anhtest2/public_html/application/core/MY_Controller.php
Line: 34
Function: view

File: /home/anhtest2/public_html/application/controllers/frontend/Post.php
Line: 59
Function: render

File: /home/anhtest2/public_html/index.php
Line: 315
Function: require_once

A PHP Error was encountered

Severity: Notice

Message: Trying to get property 'slug' of non-object

Filename: post/post_detail.php

Line Number: 384

Backtrace:

File: /home/anhtest2/public_html/application/views/frontend/post/post_detail.php
Line: 384
Function: _error_handler

File: /home/anhtest2/public_html/application/views/frontend/layout/layout_view.php
Line: 370
Function: view

File: /home/anhtest2/public_html/application/core/MY_Controller.php
Line: 34
Function: view

File: /home/anhtest2/public_html/application/controllers/frontend/Post.php
Line: 59
Function: render

File: /home/anhtest2/public_html/index.php
Line: 315
Function: require_once

https://anhtester.com//blog/selenium-java/" data-width="100%" data-numposts="4">


2017年
12月
Clear Today
 :  : 
Clear Okey
00 01 02 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23
00 05 10 15 20 25 30 35 40 45 50 55
00 05 10 15 20 25 30 35 40 45 50 55