Cucumber-Appium - Where to store Hooks if initialising driver in @Before

JordiLaForge :

I'll try to explain how I've built this, I imagine something obvious may jump out.

I'm relatively new to this but am building a cucumber-appium framework and am running into some trouble. Currently, I initialise my Appium driver in my @Before hook which is in a GlobalHooks class which contains all Hooks. I have altered the hook so part of it only runs at the start of the test run as Cucumber doesn't support global hooks and I don't see why I should initialise the driver before every test (I'm using Junit so cannot take advantage of TestNG's @BeforeSuite feature).

To take advantage of Appium's parallel sessions, I now want to make my driver (declared in a GlobalHooks class and defined in the @Before method in that class) non-static and it's presenting issues across the suite.

Is it wise to define my driver in a Hook like this if I want my Page Classes to use this driver? Or does anyone have any advice on how to initialise non-static drivers so they can be used to run parallel Appium sessions?

This is probably more of a Java question than about Cucumber or Appium.

Grasshopper :

This is a stripped down version of using selenium drivers in parallel. It should be similar to adopt to appium driver. This uses pico-container for object creation and sharing across a scenario. Need to add cucumber-picocontainer dependency.

DriverFactory stores all the drivers in a ThreadLocal variable drivers.

public final class DriverFactory {

    private static ThreadLocal<WebDriver> drivers = new ThreadLocal<>();
    //To quit the drivers and browsers at the end only. 
    private static List<WebDriver> storedDrivers = new ArrayList<>();

    static {
        Runtime.getRuntime().addShutdownHook(new Thread(){
            public void run(){
                storedDrivers.stream().forEach(WebDriver::quit);
            }
          });
    }

    private DriverFactory() {}

    public static WebDriver getDriver() {
        return drivers.get();
    }

    public static void addDriver(WebDriver driver) {
        storedDrivers.add(driver);
        drivers.set(driver);
    }

    public static void removeDriver() {
        storedDrivers.remove(drivers.get());
        drivers.remove();
    }   
}

Exists solely for allowing pico-container to create the required driver. Checks if driver already exists for thread to reuse. To avoid this case you can look at extending ThreadLocal class and setting up the initialValue() method.

public class SharedDriver {
    public SharedDriver() {
        if (DriverFactory.getDriver() == null) {
        System.setProperty("webdriver.chrome.driver", "path/to/chromedriver.exe");
        DriverFactory.addDriver(new ChromeDriver());
    }
    }   
}

public class GoogleHomePO extends LoadableComponent<GoogleHomePO>{

    @FindBy(name="q")
    private WebElement searchTextBox;

    public GoogleHomePO() {
        DriverFactory.getDriver().get("https://www.google.com/");
        PageFactory.initElements(DriverFactory.getDriver(), this);
    }

    public void enterSearch(String search) {
        searchTextBox.sendKeys(search);
    }
}

The SharedDriver class needs to be added to any one step definition constructor in the project. As cucumber initializes all the step and hook classes for each scenario picocontainer will instantiate the driver object if required and store it in the DriverFactory.

public class StepDefinition {

    private GoogleHomePO gmPO;

    public StepDefinition(SharedDriver driver, GoogleHomePO gmPO) {
        this.gmPO = gmPO;
    }

    @Given("Go to google page")
    public void given() {
        gmPO.get();
    }

    @When("Enter search {string}")
    public void when(String search) {
        gmPO.enterSearch(search);
    }    
}

Feature file 1

Feature: 

  Scenario: First
    Given Go to google page
    When Enter search "From Feature One"

  Scenario: First Again
    Given Go to google page
    When Enter search "From Feature One Again Again"

Feature file 2

Feature:

  Scenario: Second
    Given Go to google page
    When Enter search "From Feature Two"

POM settings

<plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>3.0.0-M3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                        </goals>
                        <configuration>
                            <includes>
                                <include>**/*Runner.java</include>
                            </includes>

                            <parallel>methods</parallel>
                            <useUnlimitedThreads>true</useUnlimitedThreads>

                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=158865&siteId=1