如何在 C# Selenium 中实现页面对象模型?

How to implement Page Object Model in C# Selenium?

设置

我想在没有 PageFactory 的情况下实现页面对象模型 (POM)

这是我目前的代码

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(); 

       }


    }
}

特征步骤

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();
        }
    }
}

当我尝试 运行 正在调试的测试时,我得到了 _username

的空引用

可能是我错过了一些非常明显的东西,因为我在很长一段时间后重新开始编程

需要在LoginPage的构造函数中调用PageFactory.InitElements(this, driver);

如您在评论中所述,PageFactory class 已弃用。由于 C# 支持属性和 expression bodied members,页面工厂已经失宠。你最终得到的代码更少。例如,用户名 属性:

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

改写如下:

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