Page Object Model的主要优点是,如果UI或任何HTML对象的任何页面均发生更改,则该测试不需要任何修复。
当我们要处理100多个测试并且有多个stepDefiniions文件。为了更好地管理代码并提高可重用性,此模式将不同页面或单个页面中的划分为子页面。
页面对象模式技术提供了一种用于处理多个网页的解决方案,并防止了不必要的代码重复,并为代码维护提供了一个简单的解决方案。
页面对象设计模式分为两种:
- Page Object Pattern
- Selenium PageFactory
1. Page Object Model
基于每个页面创建一个类, 该类由页面上的WebElement和作用于元素的相应方法组成。
HomePage.java
package pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class HomePage {
WebDriver driver;
//Constructor that will be automatically called as soon as the object of the class is created
public HomePage(WebDriver driver) {
this.driver=driver;
}
//Locator for login button
By LoginBtn = By.id("login");
//Method to click login button
public void clickLogin() {
driver.findElement(LoginBtn).click();
}
}
LoginPage.java
package pages;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
public class LoginPage {
WebDriver driver;
//Constructor that will be automatically called as soon as the object of the class is created
public LoginPage(WebDriver driver) {
this.driver = driver;
}
//Locator for username field
By uName = By.id("userName");
//Locator for password field
By pswd = By.id("password");
//Locator for login button
By loginBtn = By.id("login");
//Method to enter username
public void enterUsername(String user) {
driver.findElement(uName).sendKeys(user);
}
//Method to enter password
public void enterPassword(String pass) {
driver.findElement(pswd).sendKeys(pass);
}
//Method to click on Login button
public void clickLogin() {
driver.findElement(loginBtn).click();
}
}
Test Classes
package testCases;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import pages.Dashboard;
import pages.HomePage;
import pages.LoginPage;
public class Login_TC1 {
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "---Exact path to chromedriver.exe---");
WebDriver driver = new ChromeDriver();
driver.get("https://www.demoqa.com/books");
//Creating object of home page
HomePage home = new HomePage(driver);
//Creating object of Login page
LoginPage login = new LoginPage(driver);
//Click on Login button
home.clickLogin();
//Enter username & password
login.enterUsername("---Your Username---");
login.enterPassword("---Your Password---");
//Click on login button
login.clickLogin();
Thread.sleep(3000);
//Close browser instance
driver.quit();
}
}
2. Selenium PageFactory
Page Factory是Selenium WebDriver提供的用于实现Page Object Model的类。可以初始化页面对象或直接实例化它们。页面对象模型为网站的不同页面创建单独的java类
1. @FindBy
- @FindBy 注解, 用于元素定位,代替FindElement, FindElements
// 两种地位方式:
//1.
@FindBy(id="userName")
WebElement username;
//2. how 中选中定位方式id,name,XPath等
//@FindBy(how = How.CSS, using = "userName")
@FindBy(how = How.ID, using = "userName")
WebElement username;
<div class = "custom-control-check-Box">
<input type="checkBox" id="game-chk-Box" class="custom-control-input" value="1"/>
</div>
@FindBys({
@FindBy(class="custom-control-check-Box"),
@FindBy(id="game-chk-Box")
})
WebElement chkBox;
<button id = "submit" type = "submit" name= "sbmtBtn" class =" btn btn-primary">Submit</button>
即使只有一个条件与@FindAll符合一个或多个条件,以上注释仍将定位“提交”按钮。
@FindAll({
@FindBy(id="btn", //doesn't match
@FindBy(name="sbmtBtn"), //Matches
@FindBy(class="btn-primary") //doesn't match
})
WebElement submitButton;
2. @CacheLookUp
当您多次引用同一Web元素时,@ CacheLookUp批注非常有用。
考虑一个每个测试用例都需要登录操作的应用程序。使@CacheLookUp,我们可以在第一次读取后立即将Web元素存储在缓存中。无需在网页上查找元素,而直接从内存中引用它。
@CacheLookUp
@FindBys({
@FindBy(class="custom-control-check-Box"),
@FindBy(id="game-chk-Box")
})
WebElement chkBox;
3. initElements()
// PageFactory.initElements(WebDriver, PageObject.Class);
PageFactory.initElements(WebDriver driver, java.lang.class.pageObjectClass);
AjaxElementLocatorFactory的惰性加载概念。用程序使用Ajax元素时可以使用它。是一种隐式等待
PageFactory.initElements(new AjaxElementLocatorFactory(driver, 20), this);
项目中使用
package pages;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindAll;
import org.openqa.selenium.support.FindBy;
public class Login {
final WebDriver driver;
//Constructor, as every page needs a Webdriver to find elements
public Login(WebDriver driver){
this.driver=driver;
}
//Locating the username text Box
@FindAll({
@FindBy(id="wrapper"),
@FindBy(id="userName")
})
WebElement username;
//Locating the password text Box
@FindBy(id="password")
WebElement pswd;
//Locating Login Button
@FindBy(id="login")
WebElement loginBtn;
//Method that performs login action using the web elements
public void LogIn_Action(String uName, String pwd){
username.sendKeys(uName);
pswd.sendKeys(pwd);
loginBtn.click();
}
}
package testCases;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.support.PageFactory;
import pages.Login;
import pages.Profile;
public class Login_TC {
static WebDriver driver;
public static void main(String[] args) {
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://demoqa.com/login");
//Instantiating Login & Profile page using initElements()
Login loginPg = PageFactory.initElements(driver, Login.class);
//Using the methods created in pages class to perform actions
loginPg.LogIn_Action("---your username---", "---your password---");
driver.quit();
}
}
优化:每个页面都要进行初始化,声明对象。减少代码冗长。将初始化放入对应页面的构造方法中。
package pageObjects;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
public class HomePage {
WebDriver driver;
public HomePage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
public void perform_Search(String search) {
driver.navigate().to("https://shop.demoqa.com/?s=" + search + "&post_type=product");
}
public void navigateto_HomePage() {
driver.get("https://www.shop.demoqa.com");
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。