Yahya Hussein
Yahya Hussein

Reputation: 9111

Page object Model discussion

I am building a test framework for my Website using Selenium, I actually want your ideas of good practices when using Page Object Model: let us say that I have a Welcome page that contains a header where logout button exists, and this header can be seen in most of my pages I am thinking that it is better to write a separate class for the header something like this:

public class Header
    {
        [FindsBy(How = How.Name, Using = "user_profile")]
        public IWebElement BtnUserProfile{ get; set; }

        [FindsBy(How = How.ClassName, Using = "logout_button")]
        public IWebElement BtnLogout { get; set; }

        public void Logout()
         {
            BtnLogout.Click();
         }
    }

 public class LoginPage
    {
        [FindsBy(How = How.Name, Using = "username")]
        public IWebElement TxtbxUserName { get; set; }

        [FindsBy(How = How.Name, Using = "password")]
        public IWebElement TxtbxPassword { get; set; }

        [FindsBy(How = How.ClassName, Using = "button")]
        public IWebElement BtnSignIn { get; set; }


        public string GoTO()
       {
           Driver.Navigate().GoToUrl(LoginURL);
       }
        public void Login(string username, string password)
         {
            TxtbxUserName.SendKeys(username);
            TxtbxPassword.SendKeys(password);
            BtnSignIn.Click();
         }
        public bool IsAt()
         {
             return Driver.Url == LoginURL;
         }
    }

public class WelcomePage

{
    [FindsBy(How = How.Name, Using = "welcome-message")]
    public IWebElement LblWelcomeMessage { get; set; }
}

my question is do you think it is better to include the Header as a property in the Welcome Page or should they be separated?

let us take the code for Logout test method for example:

case 1:

public void LogoutTest() {
    LoginPage loginpage = new LoginPage();
    loginpage.GoTo();
    loginpage.login("user", "pass");
    Header header = new Header();
    header.Logout();
    Assert.IsTrue(loginpage.IsAt());
}

Case 2:

public void LogoutTest() {
    LoginPage loginpage = new LoginPage();
    loginpage.GoTo();
    loginpage.login("user", "pass");
    WelcomePage wlcmPage = new WelcomePage();
    WelcomePage.Logout();
    Assert.IsTrue(loginpage.IsAt());
}

a second question will be, how do you think about writing a static class for the Driver instead of a separate Driver for every page.

a third one will be how do you recommend to use waits? I am thinking about adding this method to my driver static class

public static void Wait(int seconds)
{
 Driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(seconds));
}

any ideas will be highly appreciated

Upvotes: 1

Views: 528

Answers (2)

Sakshi Singla
Sakshi Singla

Reputation: 2502

This is the concept I follow when I work on framework:

  • Create separate files for header and footer(as they are common for all the pages and it does not make sense to make them a part of a single page)
  • Keep common elements(Like Search/Back/Next etc) in separate file(The idea is to remove any kind of duplication and keeping the segregation logical)
  • For Driver, its a good idea to create a separate Driver class and keep Driver as static so that it can be accessed across all pages! (I have all my webpages extend DriverClass)
  • The functions used in PageObjects are broken down into smallest possible chunk keeping in mind the frequency and the way in which they will be called(The way you have done for login- although login can be broken down into enterUsername and enterPassword functions but still keeping it as Login function is more logical because in majority of the cases, the Login function would be called rather than separate calls to enterUsername and enterPassword functions)
  • Using PageObjects itself segregates Test script from the elementLocators
  • Have utility functions in separate utils folder(like DateUtil, excelUtils etc)
  • Have configurations in separate conf folder(like setting the environment on which the tests need to be run, configuring the output and input folders)
  • Incorporate screenCapture on failure
  • Have a static wait variable in the DriverClass with some implicit wait time as you have done
  • Always try to have conditional waits rather than static waits like: wait.until(ExpectedConditions). This ensures that the wait is not slowing down the execution unnecessarily.

Hope that helps!

Upvotes: 3

Arpan Buch
Arpan Buch

Reputation: 1400

  • As suggested by Sakshi Singla , The header and Footer could be
    separat Page Class.
  • Driver Class should be defined separately and get driver Method has to be made STATIC. The reason is , if you create different instance for driver , The tests will fail as when the Flow goes from 1 Page Class to 2nd Page Class , it will open a new instance each time.
  • Make the Driver method that returns WebDriver instance , make this method Static.
  • In the Page Class , You can choose to Call this Static driver method inside the Page Class's Constructor and assign it to the driver variable of the Page Class.

The Below code is just a representation Code and you may have to add few more lines eg Page Factory etc.

public class driverConfig{

Static WebDriver driver;

public Static WebDriver getDriver{

driver = new WebDriver();
//Navigate to the URL here
return driver;
   }
}

public Class PageClass{

public WebDriver driver;

public PageClass(){
driver = driverConfig.getDriver();
   }
}

Upvotes: 2

Related Questions