środa, 13 lutego 2019

Cucumber-java with Cucumber Spring, Selenide and Selenium WebDriver

Cucumber tests for web automated testing might be run with default selenide configuration- there is no need to configure custom web driver manager. 

This post is not for you, if you do not need custom web driver. Stay with selenide configuration (it also might be customised, see post: "Cucumber-java with custom Selenide configuration").

If you want to use Selenium WebDriver to manage browsers in tests project, this post is right for you.

Template

Whole template for cucmber-java-webdriver-manager you will find here: 

Instruction

There is an instruction attached to project, how to work with template, so here I do not write about setting up cucumber template. Read README.md file.

Test runner

Framework test runner is placed in CucumberRunner class:

@RunWith(Cucumber.class)
@CucumberOptions(
        glue={"cucumber.glue.hooks", 
              "cucumber.glue.steps", 
              "com.foreach.cuke"},
        features="src/test/resources/features",
        plugin={"pretty", "html:target/html"},
        monochrome=true)
@ContextConfiguration
@ComponentScan("classpath:cucumber.glue")
public class CucumberRunner {
}

In annotation @CucumberOptions, in 'glue' option there is 'com.foreach.cuke' phrase. It is necessary, when you run tests with Cucumber-java runner configuration. Edit your 'Run' configuration in IntelliJ: you should remove line 'cucumber.api.spring ' in 'Glue' row and paste 'com.foreach.cuke' instead (it prevents Spring TransactionDefinition error when tests are running). 
Both annotations: @ContextConfiguration and @ComponentScan are related to dependency injection with Spring.


Spring

As dependency injection template is using cucumber-spring library (with spring-context and spring-test libraries), so in class above you see annotations: @ContextConfiguration and @ComponentScan. Also in project there are another annotations, which are necessary for Spring and dependency injection: @Component and @Autowired (used in steps classes, page object classes and all classes, where dependency injection is needed).

@Autowired annotation used with field/ properties replaces common dependency injection:

@Autowired 
private NavigationPageObjects navigationPageObjects;

Common dependency injection looks like:

private NavigationPageObjects navigationPageObjects;
public NavigationPageSteps(NavigationPageObjects navigationPageObjects) {
    this.navigationPageObjects = navigationPageObjects;
}

With Spring dependency injection ends with two annotations, in this case one for class (@Component), second for field/properties (@Autowired).

Selenium WebDriver

Browsers management is dealed with WebDriverManager class. Simple switch/ case statement in method 'getWebDriver()' manages type of browser, which is chosen to automated testing:

 @PostConstruct
    public WebDriver getWebDriver(){
        String currentWebDriver = System.getProperty("browser", "");
        switch(currentWebDriver) {
            case ("chrome"):
                System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
                webDriver = new ChromeDriver();
                break;
            case ("firefox"):
                System.setProperty("webdriver.gecko.driver", "geckodriver.exe");
                FirefoxOptions firefoxOptions = new FirefoxOptions();
                firefoxOptions.setCapability("marionette", true);
                webDriver = new FirefoxDriver(firefoxOptions);
                break;
            case ("chromeHeadless"):
                System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
                ChromeOptions chromeHeadless = new ChromeOptions();
                chromeHeadless.setHeadless(true);
                webDriver = new ChromeDriver(chromeHeadless);
                break;
            case ("iexplorer"):
                System.setProperty("webdriver.ie.driver", "IEDriverServer.exe");
                DesiredCapabilities capabilitiesIE = DesiredCapabilities.internetExplorer();
 capabilitiesIE.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
                webDriver = new InternetExplorerDriver(capabilitiesIE);
                break;
            case ("edge"):
                System.setProperty("webdriver.edge.driver", "MicrosoftWebDriver.exe");
                webDriver = new EdgeDriver();
                break;
            case ("opera"):
                System.setProperty("webdriver.opera.driver", "operadriver.exe");
                webDriver = new OperaDriver();
                break;
            default:
                System.getProperty("browser", "chrome");
                System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
                webDriver = new ChromeDriver();
                break;
        }
        return webDriver;
    }

With @PostConstruct annotation Selenium WebDriver is initialised (with method 'getWebDriver()'). Default browser is sat to chrome, different browser is pointed by '-Dbrowser=' parameter before tests start running.

@PreDestroy
public void closeSession(){
webDriver.manage().deleteAllCookies();
webDriver.close();
webDriver.quit();
}

With @PreDestroy annotation Selenium WebDriver ends related processes.

Steps

Steps from scenarios are resolved in  NavigationPageSteps class.

public class NavigationPageSteps implements En {

    @Autowired
    private NavigationPageObjects navigationPageObjects;
    @Autowired
    private NavigationPageStepsAssertions assertions;

    @Given("I go to {string} page")
    public void iGoToPage(String urlName){
        navigationPageObjects.getPage(urlName);
   }

    @Then("I should be on {string} page")
    public void iShouldBeOnPage(String name){
        String currentPage = navigationPageObjects.getCurrentUrl();
        assertions.assertPageIsCorrect(currentPage, name);
    }
}

In steps class there are invoked only method from page objects classes (or assertions classes).

Selenide

Template is prepared for using Selenide library. In page object classes simply create methods and use Selenide to find elements or take actions. More about Selenide: https://selenide.org/.

Brak komentarzy:

Prześlij komentarz