有[After *]固定装置的麻烦步骤

时间:2019-03-08 00:29:28

标签: c# .net bdd specflow fixtures

问题:

我有两个功能(我刚开始使用SpecFlow) 在每个功能步骤中,我都会创建一个全局WebDriver,以便可以将其用于所有步骤。如果仅执行这些步骤,则所有功能都可以正常运行。但是,它们确实使浏览器窗口保持打开状态,因为我从未关闭过WebDriver。因此,我的想法是在每个Step文件中放置一个AfterFeature固定装置以关闭驱动程序。

[AfterFeature]
public static void ShutDown()
{
     Driver.Close();
}

当我运行每个功能时,一切都很好,并且驱动程序在运行结束时关闭。但是,如果我运行多个这样的功能,驱动程序将在第一个功能后关闭,而下一个功能启动时将不会打开新的功能。我觉得很奇怪,因为每个功能步骤文件都有自己的实例化驱动程序。

我了解到,如果使用[AfterTestRun],则测试将正确运行,并且两个浏览器将保持打开状态,直到所有功能都完成。到时它们都将关闭。当我只有两个功能时,现在可以这样做,但是当我得到一堆功能时,我宁愿没有一堆随机的浏览器窗口出现,直到所有测试完成。

我认为这可能与我无法使用[AfterScenario]而没有破坏我的测试有关。我试图使用[AfterScenario]在每个方案/测试后注销,但是当我这样做时,我看到在第一个测试结束时弹出一个随机的空白驱动程序/浏览器窗口(无论我首先运行哪个测试)。

我有种感觉,就是我在这里缺少整个BDD方法的某种范例,并且事情实际上按照设计进行。但是我对应该做出什么改变感到茫然。这是我的登录测试的示例。.这里是否缺少一些基本信息?

代码:

Login.feature
Feature: Login
    In order to be able to use Laserfiche
    As a legitimate user
    I want to be able to log into the repository

@SmokeTest
Scenario: Login with correct credentials
    Given I am on the Login page 
    And I have a good username/password combination
    And I select a repository
    When I fill out the form and submit
    Then I am taken to the repo page

---------------
LoginSteps.cs
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using Selenium_C_Sharp_POC.Page_Object_Files.Pages;
using Selenium_C_Sharp_POC.Page_Object_Files.Test_Tools;
using TechTalk.SpecFlow;

namespace Selenium_C_Sharp_POC.StepDefinitions
{
    [Binding]
    public class LoginSteps
    {
        private static readonly IWebDriver Driver = new ChromeDriver();

        private static LoginPage _loginPage;
        private static string _username;
        private static string _password;
        private static string _repo;

        [AfterTestRun]
        public static void ShutDown()
        {
            Driver?.Close();
        }

        [Given(@"I am on the Login page")]
        public void GivenIAmOnTheLoginPage()
        {
            _loginPage = new LoginPage(Driver);
        }

        [Given(@"I have a good username/password combination")]
        public void GivenIHaveAGoodUsernamePasswordCombination()
        {
            _username = Nomenclature.WebClientPersonalUsername;
            _password = Nomenclature.WebClientPersonalPassword;
        }
        [Given(@"I select a repository")]
        public void GivenISelectARepository()
        {
            _repo = Nomenclature.RepoUnderTest;
        }

        [When(@"I fill out the form and submit")]
        public void WhenIFillOutTheFormAndSubmit()
        {
            _loginPage.Login(
                username: _username, 
                password: _password, 
                repo: _repo);
        }

        [Then(@"I am taken to the repo page")]
        public void ThenIAmTakenToTheRepoPage()
        {
            Assert.AreEqual(
                expected: _repo,
                actual: Driver.Title);

            HelperMethods.Logout(Driver);
        }
    }
}

编辑:添加了登录页面类代码

