Having Multiple Step Files Opens Multiple BrowsersTroubles with [After*] Fixtures in StepsCatch multiple exceptions at once?How to create Excel (.XLS and .XLSX) file in C# without installing Ms Office?Selenium concern with Coding Practicessymfony2 / behat / mink login troubles when testing in the browser<Cucumber-JVM> pass values between steps in cucumberChrome driver 2.24 is not working with Chrome browser version 54Webdriver can login in Chrome, not in firefox: 'Unable to find owning document' errorError: 'value': keys_to_typing(value)} while sending keys selenium pythonTroubles with [After*] Fixtures in Steps

If human space travel is limited by the G force vulnerability, is there a way to counter G forces?

How do I gain back my faith in my PhD degree?

Is it possible to create a QR code using text?

Can my sorcerer use a spellbook only to collect spells and scribe scrolls, not cast?

What do you call someone who asks many questions?

Is it logically or scientifically possible to artificially send energy to the body?

Detention in 1997

How would I stat a creature to be immune to everything but the Magic Missile spell? (just for fun)

One verb to replace 'be a member of' a club

What method can I use to design a dungeon difficult enough that the PCs can't make it through without killing them?

How can saying a song's name be a copyright violation?

Unlock My Phone! February 2018

Probability that a draw from a normal distribution is some number greater than another draw from the same distribution

Do scales need to be in alphabetical order?

Unable to supress ligatures in headings which are set in Caps

What about the virus in 12 Monkeys?

Determining Impedance With An Antenna Analyzer

Is there a hemisphere-neutral way of specifying a season?

Why doesn't using multiple commands with a || or && conditional work?

What are some good books on Machine Learning and AI like Krugman, Wells and Graddy's "Essentials of Economics"

GFCI outlets - can they be repaired? Are they really needed at the end of a circuit?

Valid term from quadratic sequence?

Is "remove commented out code" correct English?

Short story with a alien planet, government officials must wear exploding medallions



Having Multiple Step Files Opens Multiple Browsers


Troubles with [After*] Fixtures in StepsCatch multiple exceptions at once?How to create Excel (.XLS and .XLSX) file in C# without installing Ms Office?Selenium concern with Coding Practicessymfony2 / behat / mink login troubles when testing in the browser<Cucumber-JVM> pass values between steps in cucumberChrome driver 2.24 is not working with Chrome browser version 54Webdriver can login in Chrome, not in firefox: 'Unable to find owning document' errorError: 'value': keys_to_typing(value)} while sending keys selenium pythonTroubles with [After*] Fixtures in Steps













2















The Problem:



If I have more than one Steps file, when I execute tests it seems that the WebDriver creation for each is being happening regardless of which test(s) I run.



I was seeing a seemingly random Chrome Browser open up whenever I ran my tests. In an attempt to see if there was some sort of incompatibility between SpecFlow and ChromeDriver (a long shot, I know), I changed the WebDriver for my search tests to Firefox and left the WebDriver for my login tests as Chrome. No matter what test(s) I ran, I always saw 2 browsers open; one Chrome and one Firefox.



When I moved all of the steps from my SearchTestSteps.cs file into the LoginTestSteps.cs file, the problem disappeared.



So, yeah, this solves the immediate issue, but it is sub-optimal to have all of my steps in a single file. That can quickly become unwieldy.



Since each set of steps needs to have its own WebDriver, I'm at a loss.



Might this have something to do with folder structure and where things are stored? Here is what mine looks like.



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


The Code:



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 (I also have a SearchTestSteps.cs that looks very similar)
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);












