Thread-safe parallel execution in specflow+Nunit facing difficulties
My Hooks class I provide here
using AventStack.ExtentReports;
using AventStack.ExtentReports.Gherkin.Model;
using BoDi;
using SpecFlowFrameWork.Utility;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Edge;
using OpenQA.Selenium.Firefox;
using TechTalk.SpecFlow;
using SpecFlowFrameWork.Pages;
using OpenQA.Selenium.Support.UI;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using SpecFlowFrameWork.Driver;
using FluentAssertions;
namespace FinanceModule.Hooks
{
[Binding]
public class Hooks : ExtentReport
{
private static readonly ThreadLocal<IWebDriver> ThreadDriver = new ThreadLocal<IWebDriver>(() => new ChromeDriver());
// public static IWebDriver driver;
public static DateTime Time = DateTime.Now;
public static String Filename = "Screenshot_" + Time.ToString("h_mm_ss") + ".png";
public static string LoginCredintial_Path = GetDataParser().TestData_Path("LoginCredentialsTD");
public static string Test_Url = GetDataParser().TestData("Test_Url", LoginCredintial_Path);
private readonly ScenarioContext _scenarioContext;
private readonly IObjectContainer _container;
public Hooks(IObjectContainer container)
{
_container = container;
}
[BeforeTestRun]
public static void BeforeTestRun()
{
Console.WriteLine("Running before test run...");
ExtentReportInit();
}
[AfterTestRun]
public static void AfterTestRun()
{
Console.WriteLine("Running after test run...");
// ExtentReportTearDown();
Instance.Flush();
}
[BeforeFeature()]
public static void BeforeFeature(FeatureContext featureContext)
{
Console.WriteLine("Running before feature...");
//_feature = _extentReports.Value.CreateTest<Feature>(featureContext.FeatureInfo.Title);
_feature = ExtentReport.Instance.CreateTest<Feature>(featureContext.FeatureInfo.Title);
}
[BeforeScenario()]
public void FirstBeforeScenario(ScenarioContext scenarioContext)
{
IWebDriver Driver = ThreadDriver.Value;
Driver.Manage().Window.Maximize();
_container.RegisterInstanceAs<IWebDriver>(Driver);
Driver.Url = Test_Url;
Thread.Sleep(5000);
_scenario = _feature.CreateNode<Scenario>(scenarioContext.ScenarioInfo.Title);
}
[AfterScenario("@BeforeFeatureDontLaunch")]
public void AfterScenario(IWebDriver driver)
{
driver = _container.Resolve<IWebDriver>();
if (driver != null)
{
driver.Quit();
}
}
[AfterFeature("@BeforeFeatureDontLaunch")]
public static void AfterFeature(IWebDriver driver)
{
Console.WriteLine("Running after feature...");
}
[AfterStep]
public void AfterStep(ScenarioContext scenarioContext)
{
Console.WriteLine("Running after step....");
string stepType = scenarioContext.StepContext.StepInfo.StepDefinitionType.ToString();
string stepName = scenarioContext.StepContext.StepInfo.Text;
IWebDriver driver = _container.Resolve<IWebDriver>();
//When scenario passed
if (scenarioContext.TestError == null)
{
if (stepType == "Given")
{
_scenario.CreateNode<Given>(stepName).Pass(scenarioContext.StepContext.StepInfo.Text.ToString(), addScreenshot(driver, Filename));
}
else if (stepType == "When")
{
_scenario.CreateNode<When>(stepName).Pass(scenarioContext.StepContext.StepInfo.Text.ToString(), addScreenshot(driver, Filename));
}
else if (stepType == "Then")
{
_scenario.CreateNode<Then>(stepName).Pass(scenarioContext.StepContext.StepInfo.Text.ToString(), addScreenshot(driver, Filename));
}
else if (stepType == "And")
{
_scenario.CreateNode<And>(stepName).Pass(scenarioContext.StepContext.StepInfo.Text.ToString(), addScreenshot(driver, Filename));
}
}
//When scenario fails
if (scenarioContext.TestError != null)
{
if (stepType == "Given")
{
_scenario.CreateNode<Given>(stepName).Fail(scenarioContext.TestError.Message, addScreenshot(driver, Filename));
}
else if (stepType == "When")
{
_scenario.CreateNode<When>(stepName).Fail(scenarioContext.TestError.Message, addScreenshot(driver, Filename));
}
else if (stepType == "Then")
{
_scenario.CreateNode<Then>(stepName).Fail(scenarioContext.TestError.Message, addScreenshot(driver, Filename));
}
else if (stepType == "And")
{
_scenario.CreateNode<And>(stepName).Fail(scenarioContext.TestError.Message, addScreenshot(driver, Filename));
}
}
}
// public IWebDriver driver => Driver.Value;
}
}
In that, I use LocalThread<IwebDriver> and IobjectContainer also to make driver thread-safe
For the extent report I have implemented the suggested solution as in the code. in that, I have used Localstatic and threadLocal pattern
by using this procedure I am unable to make the specflow parallel execution thread-safe.
report generated improper
Please suggest solution
Please sign in to leave a comment.
Comments
0 comments