3

Here is an example of some C# WebDriver code I'm using to model a registration page:

public class RegistrationPage : BasePage
{
    private IWebDriver driver;
    private String URL = "http://mydomain.com/registration.aspx";
    // private String pageTitle = "Registration";

    public RegistrationPage(IWebDriver driver) : base(driver)
    {
        this.driver = driver;

        /*
        // if we are not on the Registration page
        if (!(driver.Title.ToString().Equals(pageTitle)))
        {
            throw new Exception(); // Need a more relevant exception
        }*/
    }

    override public String URLproperty
    {
        get { return URL; }
        set { URL = value; }
    }

// CODE OMITTED ...
}

Here is a method from my BasePage, which RegistrationPage uses:

    // Open the URL specified in the implementation of the class
    public virtual void Open()
    {
        driver.Navigate().GoToUrl(this.URLproperty);
    }

And finally here is an example of my test code:

[Test]
    public void SubmitRegistrationWithBlankUserDetails()
    {
        RegistrationPage regPage = new RegistrationPage(driver);
        regPage.Open();
        regPage.ClickRegisterButton();
        Assert.IsTrue(regPage.SearchForText("You must enter a first name"));
    }

The issue I'm having is implementing the title "sanity check" in the constructor (currently commented out) for RegistrationPage. I've seen this used on the WebDriver wiki (here, code in Java I think: http://code.google.com/p/selenium/wiki/PageObjects), but I'm unsure how to go about it.

I see two possible scenarios when running my tests:

  1. My test's [SetUp] points the driver to mydomain.com. A link clicked by WebDriver (for example a link to my Registration page, above) passes the driver to the constructor of whatever page I am visiting. Job done, title sanity check can work.
  2. Let's say instead of clicking links to get to a certain page I want to start my test at the Registration page. I don't have a neat way of visiting that page without navgiating from the domain specified in [Setup]. My [SetUp] doesn't help (unless I navigate manually to the page) and creating a new PageObject of the Registration page doesn't take me anywhere unless I call the Open() method.

Should I simply create a new test plan for the second scenario, one where [Setup] points me to mydomain.com/registration.aspx? Am I misunderstanding something fundamental here?

1 Answer 1

3

I don't think that you should be defining the URL to the page inside the pageObject. The methods in your page object should actions/ journeys that your pageObjects can take.

For example a login pageObject may have 3 methods in it:

Login(String username, String password) {
// fill in login form
// Submit login form
return new landingPage(driver);
}


LoginUnsuccessfully(String username, String password) {
// fill in login form
// submit login form
return new loginPage(driver, lookForLoginFailMessage);
}

ForgotPassword() {
// click forgot password
return new ForgotPasswordPage();
}

At the start of your page your test should use the driver.get(); (or C# eqivalent) method to navigate to the correct URL, then use the methods in your pageObjects to navigate around your application.

TestLogin() {
driver.get(app.com/login);
Login page login = new LoginPage(driver);
LandingPage landingPage = login.login("joebloggs", "password1");

}

The 'basePage' class that you have should contain 'journeys' that are common to many pages like a navigation menu.

A different 'journey' through the app should be written in another test. But will be able to use the same page objects.


Page Object organisation

PageObjects

  • one for each page in the website / application
  • Contain all the logic about interacting the page
    • how to fill in a form etc
  • All the public methods should be a function that the page can perform

Tests

  • Should only call methods on the page object
  • Each test is a journey through a part of the app

This structure allows for logic of the what you are testing to be separate from the WebDriver interactions with the page

7
  • 1
    You're using 'driver.get(app.com/login)' in your test code. Doesn't this mean you're combining the logic and WebDriver interactions? Jul 15, 2013 at 9:07
  • That is just the entry point to the app. I am pointing to this url to find the app, and this is where the tests will start from. I am not interacting with the application in anyway, only telling the browser where the app is.
    – Jon Duffy
    Jul 15, 2013 at 9:18
  • So in theory I could declare 'driver.get(app.com/where/I/want/to/go)' for any page, providing my next line passes the driver into the constructor of my PageObject? I'm sure I read somewhere that the tests should not expose the driver object ([Set Up] omitted!)... Jul 15, 2013 at 9:27
  • Would this be so that you could access any page directly? You could yes i'm just not sure why you would want to. The only url this directly put in the the login page at first so the browser can get the the app. After that i just use the page objects to get around the app. I wanted to start the tests at a different point, say a sign up page. I would make another test, called signupTest and the first line might be (driver.get(app.com/signup));
    – Jon Duffy
    Jul 15, 2013 at 9:42
  • 3
    I agree with most of this answer, but I often define a url and a method to navigate directly to it within the page object. As Lord Kinboat pointed out, this allows you to avoid direct references to the webdriver in the test code. Jon is right that most of the time you would not be directly navigating to pages anyways, but when you do it is perfectly acceptable (and in my opinion better) to do so with a function in the page object itself.
    – Sam Woods
    Jul 17, 2013 at 1:42

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.