Cucumber Java (Maven) WebdriverManager (Bonigarcia) 无法从属性中获取 URL

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

大家好:我正在尝试 运行 Cucumber with Java (With Maven) and WebDriverManager (Bonigarcia)

这是我项目的树:

    ├── 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

我的驱动程序class(它就像 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");
    }
}

我的 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();
        }
    }
}

这是我的 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();
        }
    }
}

这是我的步骤定义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");
    }

}

这是我的Runner文件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 {
}

下面是我的特征文件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

我有我的配置文件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

不要忘记我的 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>

这里的问题是 2:

1.- 我在我的配置文件 (default.properties) 中写了选项 firefox 在浏览器中,但导航器正在打开 Chrome.

2.- 几秒钟后,浏览器崩溃,控制台显示下一条错误消息:

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

拜托,有人可以帮我解决这两个问题吗?

首先,有很多无用的信息。 另外,我会邀请您看一下您的这部分代码:

你的Driver.class:

driver = DriverFactory.getDriver();

您第一次尝试初始化它以供进一步使用。那么:

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

也就是说,如果没有活动的浏览器,请联系我 Chrome。 此外,在您的 DriveFactory.class 开关中:

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

所以你说默认接我 Chrome 这是 Chrome 调用而不是 FF 的可能原因。

关于 NPE, 我没有在您的代码中找到有关如何定义 .properties 文件路径的行。顺便说一句,这条线应该如何工作?

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

我建议您使用属性 class 来定义它。像下面这样。

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

希望这会有所帮助。

我做了下一个:

protected static WebDriver initializeDriver() throws IOException {

        //Declares a variable for reading properties from a resource bundle file (*.properties)
        Properties p = new Properties();

        //Always the Absolute path here.
        FileInputStream f = new FileInputStream("/src/main/resources/data/config.properties");
        p.load(f);

        //The String inside the config.properties
        String browser = p.getProperty("browser");

if(browser.equals("chrome")) {
            WebDriverManager.chromedriver().setup();
            driver = new ChromeDriver();

        } else if(browser.equals("firefox")) {
            WebDriverManager.firefoxdriver().setup();
            driver = new FirefoxDriver();

        } else if(browser.equals("ie")) {
                WebDriverManager.iedriver().setup();
                driver = new InternetExplorerDriver();

        } else if(browser.equals("edge")) {
            WebDriverManager.edgedriver().setup();
            driver = new EdgeDriver();

        } else {
            System.setProperty("webdriver.safari.driver","/usr/bin/safaridriver");
            driver = new SafariDriver();
        }
        return driver;

并且,在另一个 class 中,我写了下一个:

    driver = DriverClass.initializeDriver();