using System;
using OpenQA.Selenium;
using System.Threading;
using OpenQA.Selenium.Support.UI;
using SeleniumExtras.WaitHelpers;
using Selenium_C_Sharp_POC.Page_Object_Files.Test_Tools;

namespace Selenium_C_Sharp_POC.Page_Object_Files.Pages
{
    class LoginPage
    {
        private readonly IWebElement _repoDropDown;
        private readonly IWebElement _usernameTextBox;
        private readonly IWebElement _passwordTextBox;
        private readonly IWebElement _submitButton;
        private readonly IWebDriver _driver;
        private readonly IWebElement _warningBox;

        public LoginPage(IWebDriver driver)
        {
            _driver = driver;

            HelperMethods.OpenWebPage(
                domain: Nomenclature.Domain, 
                driver: _driver,
                subPage: Nomenclature.LoginPageFilename
                );

            _repoDropDown = _driver.FindElement(By.Id("SelectedRepo"));
            _passwordTextBox = _driver.FindElement(By.Name("password"));
            _usernameTextBox = _driver.FindElement(By.Name("username"));
            _submitButton = _driver.FindElement(By.Id("LoginButton"));
            _warningBox = _driver.FindElement(By.ClassName("alert-danger"));
        }

        public void Login(string username, string password, string repo)
        {
           SelectRepo(repo);
           _usernameTextBox.SendKeys(username);
           _passwordTextBox.SendKeys(password);
           _submitButton.Click();
           WaitForLoginToComplete();
        }

        public void SelectRepo(string repo)
        {
            _repoDropDown.Click();
            var options =  _repoDropDown.FindElements(By.XPath(".//option"));
            foreach (var option in options)
            {
                if(option.Text.Equals(repo))
                    option.Click();
            }
        }

        public bool WarningDisplayed_UsernamePassword()
        {  
           Thread.Sleep(500);
           return _warningBox.Displayed &&
                  _warningBox.Text.Equals(Nomenclature.BadUsernameOrPasswordText, StringComparison.OrdinalIgnoreCase);
        }

        internal bool OpenedRepoPage(string expectedRepo)
        {
            return _driver.Title.Equals(expectedRepo);
        }

        internal void WaitForLoginToComplete()
        {
            try
            {
                var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(5));
                wait.Until(ExpectedConditions.ElementIsVisible(By.ClassName("alert-danger")));
            }
            catch (Exception)
            {
                var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(45));
                wait.Until(ExpectedConditions.ElementExists(By.XPath("//*[@ng-model='searchQuery']")));
                wait.Until(ExpectedConditions.InvisibilityOfElementLocated(By.ClassName("entryListLoadingSpinner")));
            }
        }
    }
}

LatestInfo:

我相信我知道 为什么 。我只是不知道修复它的正确方法。作为实验,我将用于搜索测试的WebDriver更改为Firefox,并将用于登录测试的WebDriver保留为Chrome。不管我运行了什么测试,我总是看到两个浏览器都打开了。一台Chrome浏览器和一台Firefox。

当我将所有步骤从SearchTestSteps.cs文件移至LoginTestSteps.cs文件时,问题消失了。

所以,是的,这解决了眼前的问题,但是将我的所有步骤都放在一个文件中并不是最佳选择。这样很快就会变得笨拙。

由于每组步骤都需要具有自己的WebDriver,所以我很茫然。

这可能与文件夹结构以及存储的位置有关吗?这是我的样子。

Root
 |-Page Object Files
      |- Page Components
      |- Pages
      |- Test Tools  
 |- Step Definitions
      |- <*Steps.cs>  
 |- TESTS
      |- BDD Tests
          |-<*.feature>
      |- *standard selenium test files*

1 个答案:

答案 0 :(得分:0)

在进行了更多调查之后,我意识到问题不是我所认为的不是,因此标题和内容不正确。我正在关闭此问题,并使用更准确的标题和信息创建一个新问题。

Having Multiple Step Files Opens Multiple Browsers