share|improve this question


























    2















    The Problem:



    If I have more than one Steps file, when I execute tests it seems that the WebDriver creation for each is being happening regardless of which test(s) I run.



    I was seeing a seemingly random Chrome Browser open up whenever I ran my tests. In an attempt to see if there was some sort of incompatibility between SpecFlow and ChromeDriver (a long shot, I know), I changed the WebDriver for my search tests to Firefox and left the WebDriver for my login tests as Chrome. No matter what test(s) I ran, I always saw 2 browsers open; one Chrome and one Firefox.



    When I moved all of the steps from my SearchTestSteps.cs file into the LoginTestSteps.cs file, the problem disappeared.



    So, yeah, this solves the immediate issue, but it is sub-optimal to have all of my steps in a single file. That can quickly become unwieldy.



    Since each set of steps needs to have its own WebDriver, I'm at a loss.



    Might this have something to do with folder structure and where things are stored? Here is what mine looks like.



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


    The Code:



    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 (I also have a SearchTestSteps.cs that looks very similar)
    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);












    share|improve this question
























      2












      2








      2








      The Problem:



      If I have more than one Steps file, when I execute tests it seems that the WebDriver creation for each is being happening regardless of which test(s) I run.



      I was seeing a seemingly random Chrome Browser open up whenever I ran my tests. In an attempt to see if there was some sort of incompatibility between SpecFlow and ChromeDriver (a long shot, I know), I changed the WebDriver for my search tests to Firefox and left the WebDriver for my login tests as Chrome. No matter what test(s) I ran, I always saw 2 browsers open; one Chrome and one Firefox.



      When I moved all of the steps from my SearchTestSteps.cs file into the LoginTestSteps.cs file, the problem disappeared.



      So, yeah, this solves the immediate issue, but it is sub-optimal to have all of my steps in a single file. That can quickly become unwieldy.



      Since each set of steps needs to have its own WebDriver, I'm at a loss.



      Might this have something to do with folder structure and where things are stored? Here is what mine looks like.



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


      The Code:



      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 (I also have a SearchTestSteps.cs that looks very similar)
      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);












      share|improve this question














      The Problem:



      If I have more than one Steps file, when I execute tests it seems that the WebDriver creation for each is being happening regardless of which test(s) I run.



      I was seeing a seemingly random Chrome Browser open up whenever I ran my tests. In an attempt to see if there was some sort of incompatibility between SpecFlow and ChromeDriver (a long shot, I know), I changed the WebDriver for my search tests to Firefox and left the WebDriver for my login tests as Chrome. No matter what test(s) I ran, I always saw 2 browsers open; one Chrome and one Firefox.



      When I moved all of the steps from my SearchTestSteps.cs file into the LoginTestSteps.cs file, the problem disappeared.



      So, yeah, this solves the immediate issue, but it is sub-optimal to have all of my steps in a single file. That can quickly become unwieldy.



      Since each set of steps needs to have its own WebDriver, I'm at a loss.



      Might this have something to do with folder structure and where things are stored? Here is what mine looks like.



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


      The Code:



      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 (I also have a SearchTestSteps.cs that looks very similar)
      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);









      c# selenium selenium-webdriver bdd specflow






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Mar 8 at 22:20









      Eddy JonesEddy Jones

      515




      515






















          3 Answers
          3






          active

          oldest

          votes


















          1














          I figured out how to fix this issue using Binding Scopes.



          In each of the Steps files, I can do the following:



           [BeforeFeature(), Scope(Feature = "SearchTests")]
          public static void Startup()

          _driver = new ChromeDriver();


          [AfterFeature()]
          public static void ShutDown()

          _driver?.Close();



          Doing this opens and closes the Driver for only the Test file that I want it to.
          I can also choose to scope to the tag before each test if I need to get more granular.






          share|improve this answer























          • Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

            – supputuri
            Mar 9 at 14:04











          • that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

            – Eddy Jones
            Mar 11 at 17:06











          • Cool. All the best!

            – supputuri
            Mar 11 at 17:10


















          0














          You might have created driver instance in each of the .cs files.
          Eg: In the LoginSteps.cs you are creating chrome driver in the below loc.



          private static readonly IWebDriver Driver = new ChromeDriver();


          You should create the driver outside the xStep.cs files and just pass it to the class/method based on the framework.






          share|improve this answer























          • I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

            – Eddy Jones
            Mar 8 at 23:25











          • To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

            – supputuri
            Mar 8 at 23:37



















          0














          Ultimately this is being caused by creating the web drivers as static fields on your step definition classes. You need to centralize this logic.



          You want to create your web driver before the feature, register it with the SpecFlow dependency injection container, and then pass that IWebDriver object around to your step definitions.



          I found it a good idea to implement a "lazy" web driver, so the browser window only gets spawned when your C# code actually needs to interact with it. This LazyWebDriver class implements the IWebDriver interface, and is a wrapper for a real web driver.



          LazyWebDriver.cs



          public sealed class LazyWebDriver : IWebDriver

          private readonly Lazy<IWebDriver> driver;

          public string Title => driver.Value.Title;

          // Other properties defined in IWebDriver just pass through to driver.Value.Property

          public LazyWebDriver(Func<IWebDriver> driverFactory)

          driver = new Lazy<IWebDriver>(driverFactory);


          public IWebElement FindElement(By by)

          return driver.Value.FindElement(by);


          public void Close()

          driver.Value.Close();


          // other methods defined in IWebDriver just pass through to driver.Value.Method(...)



          Then using SpecFlow hooks (which is just fancy-talk for "events" in SpecFlow) you can create your real web driver and the lazy web driver and register it with the SpecFlow framework:



          SeleniumHooks.cs



          [Binding]
          public sealed class SeleniumHooks

          private readonly IObjectContainer objectContainer;

          public SeleniumHooks(IObjectContainer objectContainer)

          this.objectContainer = objectContainer;


          [BeforeFeature]
          public void RegisterWebDriver()

          objectContainer.RegisterInstanceAs<IWebDriver>(new LazyWebDriver(CreateWebDriver));


          private IWebDriver CreateWebDriver()

          return new ChromeDriver();


          [AfterFeature]
          public void DestroyWebDriver()

          objectContainer.Resolve<IWebDriver>()?.Close();




          Lastly, a few modifications to your LoginSteps.cs file:



          [Binding]
          public class LoginSteps

          private readonly IWebDriver Driver;
          private LoginPage _loginPage;

          private static string _username;
          private static string _password;
          private static string _repo;

          public LoginSteps(IWebDriver driver)

          Driver = driver;


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




          Notice that the IWebDriver object is passed in as a constructor argument to LoginSteps. SpecFlow comes with a dependency injection framework, which is smart enough to pass the LazyWebDriver you registered in SeleniumHooks as the IWebDriver argument to the LoginSteps constructor.



          Be sure to make the _loginPage field an instance field rather than static.






          share|improve this answer

























            Your Answer






            StackExchange.ifUsing("editor", function ()
            StackExchange.using("externalEditor", function ()
            StackExchange.using("snippets", function ()
            StackExchange.snippets.init();
            );
            );
            , "code-snippets");

            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "1"
            ;
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function()
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled)
            StackExchange.using("snippets", function()
            createEditor();
            );

            else
            createEditor();

            );

            function createEditor()
            StackExchange.prepareEditor(
            heartbeatType: 'answer',
            autoActivateHeartbeat: false,
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader:
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            ,
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            );



            );













            draft saved

            draft discarded


















            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55071795%2fhaving-multiple-step-files-opens-multiple-browsers%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes









            1














            I figured out how to fix this issue using Binding Scopes.



            In each of the Steps files, I can do the following:



             [BeforeFeature(), Scope(Feature = "SearchTests")]
            public static void Startup()

            _driver = new ChromeDriver();


            [AfterFeature()]
            public static void ShutDown()

            _driver?.Close();



            Doing this opens and closes the Driver for only the Test file that I want it to.
            I can also choose to scope to the tag before each test if I need to get more granular.






            share|improve this answer























            • Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

              – supputuri
              Mar 9 at 14:04











            • that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

              – Eddy Jones
              Mar 11 at 17:06











            • Cool. All the best!

              – supputuri
              Mar 11 at 17:10















            1














            I figured out how to fix this issue using Binding Scopes.



            In each of the Steps files, I can do the following:



             [BeforeFeature(), Scope(Feature = "SearchTests")]
            public static void Startup()

            _driver = new ChromeDriver();


            [AfterFeature()]
            public static void ShutDown()

            _driver?.Close();



            Doing this opens and closes the Driver for only the Test file that I want it to.
            I can also choose to scope to the tag before each test if I need to get more granular.






            share|improve this answer























            • Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

              – supputuri
              Mar 9 at 14:04











            • that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

              – Eddy Jones
              Mar 11 at 17:06











            • Cool. All the best!

              – supputuri
              Mar 11 at 17:10













            1












            1








            1







            I figured out how to fix this issue using Binding Scopes.



            In each of the Steps files, I can do the following:



             [BeforeFeature(), Scope(Feature = "SearchTests")]
            public static void Startup()

            _driver = new ChromeDriver();


            [AfterFeature()]
            public static void ShutDown()

            _driver?.Close();



            Doing this opens and closes the Driver for only the Test file that I want it to.
            I can also choose to scope to the tag before each test if I need to get more granular.






            share|improve this answer













            I figured out how to fix this issue using Binding Scopes.



            In each of the Steps files, I can do the following:



             [BeforeFeature(), Scope(Feature = "SearchTests")]
            public static void Startup()

            _driver = new ChromeDriver();


            [AfterFeature()]
            public static void ShutDown()

            _driver?.Close();



            Doing this opens and closes the Driver for only the Test file that I want it to.
            I can also choose to scope to the tag before each test if I need to get more granular.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 8 at 23:28









            Eddy JonesEddy Jones

            515




            515












            • Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

              – supputuri
              Mar 9 at 14:04











            • that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

              – Eddy Jones
              Mar 11 at 17:06











            • Cool. All the best!

              – supputuri
              Mar 11 at 17:10

















            • Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

              – supputuri
              Mar 9 at 14:04











            • that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

              – Eddy Jones
              Mar 11 at 17:06











            • Cool. All the best!

              – supputuri
              Mar 11 at 17:10
















            Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

            – supputuri
            Mar 9 at 14:04





            Cool. But I would recommend to create a browser_steps.cs with "open" method. With in the method check if driver is nil then create the driver instance based on the browser you pass to the method or in the global variable. By this way you don't have to handle the driver startup and tear down in each of the step.cs file.

            – supputuri
            Mar 9 at 14:04













            that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

            – Eddy Jones
            Mar 11 at 17:06





            that was my reluctance to do it this way as well. I have created a baseSteps class that has the driver creations with before and after feature methods... So far everything is working perfectly.

            – Eddy Jones
            Mar 11 at 17:06













            Cool. All the best!

            – supputuri
            Mar 11 at 17:10





            Cool. All the best!

            – supputuri
            Mar 11 at 17:10













            0














            You might have created driver instance in each of the .cs files.
            Eg: In the LoginSteps.cs you are creating chrome driver in the below loc.



            private static readonly IWebDriver Driver = new ChromeDriver();


            You should create the driver outside the xStep.cs files and just pass it to the class/method based on the framework.






            share|improve this answer























            • I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

              – Eddy Jones
              Mar 8 at 23:25











            • To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

              – supputuri
              Mar 8 at 23:37
















            0














            You might have created driver instance in each of the .cs files.
            Eg: In the LoginSteps.cs you are creating chrome driver in the below loc.



            private static readonly IWebDriver Driver = new ChromeDriver();


            You should create the driver outside the xStep.cs files and just pass it to the class/method based on the framework.






            share|improve this answer























            • I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

              – Eddy Jones
              Mar 8 at 23:25











            • To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

              – supputuri
              Mar 8 at 23:37














            0












            0








            0







            You might have created driver instance in each of the .cs files.
            Eg: In the LoginSteps.cs you are creating chrome driver in the below loc.



            private static readonly IWebDriver Driver = new ChromeDriver();


            You should create the driver outside the xStep.cs files and just pass it to the class/method based on the framework.






            share|improve this answer













            You might have created driver instance in each of the .cs files.
            Eg: In the LoginSteps.cs you are creating chrome driver in the below loc.



            private static readonly IWebDriver Driver = new ChromeDriver();


            You should create the driver outside the xStep.cs files and just pass it to the class/method based on the framework.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Mar 8 at 22:55









            supputurisupputuri

            1,1381612




            1,1381612












            • I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

              – Eddy Jones
              Mar 8 at 23:25











            • To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

              – supputuri
              Mar 8 at 23:37


















            • I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

              – Eddy Jones
              Mar 8 at 23:25











            • To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

              – supputuri
              Mar 8 at 23:37

















            I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

            – Eddy Jones
            Mar 8 at 23:25





            I guess this is where my newness to SpecFlow comes in. How do I pass a driver to the steps file from the Gherkin. There doesn't seem to be a way to do that.

            – Eddy Jones
            Mar 8 at 23:25













            To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

            – supputuri
            Mar 8 at 23:37






            To be frank I don't have much hands on with SpecFlow, but you have to use "before scenario" or "hooks". Sorry, I am not able to provide more insight. Check this link SpecFlow Documentation

            – supputuri
            Mar 8 at 23:37












            0














            Ultimately this is being caused by creating the web drivers as static fields on your step definition classes. You need to centralize this logic.



            You want to create your web driver before the feature, register it with the SpecFlow dependency injection container, and then pass that IWebDriver object around to your step definitions.



            I found it a good idea to implement a "lazy" web driver, so the browser window only gets spawned when your C# code actually needs to interact with it. This LazyWebDriver class implements the IWebDriver interface, and is a wrapper for a real web driver.



            LazyWebDriver.cs



            public sealed class LazyWebDriver : IWebDriver

            private readonly Lazy<IWebDriver> driver;

            public string Title => driver.Value.Title;

            // Other properties defined in IWebDriver just pass through to driver.Value.Property

            public LazyWebDriver(Func<IWebDriver> driverFactory)

            driver = new Lazy<IWebDriver>(driverFactory);


            public IWebElement FindElement(By by)

            return driver.Value.FindElement(by);


            public void Close()

            driver.Value.Close();


            // other methods defined in IWebDriver just pass through to driver.Value.Method(...)



            Then using SpecFlow hooks (which is just fancy-talk for "events" in SpecFlow) you can create your real web driver and the lazy web driver and register it with the SpecFlow framework:



            SeleniumHooks.cs



            [Binding]
            public sealed class SeleniumHooks

            private readonly IObjectContainer objectContainer;

            public SeleniumHooks(IObjectContainer objectContainer)

            this.objectContainer = objectContainer;


            [BeforeFeature]
            public void RegisterWebDriver()

            objectContainer.RegisterInstanceAs<IWebDriver>(new LazyWebDriver(CreateWebDriver));


            private IWebDriver CreateWebDriver()

            return new ChromeDriver();


            [AfterFeature]
            public void DestroyWebDriver()

            objectContainer.Resolve<IWebDriver>()?.Close();




            Lastly, a few modifications to your LoginSteps.cs file:



            [Binding]
            public class LoginSteps

            private readonly IWebDriver Driver;
            private LoginPage _loginPage;

            private static string _username;
            private static string _password;
            private static string _repo;

            public LoginSteps(IWebDriver driver)

            Driver = driver;


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




            Notice that the IWebDriver object is passed in as a constructor argument to LoginSteps. SpecFlow comes with a dependency injection framework, which is smart enough to pass the LazyWebDriver you registered in SeleniumHooks as the IWebDriver argument to the LoginSteps constructor.



            Be sure to make the _loginPage field an instance field rather than static.






            share|improve this answer





























              0














              Ultimately this is being caused by creating the web drivers as static fields on your step definition classes. You need to centralize this logic.



              You want to create your web driver before the feature, register it with the SpecFlow dependency injection container, and then pass that IWebDriver object around to your step definitions.



              I found it a good idea to implement a "lazy" web driver, so the browser window only gets spawned when your C# code actually needs to interact with it. This LazyWebDriver class implements the IWebDriver interface, and is a wrapper for a real web driver.



              LazyWebDriver.cs



              public sealed class LazyWebDriver : IWebDriver

              private readonly Lazy<IWebDriver> driver;

              public string Title => driver.Value.Title;

              // Other properties defined in IWebDriver just pass through to driver.Value.Property

              public LazyWebDriver(Func<IWebDriver> driverFactory)

              driver = new Lazy<IWebDriver>(driverFactory);


              public IWebElement FindElement(By by)

              return driver.Value.FindElement(by);


              public void Close()

              driver.Value.Close();


              // other methods defined in IWebDriver just pass through to driver.Value.Method(...)



              Then using SpecFlow hooks (which is just fancy-talk for "events" in SpecFlow) you can create your real web driver and the lazy web driver and register it with the SpecFlow framework:



              SeleniumHooks.cs



              [Binding]
              public sealed class SeleniumHooks

              private readonly IObjectContainer objectContainer;

              public SeleniumHooks(IObjectContainer objectContainer)

              this.objectContainer = objectContainer;


              [BeforeFeature]
              public void RegisterWebDriver()

              objectContainer.RegisterInstanceAs<IWebDriver>(new LazyWebDriver(CreateWebDriver));


              private IWebDriver CreateWebDriver()

              return new ChromeDriver();


              [AfterFeature]
              public void DestroyWebDriver()

              objectContainer.Resolve<IWebDriver>()?.Close();




              Lastly, a few modifications to your LoginSteps.cs file:



              [Binding]
              public class LoginSteps

              private readonly IWebDriver Driver;
              private LoginPage _loginPage;

              private static string _username;
              private static string _password;
              private static string _repo;

              public LoginSteps(IWebDriver driver)

              Driver = driver;


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




              Notice that the IWebDriver object is passed in as a constructor argument to LoginSteps. SpecFlow comes with a dependency injection framework, which is smart enough to pass the LazyWebDriver you registered in SeleniumHooks as the IWebDriver argument to the LoginSteps constructor.



              Be sure to make the _loginPage field an instance field rather than static.






              share|improve this answer



























                0












                0








                0







                Ultimately this is being caused by creating the web drivers as static fields on your step definition classes. You need to centralize this logic.



                You want to create your web driver before the feature, register it with the SpecFlow dependency injection container, and then pass that IWebDriver object around to your step definitions.



                I found it a good idea to implement a "lazy" web driver, so the browser window only gets spawned when your C# code actually needs to interact with it. This LazyWebDriver class implements the IWebDriver interface, and is a wrapper for a real web driver.



                LazyWebDriver.cs



                public sealed class LazyWebDriver : IWebDriver

                private readonly Lazy<IWebDriver> driver;

                public string Title => driver.Value.Title;

                // Other properties defined in IWebDriver just pass through to driver.Value.Property

                public LazyWebDriver(Func<IWebDriver> driverFactory)

                driver = new Lazy<IWebDriver>(driverFactory);


                public IWebElement FindElement(By by)

                return driver.Value.FindElement(by);


                public void Close()

                driver.Value.Close();


                // other methods defined in IWebDriver just pass through to driver.Value.Method(...)



                Then using SpecFlow hooks (which is just fancy-talk for "events" in SpecFlow) you can create your real web driver and the lazy web driver and register it with the SpecFlow framework:



                SeleniumHooks.cs



                [Binding]
                public sealed class SeleniumHooks

                private readonly IObjectContainer objectContainer;

                public SeleniumHooks(IObjectContainer objectContainer)

                this.objectContainer = objectContainer;


                [BeforeFeature]
                public void RegisterWebDriver()

                objectContainer.RegisterInstanceAs<IWebDriver>(new LazyWebDriver(CreateWebDriver));


                private IWebDriver CreateWebDriver()

                return new ChromeDriver();


                [AfterFeature]
                public void DestroyWebDriver()

                objectContainer.Resolve<IWebDriver>()?.Close();




                Lastly, a few modifications to your LoginSteps.cs file:



                [Binding]
                public class LoginSteps

                private readonly IWebDriver Driver;
                private LoginPage _loginPage;

                private static string _username;
                private static string _password;
                private static string _repo;

                public LoginSteps(IWebDriver driver)

                Driver = driver;


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




                Notice that the IWebDriver object is passed in as a constructor argument to LoginSteps. SpecFlow comes with a dependency injection framework, which is smart enough to pass the LazyWebDriver you registered in SeleniumHooks as the IWebDriver argument to the LoginSteps constructor.



                Be sure to make the _loginPage field an instance field rather than static.






                share|improve this answer















                Ultimately this is being caused by creating the web drivers as static fields on your step definition classes. You need to centralize this logic.



                You want to create your web driver before the feature, register it with the SpecFlow dependency injection container, and then pass that IWebDriver object around to your step definitions.



                I found it a good idea to implement a "lazy" web driver, so the browser window only gets spawned when your C# code actually needs to interact with it. This LazyWebDriver class implements the IWebDriver interface, and is a wrapper for a real web driver.



                LazyWebDriver.cs



                public sealed class LazyWebDriver : IWebDriver

                private readonly Lazy<IWebDriver> driver;

                public string Title => driver.Value.Title;

                // Other properties defined in IWebDriver just pass through to driver.Value.Property

                public LazyWebDriver(Func<IWebDriver> driverFactory)

                driver = new Lazy<IWebDriver>(driverFactory);


                public IWebElement FindElement(By by)

                return driver.Value.FindElement(by);


                public void Close()

                driver.Value.Close();


                // other methods defined in IWebDriver just pass through to driver.Value.Method(...)



                Then using SpecFlow hooks (which is just fancy-talk for "events" in SpecFlow) you can create your real web driver and the lazy web driver and register it with the SpecFlow framework:



                SeleniumHooks.cs



                [Binding]
                public sealed class SeleniumHooks

                private readonly IObjectContainer objectContainer;

                public SeleniumHooks(IObjectContainer objectContainer)

                this.objectContainer = objectContainer;


                [BeforeFeature]
                public void RegisterWebDriver()

                objectContainer.RegisterInstanceAs<IWebDriver>(new LazyWebDriver(CreateWebDriver));


                private IWebDriver CreateWebDriver()

                return new ChromeDriver();


                [AfterFeature]
                public void DestroyWebDriver()

                objectContainer.Resolve<IWebDriver>()?.Close();




                Lastly, a few modifications to your LoginSteps.cs file:



                [Binding]
                public class LoginSteps

                private readonly IWebDriver Driver;
                private LoginPage _loginPage;

                private static string _username;
                private static string _password;
                private static string _repo;

                public LoginSteps(IWebDriver driver)

                Driver = driver;


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




                Notice that the IWebDriver object is passed in as a constructor argument to LoginSteps. SpecFlow comes with a dependency injection framework, which is smart enough to pass the LazyWebDriver you registered in SeleniumHooks as the IWebDriver argument to the LoginSteps constructor.



                Be sure to make the _loginPage field an instance field rather than static.







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited 3 hours ago

























                answered 3 hours ago









                Greg BurghardtGreg Burghardt

                8,58163050




                8,58163050



























                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid


                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.

                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55071795%2fhaving-multiple-step-files-opens-multiple-browsers%23new-answer', 'question_page');

                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    How to get text form Clipboard with JavaScript in Firefox 56?How to validate an email address in JavaScript?How do JavaScript closures work?How do I remove a property from a JavaScript object?How do you get a timestamp in JavaScript?How do I copy to the clipboard in JavaScript?How do I include a JavaScript file in another JavaScript file?Get the current URL with JavaScript?How to replace all occurrences of a string in JavaScriptHow to check whether a string contains a substring in JavaScript?How do I remove a particular element from an array in JavaScript?

                    Can't initialize raids on a new ASUS Prime B360M-A motherboard2019 Community Moderator ElectionSimilar to RAID config yet more like mirroring solution?Can't get motherboard serial numberWhy does the BIOS entry point start with a WBINVD instruction?UEFI performance Asus Maximus V Extreme

                    List of MPs elected to the English parliament in 1640 (April) Contents List of constituencies and members See also Notes References Navigation menueNational Archives – The Glynde Place ArchivesCobbett's Parliamentary history of England, from the Norman Conquest in 1066 to the year 1803'Aldermen in Parliament', The Aldermen of the City of London: Temp. Henry III – 1912onepage&q&f&#61, false 229