0

I'm having an issue with sharing my driver between step files in my projects. I've done a lot of googling online and come up with a solution using the IObjectContainer. Which I believe is correct? However, it doesn't seem to work. It gets stuck. I don't quite understand where IObjectContainer gets instantiated. Below is the code of my Hooks file and one of my Step Files:

Hooks File:

public class RDM_Hooks
    {

        private IObjectContainer _objectContainer;
        public RDM_Website<ChromeDriver> RDM_Website;

        public void WebDriverSupport(IObjectContainer objectContainer)
        {
            _objectContainer = objectContainer;
        }
        
        [BeforeScenario]
        public void InitWebDriver()
        {
            RDM_Website = new RDM_Website<ChromeDriver>();
            _objectContainer.RegisterInstanceAs<RDM_Website<ChromeDriver>>(RDM_Website);
        }
        
        [AfterScenario]
        public void DisposeWebDriver()
        {
            RDM_Website.SeleniumDriver.Quit();
            RDM_Website.SeleniumDriver.Dispose();
        }
    }

Steps File:

    public class RDM_LoginSteps
    {
        private RDM_Website<ChromeDriver> RDM_Website;
        public RDM_LoginSteps(RDM_Website<ChromeDriver> rdm_website) 
        {
            RDM_Website = rdm_website;
        }

        [Given(@"I am on the homepage")]
        public void GivenIAmOnTheHomepage()
        {
            RDM_Website.RDM_Homepage.VisitHomePage();
        }
    }

I think im missing something somewhere but any info i've found online doesn't go further than the above and I'm a bit lost.

I simply want all my step files to share the same browser so I'm able to have all my login steps using one file and do something else on another for example.

Liam Nagle
  • 15
  • 5
  • Does this answer your question? [Using ChromeDriver across SpecFlow Tests](https://stackoverflow.com/questions/58409700/using-chromedriver-across-specflow-tests) – Greg Burghardt Jan 20 '23 at 13:32
  • See also [Selenium with Page Object Model Pattern](https://docs.specflow.org/projects/specflow/en/latest/ui-automation/Selenium-with-Page-Object-Pattern.html) at SpecFlow.org. – Greg Burghardt Jan 20 '23 at 13:33
  • Hi @GregBurghardt thanks for this. The first link you sent essentially does what I have done. Which is what I don't understand. However it doesn't work? The IObjectContainer doesn't get called anywhere and none of the constructors for the step files do either? So i'm confused on how this works? Are you able to help? – Liam Nagle Jan 20 '23 at 15:10
  • 2
    Do you have the `[Binding]` attribute above your hooks and steps classes? – Greg Burghardt Jan 20 '23 at 15:14
  • 1
    Does your solution even build? It looks like the constructor is named incorrectly. Shouldn't the constructor for the RDM_Hooks class be named "RDM_Hooks" instead of "WebDriverSupport"? – Greg Burghardt Jan 20 '23 at 15:45
  • I do have the ```[Binding]``` yeah. Ahh amazing i completely missed that - It all works now. Thanks so much! I would have been messing around with that for ages – Liam Nagle Jan 20 '23 at 17:15

1 Answers1

0

Here's the Hook file I use my UI tests

[Binding]
internal sealed class WebHooks
{
    private readonly IObjectContainer _objectContainer;

    public WebHooks(IObjectContainer objectContainer)
    {
        _objectContainer = objectContainer;
    }

    [BeforeScenario("web")]
    public void BeforeWebScenario()
    {
        //HACK: 
        //https://stackoverflow.com/questions/43571119/loading-of-unpacked-extensions-is-disabled-by-the-administrator
        var options = new ChromeOptions();
        options.AddArgument("--start-maximized");
        options.AddAdditionalCapability("useAutomationExtension", false);
        options.AddArgument("--no-sandbox");
        options.AddArgument("--whitelisted-ips=''");


        //HACK: this fixes issue with not being able to find chromedriver.exe
        //https://stackoverflow.com/questions/47910244/selenium-cant-find-chromedriver-exe
        var webDriver = new ChromeDriver(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), options, TimeSpan.FromMinutes(15));
        webDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(40);

        _objectContainer.RegisterInstanceAs<IWebDriver>(webDriver);
    }


    [AfterScenario("web")]
    public void AfterWebScenario()
    {
        var webDriver = _objectContainer.Resolve<IWebDriver>();

        if (webDriver == null) return;

        webDriver.Close();
        webDriver.Dispose();
    }
}

It looks like you're missing the [Binding] attribute on the hook class.

I also don't see you getting the reference out of the container to Dispose of it when you are done.

I don't know what RDM_Website is doing, but I'd keep you hooks clean with just reference to the driver and nothing else.

Then reference it in your step class like

[Binding]
public class Steps
{
    private readonly IWebDriver _webDriver;

    public Steps(IWebDriver webDriver)
    {
        _webDriver = webDriver;
    }
}

the BoDi container is already hooked up for you

Fran
  • 6,440
  • 1
  • 23
  • 35
  • Thanks for this. I managed to fix it thanks to Greg's comment. I was stupid and didn't change the name of the constructor – Liam Nagle Jan 21 '23 at 16:29