2

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:

  1. How I can know what to to with these elements? Some of them need to be clicked, some need to send keys, some need to be click and then press ENTER, etc.
  2. Navigation - In my test code, I want to navigate between by pages (This is all about Page pattern). How can I know the connection between my page objects?
2
  • The problem I forsee is it will generally have the same downfalls as record & playback tools do. They will generate awful selectors & rubbish code which can be done much better by hand. Commented Feb 10, 2014 at 9:42
  • @Arran You can generate XPATH for each element by taking it tag name & all attributes of this element. Commented Feb 10, 2014 at 11:56

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for your answer. I have a question about 2. I have a lot of problem with this issue in my application. For example, when I click on one of my checkbox, It switch another element (//button) which lead to different pages. How I can know that click on this element is changed this buttons and lead to 2 different test (and logic..).
Also, chronological: If I need to press OK, before starting sendKeys(), how I can know it by the DOM and selenuim?
1st question: You could have a page object that contains all your button whatever they are visible or not. You will have to code a method 'isVisble' on the reausable page object for the button. You will have a test case where you test the visibility of the button depending on the checkbox is ticked or not, a test case to test the behviour of your page when the button is visible and a test case to test the behaviour of your page when the button is not visible.
You can't guess the behaviour of your page just by reading the DOM (using Selenium or whatever technique). It is something that you may (it is not always possible) shield in your page object but you will have to code it yourself. 2nd question: If you have lot of pair "buttonOk-textfield" for which you have to click before invoking sendKeys, you can make a reusable page object out of it and code a method 'setText' which will internaly click on the button, then do the sendkeys.
2

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:

  • Add new elements from the browser page
  • Edit and debug recorded web elements: Test and change locators
  • Generate Page Object class file

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:

  • The process of recording new pages with SWD Page Recorder and generating the PageObject code become much faster and more fun.
  • The smoke test suite fails fast when the PageObjects are not corresponding to the real pages.
  • In order to fix the page object, I need to re-record some of the elements manually with SWD Page Recorder or make the manual modifications. As I’ve said, it is not permitted to directly use the web elements outside the given PageObject; so that the fixes need to be applied only inside the broken pageObject. The other pages

References

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.