Search code examples
javacucumbercucumber-jvmcucumber-java

Implementation of shared state among cucumber steps in java


I have two-page objects called OrderSelection and OrderDetails. In addition, I have SharedState class and OrderSelectionStepDef and OrderDetailsStepDef. I declared two variables for OrderSelection and OrderDetails in SharedState. However, they are not initialized in the constructor of SharedState. In OrderSelectionStepDef and OrderDetailsStepDef classes, I declared their constructors and pass SharedState object.

public OrderSelectionStepDef(SharedState sharedState) {
  this.sharedState = sharedState;
}    
public OrderDetailsStepDef(SharedState sharedState) {
  this.sharedState = sharedState;
}

When I call sharedState.orderDetails within OrderDetailsStepDef or OrderSelectionStepDef a NullPointerException was thrown.

Then, I initialized OrderSelection and OrderDetails class objects in SharedState constructor. Then the issue was solved. But is this implementation ok with cucumber pico container concept?.


Solution

  • Step 1. OrderSelectionStepDef & OrderDetailsStepDef would look like below (please change name as per your implementation)

    /**
     * Step Definition implementation class for Cucumber Steps defined in Feature file
     */
    
    public class HomePageSteps extends BaseSteps {
    
        TestContext testContext;
    
        public HomePageSteps(TestContext context) {
            testContext = context;
        }
    
        @When("^User is on Brand Home Page (.+)$")
        public void user_is_on_Brand_Home_Page(String siteName) throws InterruptedException {
            homePage = new HomePage().launchBrandSite(siteName);
            testContext.scenarioContext.setContext(Context.HOMEPAGE, homePage);
        }
    
        @Then("^Clicking on Sign In link shall take user to Sign In Page$")
        public void clicking_on_Sign_In_link_shall_take_user_to_Sign_In_Page() {
            homePage = (HomePage) testContext.scenarioContext.getContext(Context.HOMEPAGE);
            signInPage = homePage.ecommSignInPageNavigation();
            testContext.scenarioContext.setContext(Context.SIGNINPAGE, signInPage);
        }
    

    For your reference

    public class BaseSteps {
    
        protected HomePage homePage;
        protected PLPPage plpPage;
        protected PDPPage pdpPage;
        protected ShoppingBagPage shoppingBagPage;
        protected ShippingPage shippingPage;
    
    More implementation goes here.....  
    
    }
    

    Step 2. Please add below 2 Classes under your framework -

    First, Java file name - ScenarioContext.java

    public class ScenarioContext {
    
        private  Map<String, Object> scenarioContext;
    
        public ScenarioContext(){
            scenarioContext = new HashMap<String, Object>();
        }
    
        public void setContext(Context key, Object value) {
            scenarioContext.put(key.toString(), value);
        }
    
        public Object getContext(Context key){
            return scenarioContext.get(key.toString());
        }
    
        public Boolean isContains(Context key){
            return scenarioContext.containsKey(key.toString());
        }
    }
    

    Second, Java file name - TestContext.java

    public class TestContext {
    
        public ScenarioContext scenarioContext;
    
        public TestContext(){
            scenarioContext = new ScenarioContext();
        }
    
        public ScenarioContext getScenarioContext() {
            return scenarioContext;
        }
    }
    

    Step 3. POM Dependency - picocontainer shall be as per your cucumber version

       <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-picocontainer</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
    

    Hope this helps.