javamavenselenium-webdrivercucumberwebdrivermanager-java

Cucumber Java (Maven) WebdriverManager (Bonigarcia) Not able to get URL from properties


Hi everybody: I'm trying to run Cucumber with Java (With Maven) and WebDriverManager (Bonigarcia)

This is the tree of my project:

    ├── maven_selenium_cucumber.iml
├── pom.xml
├── src
│   ├── main
│   │   ├── java
│   │   │   ├── common
│   │   │   │   └── BasePage.java
│   │   │   ├── pages
│   │   │   │   └── Page_First.java
│   │   │   └── util
│   │   │       └── driver
│   │   │           ├── Driver.java
│   │   │           └── DriverFactory.java
│   │   └── resources
│   │       ├── default.properties
│   │       └── log4j.properties
│   └── test
│       └── java
│           ├── features
│           │   └── first.feature
│           ├── runner
│           │   └── TestRunner.java
│           └── steps
│               └── Step_First.java
└── target

My Driver class (It acts like Hooks)

package util.driver;

import common.BasePage;
import cucumber.api.java.After;
import cucumber.api.java.Before;
import org.openqa.selenium.WebDriver;

import java.util.concurrent.TimeUnit;

public class Driver extends BasePage {


    public static WebDriver driver;


    @Before
    public void initializeDriver(){

        driver = DriverFactory.getDriver();
        driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
        driver.manage().window().maximize();

        if (driver == null) {
            log.info("Driver did not initialize correctly");
        }
    }


    @After
    public void closeDriver(){


        driver.quit();
        log.info("Driver closed");
    }
}

My DriverFactory class:

package util.driver;

import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.firefox.FirefoxBinary;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.safari.SafariDriver;


public class DriverFactory {

    private static final String BROWSER = System.getenv("browser");
    private static final String WINDOW_WIDTH = System.getenv("window_width");
    private static final String WINDOW_HEIGHT = System.getenv("window_height");
    private static final String CHROME = "chrome";
    private static final String HEADLESS_CHROME = "headless-chrome";
    private static final String FIREFOX = "firefox";
    private static final String HEADLESS_FIREFOX = "headless-firefox";
    private static final String IE = "ie";
    private static final String EDGE = "edge";
    private static final String SAFARI = "safari";
    private static final String WINDOW_SIZE = "--window-size="+WINDOW_WIDTH+"x"+WINDOW_HEIGHT;

    private static WebDriver driver;


    public static WebDriver getDriver() {
        if (BROWSER == null) {
            WebDriverManager.chromedriver().setup();
            return new ChromeDriver();
        }
        switch (BROWSER.toLowerCase())
        {
            case CHROME:
                WebDriverManager.chromedriver().setup();
                return new ChromeDriver();
            case HEADLESS_CHROME:
                ChromeOptions chromeOptions = new ChromeOptions();
                chromeOptions.addArguments("--headless");
                chromeOptions.addArguments("start-maximized"); 
                chromeOptions.addArguments("disable-infobars"); 
                chromeOptions.addArguments("--disable-extensions"); 
                chromeOptions.addArguments("--disable-gpu"); 
                chromeOptions.addArguments("--disable-dev-shm-usage");
                chromeOptions.addArguments("--no-sandbox");
                return new ChromeDriver(chromeOptions);
            case FIREFOX:
                WebDriverManager.firefoxdriver().setup();
                return new FirefoxDriver();
            case HEADLESS_FIREFOX:
                FirefoxBinary firefoxBinary = new FirefoxBinary();
                firefoxBinary.addCommandLineOptions("--headless");
                firefoxBinary.addCommandLineOptions(WINDOW_SIZE);
                FirefoxOptions firefoxOptions = new FirefoxOptions();
                firefoxOptions.setBinary(firefoxBinary);
                WebDriverManager.firefoxdriver().setup();
                return new FirefoxDriver(firefoxOptions);
            case IE:
                WebDriverManager.iedriver().setup();
                return new InternetExplorerDriver();
            case EDGE:
                WebDriverManager.edgedriver().setup();
                return new EdgeDriver();
            case SAFARI:
                driver = new SafariDriver();
                return new SafariDriver();
            default:
                WebDriverManager.chromedriver().setup();
                return new ChromeDriver();
        }
    }
}

