neo-technoker
neo-technoker

Reputation: 389

How to implement Page Object Model in C# Selenium?

Setup

I would like to implement the Page Object Model (POM) without the PageFactory

This is the code I have so far

POM

using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;

namespace Vasool.DrPay.Test
{
    class LoginPage
    {
        private readonly IWebDriver _driver;
        private const string PageUri = @"https://site.site/SignIn";

        [FindsBy(How = How.Name, Using = "Input.Username")]
        private IWebElement _username;

        [FindsBy(How = How.Name, Using = "Input.Password")]
        private IWebElement _password;

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

        [FindsBy(How = How.CssSelector, Using = ".btn.btn-primary")]
        private IWebElement _login;

        public LoginPage(IWebDriver driver)
        {
            _driver = driver;
        }

        public static LoginPage NavigateTo(IWebDriver driver)
        {
            driver.Navigate().GoToUrl(PageUri);

            return new LoginPage(driver);
        }



        public string Username { set { _username.SendKeys(value); } }
        public string Password { set { _password.SendKeys(value); } }

        public void Remember() {  _rememberLogin.Click(); }
        public void Login()
        {
            _login.Click(); 

       }


    }
}

Feature Step

using OpenQA.Selenium;
using TechTalk.SpecFlow;
using Xunit;

namespace Inc.Test
{
    [Binding]
    public class LoginSteps

    {
        private readonly IWebDriver _webDriver;
        private LoginPage _loginPage;

        public LoginSteps(ScenarioContext scenarioContext)
        {
            _webDriver = scenarioContext["WEB_DRIVER"] as IWebDriver;

        }

        [Given(@"I am on the Login Page")]
        public void GivenIAmOnTheLoginPage()
        {

            _loginPage = LoginPage.NavigateTo(_webDriver);

        }

        [Given(@"I have entered the ""(.*)"" as the username")]
        public void GivenIHaveEnteredTheAsTheUsername(string username)
        {
            _loginPage.Username = username;
        }

        [Given(@"I have entered the ""(.*)"" as the password")]
        public void GivenIHaveEnteredTheAsThePassword(string password)
        {
            _loginPage.Password = password;
        }

        [Then(@"I should be navigated to the Home Page")]
        public void ThenIShouldBeNavigatedToTheHomePage()
        {
           // ScenarioContext.Current.Pending();
        }
    }
}

When I try to run the tests under debugging, I get a null reference for _username

It might be that I am missing something very obvious as I am getting back to programming after a long time

Upvotes: 1

Views: 2147

Answers (1)

Greg Burghardt
Greg Burghardt

Reputation: 18783

You need to call PageFactory.InitElements(this, driver); in the constructor of LoginPage.

As you have noted in your comment, the PageFactory class is deprecated. Since C# supports properties and expression bodied members, the page factory has fallen out of favor. You end up with less code. For instance, the username property:

[FindsBy(How = How.Name, Using = "Input.Username")]
private IWebElement _username;

Would be rewritten as follows:

private IWebElement Username => driver.FindElement(By.Name("Input.Username"));

Upvotes: 1

Related Questions