我真的很喜欢硒2按照惯例如何促使您使用PageObjects作为POJO,然后简单地使用PageFactory实例化此类中的字段。
我发现的限制是,我们在许多不同的页面上重用了许多元素。最大的问题是,这些重用的组件在不同页面上显示时,其ID
/名称不相同;但是我们将为每个测试运行的测试是相同的。
例如,我们在许多地方收集日期。因此,此示例页面对象可能是(删除了“月,日”字段):
public class DatePageObject {
private WebDriver driver;
DatePageObject(WebDriver driver) {
this.driver = driver;
}
@FindBy( id = "someIdForThisInstance")
private WebElement year;
public void testYearNumeric() {
this.year.sendKeys('aa');
this.year.submit();
//Logic to determine Error message shows up
}
}
然后,我可以使用以下代码对此进行简单的测试:
public class Test {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
DatePageObject dpo = PageFactory.initElements(driver, DriverPageObject.class);
driver.get("Some URL");
dpo.testYearNumeric();
}
}
我真正想要做的是进行设置,使用Spring我可以将id / name / xpath等注入到应用程序中。
有没有办法我可以做到而又不会失去使用PageFactory的能力?
编辑1-在自定义定位器和工厂上添加理想的基本级别类。
public class PageElement {
private WebElement element;
private How how;
private String using;
PageElement(How how, String using) {
this.how = how;
this.using = using;
}
//Getters and Setters
}
public class PageWidget {
private List<PageElement> widgetElements;
}
public class Screen {
private List<PageWidget> fullPage;
private WebDriver driver;
public Screen(WebDriver driver) {
this.driver = driver;
for (PageWidget pw : fullPage) {
CustomPageFactory.initElements(driver, pw.class);
}
}
编辑2-只需注意,只要您正在运行Selenium 2.0.a5或更高版本,就可以为驱动程序提供隐式超时值。
因此,您可以将代码替换为:
private class CustomElementLocator implements ElementLocator {
private WebDriver driver;
private int timeOutInSeconds;
private final By by;
public CustomElementLocator(WebDriver driver, Field field,
int timeOutInSeconds) {
this.driver = driver;
this.timeOutInSeconds = timeOutInSeconds;
CustomAnnotations annotations = new CustomAnnotations(field);
this.by = annotations.buildBy();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); //Set this value in a more realistic place
}
public WebElement findElement() {
return driver.findElement(by);
}
}
您可以构建通用Web元素的Page对象(只是发明了这个名称:))-每个CWE都代表一个在不同页面上使用的“小部件”。在您的示例中,这将是某种“日期”小部件-
它包含年,月和日。基本上它将是一个页面对象。
PageFactory
要求在@FindBy
注释中使用字符串常量。
为了解决此限制,我们创建了自己ElementLocator
的。
您可以DateWidget
在测试中使用:
....
DateWidget widget = new DateWidget(driver, "yearId", "monthId", "dayId");
....
public void testYearNumeric() {
widget.setYear("aa");
widget.submit();
//Logic to determine Error message shows up
// ... and day
widget.setDay("bb");
widget.submit();
//Logic to determine Error message shows up
}
的DateWidget
类,它包含自定义定位器和注释解析器是:
package pagefactory.test;
import java.lang.reflect.Field;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.Annotations;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
public class DateWidget {
// These constants are used to identify that they should be changed to the actual IDs
private static final String YEAR_ID = "$YEAR_ID$";
private static final String MONTH_ID = "$MONTH_ID$";
private static final String DAY_ID = "$DAY_ID$";
// Elements whose ids will be replaced during run-time
/** Year element */
@FindBy(id = YEAR_ID)
private WebElement year;
/** Month element */
@FindBy(id = MONTH_ID)
private WebElement month;
/** day element */
@FindBy(id = DAY_ID)
private WebElement day;
// The ids of the elements
/** ID of the year element */
private String yearId;
/** ID of the month element */
private String monthId;
/** ID of the day element */
private String dayId;
public DateWidget(WebDriver driver, String yearId, String monthId,
String dayId) {
this.yearId = yearId;
this.monthId = monthId;
this.dayId = dayId;
PageFactory.initElements(new CustomLocatorFactory(driver, 15), this);
}
public String getYear() {
return year.getValue();
}
public void setYear(String year) {
setValue(this.year, year);
}
public String getMonth() {
return month.getValue();
}
public void setMonth(String month) {
setValue(this.month, month);
}
public String getDay() {
return day.getValue();
}
public void setDay(String day) {
setValue(this.day, day);
}
public void submit() {
year.submit();
}
private void setValue(WebElement field, String value) {
field.clear();
field.sendKeys(value);
}
private class CustomLocatorFactory implements ElementLocatorFactory {
private final int timeOutInSeconds;
private WebDriver driver;
public CustomLocatorFactory(WebDriver driver, int timeOutInSeconds) {
this.driver = driver;
this.timeOutInSeconds = timeOutInSeconds;
}
public ElementLocator createLocator(Field field) {
return new CustomElementLocator(driver, field, timeOutInSeconds);
}
}
private class CustomElementLocator implements ElementLocator {
private WebDriver driver;
private int timeOutInSeconds;
private final By by;
public CustomElementLocator(WebDriver driver, Field field,
int timeOutInSeconds) {
this.driver = driver;
this.timeOutInSeconds = timeOutInSeconds;
CustomAnnotations annotations = new CustomAnnotations(field);
this.by = annotations.buildBy();
}
@Override
public WebElement findElement() {
ExpectedCondition<Boolean> e = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
d.findElement(by);
return Boolean.TRUE;
}
};
Wait<WebDriver> w = new WebDriverWait(driver, timeOutInSeconds);
w.until(e);
return driver.findElement(by);
}
}
private class CustomAnnotations extends Annotations {
public CustomAnnotations(Field field) {
super(field);
}
@Override
protected By buildByFromShortFindBy(FindBy findBy) {
if (!"".equals(findBy.id())) {
String id = findBy.id();
if (id.contains(YEAR_ID)) {
id = id.replace(YEAR_ID, yearId);
return By.id(id);
} else if (id.contains(MONTH_ID)) {
id = id.replace(MONTH_ID, monthId);
return By.id(id);
} else if (id.contains(DAY_ID)) {
id = id.replace(DAY_ID, dayId);
return By.id(id);
}
}
return super.buildByFromShortFindBy(findBy);
}
}
}
我想将Nightwatch的页面对象系统用于我们应用程序中使用的UI组件。因为nightwatch有自己的读取/初始化它们的方式,所以我看不到正确扩展/重用它们的方法。 例如,我想要一个“日期字段”的DateInputPageObject。它将识别标签、输入、日期选择器等。 我会在任何带有日期输入字段的页面上使用它。 我还想扩展页面对象。例如,。将为所有模态元素定义选择器-覆盖、容器、关闭按钮等。
本章是一个针对页面对象设计模式的教程引导。 一个页面对象表示在你测试的WEB应用程序的用户界面上的区域。 使用页面对象模式的好处: 创建可复用的代码以便于在多个测试用例间共享 减少重复的代码量 如果用户界面变化,只需要修改一处 6.1. 测试用例 下面是一个在python.org网站搜索一个词并保证一些结果可以找到的测试用例。 import unittest from selenium impor
人们是如何做到这一点的? 谢谢
对登录页面使用页面对象模型和页面分解,在登录页面中获取对象。java和操作在LoginScript中。JAVA我有一个java。“Ele_usernamedit.clear();”行中的lang.NullPointerException请帮助检查代码。谢谢 这是我的登录页。爪哇: 这是我的登录cript.java:
在Selenium PageObjects中,我没有实例化任何web驱动程序实例,也没有如下所示进行编码 我试图在Selenium Page对象函数中实现以下代码。 有谁能建议我,在使用页面对象模型时,如何在上述代码中使用webdriver实例?
我有一个关于selenium WebDriver中页面对象的问题。我们的站点非常动态,有很多ajax和各种身份验证状态。如何定义每个页面对象,但让我们假设我已经弄清楚了,并定义了代表我们站点的几个页面对象。 你如何处理从一页到另一页的交叉?因此,我得到一个页面对象用于我的主页,一个用于我的帐户页面,一个用于我的结果页面。然后我需要编写一个遍历我所有页面的测试来模拟一个用户执行多个动作。