Here is my BasePage:

package common;

import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import util.driver.Driver;
import java.util.logging.Logger;


public abstract class BasePage {

    protected static String BASE_URL = System.getenv("base_URL");
    protected static final Logger log = Logger.getLogger(BasePage.class.getName());
    private WebDriver driver = Driver.driver;


    public BasePage() {

        PageFactory.initElements(driver, this);

    }

    protected void waitForElementClickable(WebElement element){
        WebDriverWait wait = new WebDriverWait(driver, 30);
        wait.until(ExpectedConditions.elementToBeClickable(element));
    }

    protected void waitForElementVisible(WebElement element){
        WebDriverWait wait = new WebDriverWait(driver, 15);
        wait.until(ExpectedConditions.visibilityOf(element));
    }

    protected void setTextAs(WebElement element, String text){
        waitForElementClickable(element);
        element.sendKeys(text);
    }

    protected void clearElement(WebElement element){
        waitForElementClickable(element);
        element.clear();
    }

    protected void clickElement(WebElement element){
        waitForElementClickable(element);
        element.click();
    }

    protected void clickElementByJavascriptExecutor(String xpath){
        WebElement element=driver.findElement(By.xpath(xpath));
        JavascriptExecutor ex=(JavascriptExecutor)driver;
        ex.executeScript("arguments[0].click()", element);
    }

    protected void clickLink(WebElement element){
        waitForElementVisible(element);
        element.click();
    }

    protected String getText(WebElement element){
        waitForElementVisible(element);
        return element.getText();
    }

