I am using Selenium to do some of my automation work. I am using Page Object Model(POM) based approach to define my WebElement property.
@FindBy(id = "username")
private WebElement usernameText;
@FindBy(css = "password")
private WebElement passwordText;
I do not want the annotation parameters(id=username and css=password) to be specified in the class directly.
Is it possible to move these to a bean properties file in Spring, so that I can map these annotations to a bean object.
For example, I can define a bean object to pass the id and css values, which should be auto-wired to this object in my Java class.
I don't actually see how it may be useful for you making WebElement
instance ApplicationContext
aware as WebElement
has no Spring beans dependencies. Despite it lets have a look what we will have to do to achieve the goal:
WebElement
is created by Selenium, BeanDefinition
with prototype
scope for this instance should be created as well and should be registered with a unique name in BeanDefinitionRegistry
BeanDefinition
is created, corresponding WebElement
instance should be created lazily inside ApplicationContext
as this WebElement
may be absent in DOM in the moment of its creation. Additionally on this stage we have to provide locator somehow WebElement
s in a single Page Object, you will not be able to inject WebElement
instance by type. Thus you will have to use @Qualifier
or @Resource
annotations on fields + @Lazy
annotation for lazy bean initialization. It is at least 2 annotations on each WebElement
field Do you see how complicated it is?
From my perspective you do not need to put WebElement
into ApplicationContext
. Some things that may be useful:
BeanPostProcessor
for your Page Objects and call PageFactory.initElements(..)
from there. And that's it @FindBy
annotations and use Page Object pattern only. You can store your locators as By
objects in enum
. It is handy to store such enum
as nested class of particular Page Object or as separate class if you wish so. You may retrieve these By
objects using WebElementFactory
. Example below:
public interface Labeled {
String label();
}
public interface ByAware {
By locator();
}
public interface WebElementDescriptor extends ByAware, Labeled {
}
@Component("pageObject")
public class PageObject {
@Autowired
private WebElementFactory factory;
public PageObject login(String name, String password) {
factory.getWebElement(Element.USERNAME_FIELD).sendKeys(name);
factory.getWebElement(Element.PASSWORD_FIELD).sendKeys(password);
return this;
}
enum Element implements WebElementDescriptor {
USERNAME_FIELD(By.id("username"), "User name input field"),
PASSWORD_FIELD(By.cssSelector("password"), "Password input field");
private By by;
private String label;
Element(By by, String label) {
this.by = by;
this.label = label;
}
@Override
public String label() {
return label;
}
@Override
public By locator() {
return by;
}
}
}
@Component("webElementFactory")
public class WebElementFactory {
@Autowired
private WebDriver driver;
public WebElement getWebElement(WebElementDescriptor descriptor) {
System.out.println("Processing " + descriptor.label());
return driver.findElementBy(descriptor.locator());
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.