Search code examples
c#seleniumfindbypage-factory

How to define a @findBy annotation in a subclass, using PageFactory?


I work in an automation project with Selenium and C #. I use the Page Object pattern to define each of the pages (with their locators), and then define the tests separately in a Test class. I have a Page class that is the base class of the pages, where I call: PageFactory.InitElements (webDriver, this);

and define the common methods for all the pages. Then each page inherits from Page, and the corresponding elements are defined using @FindBy annotations:

[FindsBy (How = How.Id, Using = "UserName")]
public IWebElement UserName {get; set; }

[FindsBy(How = How.Id, Using = "UserPass")]
public IWebElement Password { get; set; }

[FindsBy(How = How.Id, Using = "login-btn")]
public IWebElement SubmitButton { get; set; }

A new login page was added, and I have to keep both (new and old login) and be able to run the tests with both pages. Both pages have the same elements (not the locators), and they must be able to respond to the same methods such as: login (user, pass) The idea would be to define a hierarchy of classes: BaseLogin (inherited from Page), LoginPage and NewLoginPage (both inherit from BaseLogin), where in BaseLogin you can define the elements (IWebElement) and the common methods. Then in each subclass associate / relate each element with the corresponding locator.

This is to avoid repeating the code that allows me to interact with the page, on each of the pages.

public class BaseLoginPage : Page
{
 protected IWebElement UserName { get; set; }
 protected IWebElement Password { get; set; }
 protected IWebElement SubmitButton { get; set; }
}
    // BaseLogin just define the IWebElement without assign a specific locator.

How can I associate/relate the element "IWebElement UserName" with its corresponding locator?

[FindsBy(How = How.Id, Using = "UserName")]   --> in LoginPage Class
[FindsBy(How = How.Id, Using = "user")]       --> in NewLoginPage Class

Solution

  • How about using an or operator? If the login is the same for both, this would just send the value to whichever locator is on the page.

     [FindsBy(How = How.Id, Using = "user | UserName")]
    

    or XPath

     [FindsBy(How = How.XPath, Using = "//input[@id='user'] | //input[@id='UserName']")]