    protected void freeze(int seconds) {
        try {
            Thread.sleep(seconds * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

This is my stepdefinition class Step_First:

package steps;

import common.BasePage;
import cucumber.api.java.en.Given;
import cucumber.api.java.en.Then;
import cucumber.api.java.en.When;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import pages.Page_First;
import util.driver.Driver;

import java.io.IOException;


public class Step_First extends BasePage {

    private WebDriver driver = Driver.driver;
    private Page_First page_first = PageFactory.initElements(driver, Page_First.class);


    @Given("I go to Google")
    public void I_go_to_Googl () {

        page_first.navigateToBrowser();
    }

    @When("I query for {string} cucumber spring selenium")
    public void I_query_for_cucumber_spring_selenium (String search) throws IOException {

        page_first.search(search);
    }

    @When("click search")
    public void click_search(){

        page_first.enterButton();
    }

    @Then("google page title should become the first page")
    public void google_page_title_should_become_the_first_page() {

        log.info("All OK");
    }

}

This is my Runner file TestRunner

package runner;

import org.junit.runner.RunWith;
import cucumber.api.CucumberOptions;
import cucumber.api.junit.Cucumber;

@RunWith(Cucumber.class)
@CucumberOptions(
        features = "src/test/java/features",
        glue= {"steps"},
        monochrome = true,
        plugin = {"pretty", "html:TestReports", "json:TestReports/cucumber.json", "junit:TestReports/cucumber.xml"}
)

public class TestRunner {
}

Below, my feature file fist.feature

Feature: Navigation Test

  Scenario: Search google.com to verify google search is working

    Given I go to Google
    When I query for "<search>" cucumber spring selenium
    And click search
    Then google page title should become the first page

I have my config file default.properties

# default.properties
# properties set here will be available to the test execution as environment variables

# Browser
browser = firefox

# Base URL
base_URL = https://www.google.com

# Search
search = cucumber selenium

And don't foget about my POM:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>automation</groupId>
    <artifactId>maven_selenium_cucumber</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.version>3.7.0</maven.compiler.version>
        <cucumber.version>3.0.2</cucumber.version>
        <selenium.version>3.12.0</selenium.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-jvm-deps</artifactId>
            <version>1.0.6</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-core</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-java8 -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-java8</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.cucumber/cucumber-picocontainer -->
        <dependency>
            <groupId>io.cucumber</groupId>
            <artifactId>cucumber-picocontainer</artifactId>
            <version>${cucumber.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
        <dependency>
            <groupId>io.github.bonigarcia</groupId>
            <artifactId>webdrivermanager</artifactId>
            <version>3.7.1</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

The issues here are 2:

1.- I wrote in my config file (default.properties) the option firefox in browser, but the navigator is opening Chrome.

2.- After some seconds, the browser crashes and console displays the next error message:

java.lang.NullPointerException: null value in entry: url=null
    at com.google.common.collect.CollectPreconditions.checkEntryNotNull(CollectPreconditions.java:32)
    at com.google.common.collect.SingletonImmutableBiMap.<init>(SingletonImmutableBiMap.java:42)
    at com.google.common.collect.ImmutableBiMap.of(ImmutableBiMap.java:70)
    at com.google.common.collect.ImmutableMap.of(ImmutableMap.java:123)
    at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:271)
    at pages.Page_First.navigateToBrowser(Page_First.java:37)
    at steps.Step_First.I_go_to_Google(Step_First.java:24)
    at ✽.I go to Google (/Users/rodrigo.g/Documents/automation_projects/maven_selenium_cucumber/src/test/java/features/first.feature:8)


Skipped step

Skipped step

Skipped step
Feb 21, 2020 7:18:03 PM util.driver.Driver closeDriver
INFO: $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ Finish of Test Execution $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
Feb 21, 2020 7:18:03 PM util.driver.Driver closeDriver
INFO: Driver closed

Failed scenarios:
/Users/rodrigo.g/Documents/automation_projects/maven_selenium_cucumber/src/test/java/features/first.feature:6 # Search google.com to verify google search is working

1 Scenarios (1 failed)
4 Steps (1 failed, 3 skipped)
0m2.833s

java.lang.NullPointerException: null value in entry: url=null
    at com.google.common.collect.CollectPreconditions.checkEntryNotNull(CollectPreconditions.java:32)
    at com.google.common.collect.SingletonImmutableBiMap.<init>(SingletonImmutableBiMap.java:42)
    at com.google.common.collect.ImmutableBiMap.of(ImmutableBiMap.java:70)
    at com.google.common.collect.ImmutableMap.of(ImmutableMap.java:123)
    at org.openqa.selenium.remote.RemoteWebDriver.get(RemoteWebDriver.java:271)
    at pages.Page_First.navigateToBrowser(Page_First.java:37)
    at steps.Step_First.I_go_to_Google(Step_First.java:24)
    at ✽.I go to Google (/Users/rodrigo.g/Documents/automation_projects/maven_selenium_cucumber/src/test/java/features/first.feature:8)


Process finished with exit code 1

Please, somebody could help me with these 2 issues?


Solution

  • Firstly, there is a lot of useless info. Also, I would invite you to take a look on this part of your code:

    Your Driver.class:

    driver = DriverFactory.getDriver();
    

    You trying to initialize it for the first time for further using. Then:

    if (BROWSER == null) {
                WebDriverManager.chromedriver().setup();
                return new ChromeDriver();
            }
    

    So you're saying get me Chrome if there is no active browser. Also, in your DriveFactory.class in switch:

    default:
            WebDriverManager.chromedriver().setup();
            return new ChromeDriver();
    

    So you're saying get me Chrome by default That's the probable reason of Chrome invocation instead of FF.

    Regarding NPE, I didn't find the line in your code on how you define the path to your .properties file. BTW, how this line should work?

    protected static String BASE_URL = System.getenv("base_URL");
    

    I would recommend you to use the Properties class to define it. Smth like this below.

    Properties properties = new Properties();
      properties.load(new FileInputStream("yourPropertiesFilePath"));
      String browserName = properties.getProperty("base_URL");
    

    Hope this will help.