serenity-bdd / serenity-cucumber

Cucumber integration for the Serenity BDD Reporting library
Other
78 stars 74 forks source link

If a scenario fails due to an exception then for the next scenario WebDriver is not initialised(getDriver() is shown as Unitialised WebDriverFacade) #227

Open giddasriram opened 4 years ago

giddasriram commented 4 years ago

Hi I have written multiple scenarios is a feature file, when one of the scenarios fails due to an exception then for the next scenario webdriver is not instantiated/enabled. When I've set a break-point at getDriver() in PageObject then it is shown as "Uninitialised WebDriverFacade".

I've tried to set the Driver using the below ways but it still did not work. ThucydidesWebDriverSupport.getDriver() and ((getDriver())WebDriverFacade).getProxiedDriver().

My serrenity.properties file is as below. webdriver.driver=chrome webdriver.timeouts.implicitlywait=50000 webdriver.wait.for.timeout=5000 serenity.driver.capabilities=javascriptEnabled:true serenity.use.unique.browser=true restart.browser.each.scenario=true serenity.restart.browser.for.each=SCENARIO

Could you please point out where I am going wrong. This issue is driving me crazy. I really appreciate any help on this issue.

Thanks

wakaleo commented 4 years ago

That doesn’t sound normal behaviour - can you provide a sample project that reproduces this?

wakaleo commented 4 years ago

That doesn’t sound normal behaviour - can you provide a sample project that reproduces this?

giddasriram commented 4 years ago

Hi Thanks for the quick response, I've debugged further and found that the issue is happening because in the below method of WebDriverFacade.java, isEnabled is being returned as false because "aStepInTheCurrentTestHasFailed()" is being returned as false. I guess this is somehow retaining the failure from the previous scenario. I've given my runner class and serenity property files at the end. I've managed to fix this issue(please see the end of the comment) but not sure if it is a valid fix, please suggest otherwise.

WebDriverFacade public void get(final String url) { if (!isEnabled()) { return; } // openIgnoringHtmlUnitScriptErrors(url); getProxiedDriver().get(url); setTimeouts(); }

public boolean isEnabled() { return !StepEventBus.getEventBus().webdriverCallsAreSuspended(); }

public boolean webdriverCallsAreSuspended() {

    if (driverReenabled || inFixureMethod()) {
        return false;
    }
    if (softAssertsActive()) {
        return !webdriverSuspensions.isEmpty();
    }
    return currentTestIsSuspended() || aStepInTheCurrentTestHasFailed() || !webdriverSuspensions.isEmpty();
}

public boolean aStepInTheCurrentTestHasFailed() { return stepFailed; }

RunnerClass @RunWith(CucumberWithSerenity.class) @CucumberOptions(glue = "com.dar.api.tests", tags = {"@smoke"}, features = "src/test/resources/features", plugin = "json:target/report.json") public class TestRunner { }

Serenity.properties serenity.use.unique.browser=true restart.browser.each.scenario=true webdriver.driver=chrome webdriver.timeouts.implicitlywait=50000 webdriver.wait.for.timeout=5000 serenity.driver.capabilities=javascriptEnabled:true webdriver.chrome.driver=.\src\main\resources\drivers\windows\chromedriver.exe

I've tried to fix this using the below code and it worked. Could you please let me know if there is anything that is making serenity retain failures from the previous scenario to the next scenario as well.

if(!driverIsInstantiated()){ StepEventBus.getEventBus().clear(); getDriver().get(rStudioUrl); }else{ getDriver().get(rStudioUrl); }

wakaleo commented 4 years ago

aStepInTheCurrentTestHasFailed() is cleared at the start of each scenario - are you sure there isn't a step that is failing in your scenario each time?

giddasriram commented 4 years ago

Yes there are no failures before starting the scenario, In fact just for debugging purposes I've made sure I only have 1 step in each scenario and I was trying to open the browser in the method tagged with @Before, first launch worked fine but after a failure it did not work. @smoke @DR-Accounts-01 @DR_Account_Creation_01 Scenario: Create an IAS account through API calls And I verify the "accountId" is present under "accounts" table in XYZ

@smoke @DR_Link_Acc_ID_to_UK_Number_01 Scenario: Create_Customer_Account_AccountNumber_Link_Account_And_AccountNumber And I verify the following attributes present under "accounts" table in XYZ | accountId | | customerId | And I verify the "accountNumber" is present under "payment_devices" table in XYZ

wakaleo commented 4 years ago

Can you provide a sample project to reproduce the issue? Otherwise, you can try placing a breakpoint and inspecting StepEventBus.getEventBus().getBaseStepListener().latestTestOutcome().get().getFailingStep() or StepEventBus.getEventBus().getBaseStepListener().latestTestOutcome().get().getTestFailureCause() to see what the actual failure is

giddasriram commented 4 years ago

Hi Thank you for responding to my previous issue. I am working on a new issue i.e. I have a class variable of PaymentContext marked with @Shared in two different StepDef files. The paymentContext is getting populated and retaining values as long as the execution is in InboundPaymentEventsStepDefs file but once the execution moves to RStudioStepDefs paymentContext is being reset and all the values are reset to null.

@Log public class InboundPaymentEventsStepDefs {

@Shared
private PaymentContext paymentContext;

@Steps
private InboundPaymentEventsModule inboundPaymentEventsModule;

@Steps
private RStudioStepDefs rStudioStepDefs;

}

@Log public class RStudioStepDefs {

@Steps
private RStudioPage rStudioPage;

@Shared
private AccountContext accountContext;

@Shared
private CustomerContext customerContext;

@Shared
private PaymentContext paymentContext;

@Shared
private ProductContext productContext;

}

Is there a way to retain the values between two step def files.