added a line to the code, reworded title.
Source Link

How to implement context-awarenesspass the same webdriver instance between Cucumber tests?

 ScenarioContext scenarioContext = ScenarioContext.getInstanceOfScenarioContextClass();

 @Before
    public void setUp() {
        WebDriver driver = scenarioContext.getDriver();
        loginPage = new LoginPage(driver);
        PageFactory.initElements(driver, loginPage);
    }

    @Given("^user navigates to Login page$")
    public void userNavigatesToPage() {
        loginPage.open();
    }

    @When("^user logs in with '(.*)' username and '(.*)' password$")
    public void userLogsInWithUsername(String name, String password) {
        loginPage.userLogin(name,password,scenarioContext.getDriver());
    }
  ....Then
  etc.

How to implement context-awareness between Cucumber tests?

 @Before
    public void setUp() {
        WebDriver driver = scenarioContext.getDriver();
        loginPage = new LoginPage(driver);
        PageFactory.initElements(driver, loginPage);
    }

    @Given("^user navigates to Login page$")
    public void userNavigatesToPage() {
        loginPage.open();
    }

    @When("^user logs in with '(.*)' username and '(.*)' password$")
    public void userLogsInWithUsername(String name, String password) {
        loginPage.userLogin(name,password,scenarioContext.getDriver());
    }
  ....Then
  etc.

How to pass the same webdriver instance between Cucumber tests?

 ScenarioContext scenarioContext = ScenarioContext.getInstanceOfScenarioContextClass();

 @Before
    public void setUp() {
        WebDriver driver = scenarioContext.getDriver();
        loginPage = new LoginPage(driver);
        PageFactory.initElements(driver, loginPage);
    }

    @Given("^user navigates to Login page$")
    public void userNavigatesToPage() {
        loginPage.open();
    }

    @When("^user logs in with '(.*)' username and '(.*)' password$")
    public void userLogsInWithUsername(String name, String password) {
        loginPage.userLogin(name,password,scenarioContext.getDriver());
    }
  ....Then
  etc.
Source Link

How to implement context-awareness between Cucumber tests?

I have a series of steps in a Cucumber-automated test for a web-site. In some cases, I need to pass the Selenium webdriver instance, such that the test can use it to wait until certain elements on the page are visible, e.g.:

public void userLogin(String username, String password, WebDriver driver) {
    //wait until the element is visible
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(ExpectedConditions.visibilityOf(element));
    userName.sendKeys(username);
    continue_login.click();
    //...
}

I have seen two ways of getting it done:

  1. using the Singleton pattern
  2. without a Singleton

I. Singleton variant

public class ScenarioContext {
    // instance of singleton class
    private static ScenarioContext scenarioContext;
    private WebDriver driver;

    private ScenarioContext(){
        driver= new FirefoxDriver();
    }

    public static ScenarioContext getInstanceOfScenarioContextClass(){
        if (scenarioContext == null) {
            scenarioContext = new ScenarioContext();
        }
        return scenarioContext;
    }

    public WebDriver getDriver(){
        return driver;
    }
}

Steps Definitions:

 @Before
    public void setUp() {
        WebDriver driver = scenarioContext.getDriver();
        loginPage = new LoginPage(driver);
        PageFactory.initElements(driver, loginPage);
    }

    @Given("^user navigates to Login page$")
    public void userNavigatesToPage() {
        loginPage.open();
    }

    @When("^user logs in with '(.*)' username and '(.*)' password$")
    public void userLogsInWithUsername(String name, String password) {
        loginPage.userLogin(name,password,scenarioContext.getDriver());
    }
  ....Then
  etc.

II. Without singleton

@Before
    public void setUp() {
        driver = new FirefoxDriver();
        loginPage = new LoginPage(driver);
        PageFactory.initElements(driver, loginPage);
    }

    @Given("^user navigates to Login page$")
    public void userNavigatesToPage() {
        loginPage.open();
    }

    @When("^user logs in with '(.*)' username and '(.*)' password$")
    public void userLogsInWithUsername(String name, String password) {
        loginPage.userLogin(name,password, driver);
    }

It boils down to these:

  • loginPage.userLogin(name,password, scenarioContext.getDriver()) plus an extra class
  • loginPage.userLogin(name,password, driver)

The first form, which uses the Singleton pattern, requires more writing. The latter seems more concise.

What is the best practice? And what is the added value of the Singleton approach, that some forums advocate?