Search code examples
c#seleniumselenium-webdriverselenium-chromedriverpage-factory

Setup BasePage for selenium pagefactory


I have set up the first two pages of my website, and both pages share a Utility Navigation bar at the top of the page. as you can see in the two pages, i have had to duplicate the code used to find and click on these elements. I have read up that you can move common elements to a base page and then have your other pages share the code from that base page.

My question is, how do I move the duplicate code to a new file but still be able to access all the elements from my other pages.

DashboardPage:

 public class DashboardPage
    {
        private IWebDriver driver;

        #region WebElement

        [FindsBy(How = How.Id, Using = "AgentPAS")]
        private IWebElement Policy;

        [FindsBy(How = How.Id, Using = "Billing")]
        private IWebElement Billing;

        [FindsBy(How = How.LinkText, Using = "Activity")]
        private IWebElement Activity;

        [FindsBy(How = How.LinkText, Using = "Premium")]
        private IWebElement Premium;

        [FindsBy(How = How.LinkText, Using = "Production Summary")]
        private IWebElement ProductionSummary;

        [FindsBy(How = How.LinkText, Using = "Quote to Bind")]
        private IWebElement QuoteToBind;

        #endregion

        public DashboardPage()
        {
            PageFactory.InitElements(ObjectRepository.Driver, this);
        }

        #region Actions

        public void PolicyButton()
        {
            Policy.Click();
        }

        public void BillingButton()
        {
            Billing.Click();
        }

        public void ActivityLink()
        {
            Activity.Click();
        }

        public void PremiumLink()
        {
            Premium.Click();
        }

        public void ProductionSummaryLink()
        {
            ProductionSummary.Click();
        }

        public void QuoteToBindLink()
        {
            QuoteToBind.Click();
        }

        #endregion

    }

ClientDetailsOnePage:

public class ClientDetailsOnePage
    {
        private IWebElement driver;

        #region WebElement

        [FindsBy(How = How.Id, Using = "AgentPAS")]
        private IWebElement Policy;

        [FindsBy(How = How.Id, Using = "Billing")]
        private IWebElement Billing;

        [FindsBy(How = How.XPath, Using = "//input[@fieldref='AccountInput.Title']")]
        private IWebElement Title;

        [FindsBy(How = How.XPath, Using = "//input[@fieldref='AccountInput.FirstName']")]
        private IWebElement FirstName;

        [FindsBy(How = How.XPath, Using = "//input[@fieldref='AccountInput.Name']")]
        private IWebElement LastName;

        [FindsBy(How = How.XPath, Using = "//input[@fieldref='AccountInput.DesignatedAuthority']")]
        private IWebElement DesignatedAuthority;

        [FindsBy(How = How.XPath, Using = "//span[@data-ref='displayEl']")]
        private IWebElement UKResident;

        [FindsBy(How = How.LinkText, Using = "Save & Exit")]
        private IWebElement SaveExit;

        [FindsBy(How = How.LinkText, Using = "Next")]
        private IWebElement Next;

        #endregion

        public ClientDetailsOnePage()
        {
            PageFactory.InitElements(ObjectRepository.Driver, this);
        }

        #region Actions

        public void PolicyButton()
        {
            Policy.Click();
        }

        public void BillingButton()
        {
            Billing.Click();
        }

        public void TitleDropDown(string text)
        {
            Title.SendKeys(text);
        }

        public void FirstNameTextBox(string text)
        {
            FirstName.SendKeys(text);
        }

        public void LastNameTextBox(string text)
        {
            LastName.SendKeys(text);
        }

        public void DesignatedAuthorityDropDown(string text)
        {
            DesignatedAuthority.SendKeys(text);
        }

        public void UKResidentCheckBox()
        {
            UKResident.Click();
        }

        public void SaveExitButton()
        {
            SaveExit.Click();
        }

        public void NextButton()
        {
            Next.Click();
        }

        #endregion
    }

Solution

  • Both pages have a navigation bar, so the navigation bar is part of the page. You can create a separate class for the navigation bar and re-use this on every page you like.

    This is called composition

    Quick example:

    public class NavigationBar
    {
        [FindsBy(How = How.LinkText, Using = "Next")]
        private IWebElement Next;
    
        [FindsBy(How = How.LinkText, Using = "Previous")]
        private IWebElement Previous;
    
        public NavigationBar(IWebDriver driver)
        {
            PageFactory.InitElements(driver, this)
        }
    }
    
    public class DashboardPage
    {
        public NavigationBar NavigationBar { get; set; }
    
        public DashboardPage(IWebDriver driver)
        {
            NavigationBar = new NavigationBar(driver);
        }
    }
    
    public class ClientDetailsOnePage
    {
        public NavigationBar NavigationBar { get; set; }
    
        public ClientDetailsOnePage(IWebDriver driver)
        {
            NavigationBar = new NavigationBar(driver);
        }
    }