2

I created a xunit project and added specflow with Gherkin and selenium web drivers to the project. I've following StepDefinition file,

[Binding]
public class MyPageStepDefinition
{
    private readonly UserContext _userContext;
    private readonly ConfigurationDriver cd;

    public MyPageStepDefinition(UserContext userContext)
    {
        _userContext = userContext;
        cd = new ConfigurationDriver();
    }

    // Many Given, when and Then
}

I've UserContext file as follows,

public class UserContext
{
    public string email { get; set; }
}

I'm using IObjectContainer to get help with ContextInjection in specflow as follows,

[Binding]
public class BrowserDriver
{
    
    private readonly IObjectContainer _objectContainer;
    // BrowserType is enum
    public Dictionary<BrowserType, IWebDriver> _drivers;
    
    public BrowserDriver(IObjectContainer objectContainer) {
        _objectContainer = objectContainer;
        _drivers = new Dictionary<BrowserType, IWebDriver>();
    }

    [BeforeScenario]
    public void BeforeScenario()
    {
        _objectContainer.RegisterInstanceAs(_drivers);
    }

}

My browser initialization code,

 public IWebDriver InitBrowser(BrowserType browser)
{
    IWebDriver driver = null;
    switch (browser)
    {
        case BrowserType.Chrome:
            ChromeOptions chromeOptions = new ChromeOptions();
            if (!Debugger.IsAttached)
            {
                chromeOptions.AddArgument("headless");
                chromeOptions.AddArguments("disable-gpu");
                chromeOptions.AddArguments("window-size=1900,1280");
                chromeOptions.AddArguments("--no-sandbox");
                chromeOptions.AddArguments("--ignore-certificate-errors");
                chromeOptions.AddArguments("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(chromeOptions);
            break;
    }



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

    return driver;
}

I call above method as follows,

SupportedBrowserList().ForEach(b => _drivers.Add(b, _testContext.InitBrowser(b)));


public List<BrowserType> SupportedBrowserList()
{
    return new List<BrowserType>
    {
        BrowserType.Chrome,
    };
}

and I use _drivers as follows,

GetCurrentDriverList(_drivers).ForEach(d =>
{
   // Do something on webpage, like d.FindElement(..);
});


public List<IWebDriver> GetCurrentDriverList(Dictionary<BrowserType, IWebDriver> drivers)
{
  return new List<IWebDriver>(drivers.Values);
}

I've 2 features files to handle 2 flows. Most of the steps are common so they both call MyPageStepDefinition constructor. When I run the feature files parallelly (default behavior of xunit) then one or the other test case fail, saying the email is not matching. I was able to debug and understand, that the email of one test is going in another. Looks like there is some race condition in Context Injection in specflow in parallel execution.

To validate my hypothesis, I made the test run sequentially using xunit.runner.json file with following configuration,

{
    "parallelizeTestCollections": false
}

and the code worked flawlessly. Now, if I run again in parallel it fails. It confirmed my hypothesis that specflow+xunit in parallel run is causing some issues. I'm pretty sure someone must have faced similar issue and fixed it, but I can't seem to figure it out. Can someone please help me in this? And How can I fix this?

Note: I've made the file simple, the UserContext has more data fields. None of the fields are static in UserContext.

Nandini
  • 21
  • 4
  • Can you [edit] your question to include the web driver initialization code? I suspect that is the root cause, but I cannot confirm this without the code. – Greg Burghardt Jun 18 '21 at 17:02
  • @GregBurghardt I've added the initialization code. It uses `ForEach` to open the browser. But as I'm using chrome to start with, it will just start one browser at a time. – Nandini Jun 21 '21 at 10:30

0 Answers0