Reputation: 3596
I am trying to create some sort of code generation for Page Object in WebDriver.
I read about it, and watch the next lecture: http://www.youtube.com/watch?v=mSCFsUOgPpw
I also saw some tools which create a page object for each new page in my application, So I know how to identify and create WebElement which relevant for me (by ID or XPath), and create a new page object.
But I have 2 main problems:
Upvotes: 2
Views: 3571
Reputation: 291
I’ve been also inspired by this lecture, and after a time exploring of the topic, I would say: this approach of automatic page object generation is possible for some web applications: for instance, the default important controls on .NET/ASPX pages would have id: ctxWebPageName_Container1_Panel1_btnLogin.
You can easily parse the id and get all required information.
However, in general case, the automated page object generation is impossible or very hard and requires some artificial intelligence.
That is why I’ve built my own tool SWD Page Recorder for semi-automating this boring process of manual creating the page object class.
The tool allows to:
In order to show the full picture, I am working on another project, a simple framework with PageObjects:
SWD.Starter which introduce the following rules for PageObjects:
Each page can be self-tested:
There is a generic test for each PageObject inside the framework, which opens the Page and asks the PageObject to self-test its elements.
Those tests are implemented as a tiny smoke test suite. First of all, they test the application, but on the other hand, they also check the page object declaration inside the code is still corresponds to the real page.
Service oriented architecture
The web elements of the Page1 cannot be accessed outside the Page1 class. When the test code or another page wants to perform some actions on the Page1, they should call a method, declared inside Page1. All web elements inside Page1 are declared with private or protected modifiers.
By following those rules, I’ve really simplified my life:
References
Upvotes: 2
Reputation: 1288
Create a (reusable) page object per widget (widget= button, combobox, textfield, ...). The constructor of a widget accept a WebElement or a By object. Every page object should use the reusable page object. Here is the example of a simple login page.
public class MyLoginPage {
private TextField mUsername;
private TextField mPassword;
private Button mSignon;
...
// getter
public TextField getUsername() {
return mUsername;
}
}
With the use of some heuristics you should be able to choose the correct widget to be use. This should answer your first question.
For the second question. Either you implement specific method on your page object that return you another page object. Something like that:
public MyHomePage clickSignon() {
this.mSignon.click();
return new MyHomePage(...);
}
You can also implement the button as a generic class. The method click on the Button widget:
public <T extends Widget> T click() {
... // coe that makes the click
return new T(...);
}
The member declaration inside the login page:
private Button mSignon<MyHomePage>;
So you can write:
MyHomePage hp = loginPage.getSignon().click();
Either you implement a factory of page object. The factory is able to determine the current state of the screen and return you the page objct that match what you see. You can determine that by trying to find some specific element on the screen (i.e. The button for the login is only present on the login page).
Not at all a definitive answer, but I hope it already give you direction. Don't hesitate to post a question in the comment and I will update this answer.
Upvotes: 5