1

I am building a testing framework for a website using Page Object Model with Selenium

I am thinking that in general if I have two pages with the exact user controls and functions but different URLs I should create one father page class that has two classes inheriting from it. But what if I have the same two pages with different locators for controls? what do you think? do you think that creating a totally separate class for every page will be a good practice? or is there a way to let the children classes override locators? knowing that I am using PageFactory.

Here is an example:

public class Header 
    {
    [FindsBy(How = How.ClassName, Using = "logout_button")]
    public IWebElement BtnLogout { get; set; }
    public Header()
     {
      PageFactory.InitElements(Browser.Driver, this);
     }

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

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

   public Header()
    {
     PageFactory.InitElements(Browser.Driver, this);
    }

   public void Logout()
   {
    this.BtnLogout.Click();
   }
}
4
  • correct you about what? Dec 27, 2016 at 7:29
  • Why same page has different locators? What is the thing this locator depend on?
    – dzieciou
    Dec 27, 2016 at 12:05
  • no, I am assuming that the website has pages with the same content, it is not the same page, different pages with the same content Dec 27, 2016 at 12:07
  • So it looks like they provide similar functionality, e.g. function to logout, but implemented differently. Looks like a good place for interfaces. See my answer.
    – dzieciou
    Dec 27, 2016 at 12:09

2 Answers 2

1

I don't know about C# but in Java annotations are static and cannot be changed at runtime. So this excludes using PageFactory.

However, you could simply use dynamic locators, i.e., old driver.findElement(locator) where locator is provided somehow dynamically. This doesn't seem very clear implementation to me. Neither I can see any benefit from that.

More clear solution for me would be to involve interface, e.g.,

public interface Header {
   void Logout();
}

public class Header1 implements Header { 

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

    public Header1() {
      PageFactory.InitElements(Browser.Driver, this);
    }

   @Override
   public void Logout() {
    this.BtnLogout.Click();
   }
}

public class Header2 implements Header { 

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

    public Header2() {
      PageFactory.InitElements(Browser.Driver, this);
    }

   @Override
   public void Logout() {
    this.BtnLogout.Click();
   }
}

And can be used:

Header oneHeader = new Header1();
Header anotherHeader = new Header2();
...
oneHeader.Logout();
...
anotherHeader.Logout();
9
  • so you are suggesting that I should get rid off the FindsBy annotations ? and not use PageFactory? Dec 27, 2016 at 12:15
  • @YahyaHHussein Yes if you see a benefit of using interfaces. It obviously depends on your use case.
    – dzieciou
    Dec 27, 2016 at 12:16
  • yes, you are right, it depends on the system I am testing, but is getting rid off Pagefactory is a good practice? it is a cheap price to pay to buy more organised architecture? I am thinking about this trade, what do you think? Dec 27, 2016 at 12:19
  • @YahyaHHussein I re-thought and think that PageFactory with annotations still can be used. See my update to the answer.
    – dzieciou
    Dec 27, 2016 at 12:27
  • 1
    I am new in the company, so I am working on it, thanks :) Dec 27, 2016 at 12:53
1

One more suggestion which doesn't need separate objects. Might be useful if your locators are different because of, let's say, different user roles, and you want to stick with PageFactory.

Use

[FindsBy(How = How.Xpath, 
       Using = "@class='logout' or @class='logoutbutton']")] 
public IWebElement BtnLogout { get; set; }

Duplicating objects just because you need to change one selector is bad. Unless there is a very good reason for it. You can abstract Header, but it wouldn't change the fact that there is a code duplication.

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.