使用Selenium PageObjects,Locator对象不能为null

时间:2017-05-22 10:23:14

标签: c# selenium selenium-webdriver pageobjects

我确信这是一个简单的问题,但我无法找到导致此错误的原因,更不用说解决方案了。

我正在使用selenium页面对象,直到现在我已经为我的测试添加了一个新页面。

这是我的主要代码

class RunTest
{
   static IWebDriver driver;

   [Test]
   public void Login()
   {
      var options = new ChromeOptions();
      options.AddArguments("chrome.switches", "--disable-extensions --disable-extensions-file-access-check --disable-extensions-http-throttling --disable-infobars --enable-automation ");
      options.AddUserProfilePreference("credentials_enable_service", false);
      options.AddUserProfilePreference("profile.password_manager_enabled", false);
      driver = new ChromeDriver(options);

      driver.Url = ConfigurationManager.AppSettings["URL"];

      driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);

      var loginPage = new LoginPage(driver);
      loginPage.LoginToApplication("Test1");

      IWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
      var element = wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='content']/div/div/div/div/ul/li[4]/div[1]/div[2]/div/button[1]")));

      var setenv = new SetEnvironment(driver);
      setenv.SetEnvQA();
}

[Test]
public void AddBatchTest()
{
   var AddBatch = new Batch(driver);
   AddBatch.AddNewBatch("Test1");
}

[Test]
public void Test1()
{
   var NewCli = new AddNewClient(driver);
   NewCli.Addanewclient("Test1");
}

Login和Test1测试(以及其他测试)运行完美,但Batch测试会随

而失败
  

System.ArgumentException:定位器对象的SearchContext不能为null   参数名称:locator

批次类和AddNewClient类中的代码是相同的,所以我无法看到问题所在

批次:

namespace OnlineStore.PageObjects
{
    class Batch
    {
        IWebDriver driver;

        //Admin link in left hand otions
        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_NavigationPanel_navigationpanel1_hlAdmin']")]
        public IWebElement AdminScreen { get; set; }

        //Add new batch link
        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_HyperLink38']")]
        public IWebElement AddNewBatchLnk { get; set; }

        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_DatepickerReceived_txtDate']")]
        public IWebElement DateReceived { get; set; }

        [FindsBy(How = How.XPath, Using = "//*[@id='aspnetForm']/div[3]/div/div[2]/div[3]/table[3]/tbody/tr/td/table/tbody/tr[7]/td]")]
        public IWebElement SelectToday { get; set; }

        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_txtTotal']")]
        public IWebElement BatchTotal { get; set; }

        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_ucCurrency_ddlCurrency']")]
        public IWebElement Currency { get; set; }

        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_cboAgency']")]
        public IWebElement Provider { get; set; }

        [FindsBy(How = How.XPath, Using = "//*[@id='ctl00_MainBody_txtNote']")]
        public IWebElement BatchNotes { get; set; }

        public Batch(IWebDriver driver)
        {
            this.driver = driver;
            PageFactory.InitElements(driver, this); 
        }

        public void AddNewBatch(string testName)
        {
            var userData = ExcelDataAccess.GetTestData(testName);

            IWait<IWebDriver> wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30.00));

            AdminScreen.Click();
            wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='ctl00_MainBody_HyperLink38']")));

            AddNewBatchLnk.Click();
            wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[@id='ctl00_MainBody_DatepickerReceived_txtDate']")));

            DateReceived.SendKeys("22/05/2017");
            //SelectToday.Click();
            BatchTotal.SendKeys("1000");
            Currency.SendKeys("USD");
            Provider.SendKeys("Client");
            BatchNotes.SendKeys("Some Batchg notes here please");

        }
    }
}

AddNewClient:

public AddNewClient(IWebDriver driver)
{
   this.driver = driver;
   PageFactory.InitElements(driver, this);
}

public void Addanewclient(string testName)
{ 
   //Code here
}

有什么想法吗?

更新:我尝试将AddBatchTest代码移动到Login代码脚本中并且运行正常但是当我将其推回到自己的测试时它再次出错。

评论中要求的完整堆栈跟踪。

Result StackTrace:  
at OpenQA.Selenium.Support.PageObjects.PageFactory.InitElements(Object page, IElementLocator locator, IPageObjectMemberDecorator decorator)
   at OpenQA.Selenium.Support.PageObjects.PageFactory.InitElements(ISearchContext driver, Object page)
   at OnlineStore.PageObjects.Batch..ctor(IWebDriver driver) in C:\Users\andrew.logan-smith\documents\visual studio 2015\Projects\OnlineStore\OnlineStore\PageObjects\Batch.cs:line 54
   at OnlineStore.TestCases.RunTest.AddBatchTest() in C:\Users\andrew.logan-smith\documents\visual studio 2015\Projects\OnlineStore\OnlineStore\TestCases\RunTest.cs:line 52
Result Message: 
System.ArgumentException : The SearchContext of the locator object cannot be null
Parameter name: locator

1 个答案:

答案 0 :(得分:2)

Test类中RunTest方法的顺序不一定是ecxution顺序。在您的情况下,订单可能是AddBatchTest() - &gt; Login() - &gt; Test1()。这导致driver在调用null构造函数时BatchPageFactory.InitElements收到null作为driver参数,即SearchContext因此错误

  

定位器对象的SearchContext不能为空

来自github

InitElements方法

public static void InitElements(ISearchContext driver, object page)
{
    InitElements(page, new DefaultElementLocator(driver));
}

我建议您在Login()注释下移动[SetUp]并添加[TearDown]。它将在每次测试之前和之后运行,并为您提供“干净的石板”

public class RunTest
{
    private IWebDriver driver = null;

    [SetUp]
    public void Login()
    {
        driver = new ChromeDriver(options);
        //...
    }

    [Test]
    public void AddBatchTest()
    {
        var AddBatch = new Batch(driver);
        AddBatch.AddNewBatch("Test1");
    }

    [Test]
    public void Test1()
    {
        var NewCli = new AddNewClient(driver);
        NewCli.Addanewclient("Test1");
    }

    [TearDown]
    public void TearDown()
    {
        if (Driver != null)
        {
            Driver.Quit();
        }
    }
}
  

修改

如果您想为所有测试运行SetUpTearDown一次,可以使用[TestFixtureSetUp][TestFixtureTearDown]注释。您还需要将[TestFixture]添加到班级

[TestFixture]
public class RunTest
{
    [TestFixtureSetUp]
    public void SetUp()
    {
    }

    [Test]
    public void AddBatchTest()
    {
    }

    [Test]
    public void Test1()
    {
    }

    [TestFixtureTearDown]
    public void TearDown()
    {
    }
}

*适用于NUnit 2,NUnit 3使用[OneTimeSetUp][OneTimeTearDown]