5

I am trying to get my head around spring boot and I am having some issues trying to integrate selenium into my spring boot application. I am trying to achieve a simple web page, which has a input box and button. The input box will contain a URL and the button will then launch a selenium browser navigating to that URL entered.

I currently have a simple spring boot application consisting of the following:

index.html

Contains an input form (user types URL here) which is passed to myController.

myController.java

@Controller
public class myController {

    @Autowired
    private WebDriver driver;

    ....
}   

pom.xml

Contains selenium..

    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>3.4.0</version>
    </dependency>   

My error when I run my project:

 APPLICATION FAILED TO START


 Description:

 Field driver in com.project.myController required a bean of type 'org.openqa.selenium.WebDriver' that could not be found.


 Action:

 Consider defining a bean of type 'org.openqa.selenium.WebDriver' in your configuration.

I am trying to create an instance of Selenium WebDriver so that I can use it whenever I need to. I will only ever need it in this controller, so I declared it here. What am I missing? Any help will be appreciated. Thank you in advance.

user3054735
  • 117
  • 1
  • 2
  • 8

2 Answers2

10

You need to have an instance of WebDriver, e.g.:

@Bean
public WebDriver webDriver() {
    return new FirefoxDriver();
    //OR return new ChromeDriver();
}

in one of your configuration classes. That would be anything annotated with @Configuration or an annotation which includes this; in the most basic Spring Boot application (as used in Spring Boot examples), this would probably be something like this:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    // Your beans go here

}

because @SpringBootApplication is annotated with @SpringBootConfiguration which is annotated with @Configuration.

Ravindra Gullapalli
  • 9,049
  • 3
  • 48
  • 70
Danny Yeshurun
  • 407
  • 6
  • 10
  • I do agree. You have to create the bean yourself. Have a look here http://www.seleniumhq.org/docs/03_webdriver.jsp – kimy82 Jun 27 '17 at 13:34
  • Excellent answer, thank you. However 'return new WebDriver()' did not work, however specifying 'new FirefoxDriver()' did work. Also out of interest, where would you normally declare your beans (what is best practice)? – user3054735 Jun 27 '17 at 21:02
  • 1
    WebDriver is an interface so of course you need to create some concrete implementation. – Danny Yeshurun Jun 27 '17 at 21:12
  • Take a look at the implementation here: https://www.swtestacademy.com/selenium-spring-boot-cucumber-junit5-project/ – Onur Baskirt Mar 01 '22 at 05:44
1
package br.com.api.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxDriverLogLevel;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.springframework.core.io.ClassPathResource;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "api/cenario/teste")
public class TesteCenarioController {

private WebDriver driver;

@GetMapping
public ResponseEntity<String> teste() {

    setUpGeckoDriver();

    FirefoxOptions options = new FirefoxOptions();
    options.setLogLevel(FirefoxDriverLogLevel.TRACE);
    options.setCapability("marionete", true);
    this.driver = new FirefoxDriver(options);

    System.err.println("DRIVER OK");
    this.driver.get("https://www.phptravels.net/blog");

    WebElement findElement = this.driver.findElement(By.xpath("//*[@id=\"body-section\"]/div/div/div[1]/div/div[1]"));
    String testResult = "LATEST POSTS".equals( findElement.getText() ) ? "PASS" : "FAIL";

    this.driver.quit();
    return new ResponseEntity<String>(testResult, HttpStatus.OK);
}

private void setUpGeckoDriver() {
    ClassPathResource classPathResource = new ClassPathResource("selenium/geckodriver.exe");
    InputStream inputStream = null;
    try {
        inputStream = classPathResource.getInputStream();
        File geckodriverFile = File.createTempFile("geckodriver", ".exe"); ;
        FileOutputStream out = new FileOutputStream( geckodriverFile );
        IOUtils.copy(inputStream, out);
        System.err.println( geckodriverFile.getCanonicalPath());
        System.setProperty("webdriver.gecko.driver", geckodriverFile.getCanonicalPath() );
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        IOUtils.closeQuietly(inputStream);
    }
}

}

On my resources directory I have selenium/geckodriver.exe.

My pom is the following:

<?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>testes-regressao</groupId>
    <artifactId>testes-regressao</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>testes-regressao</name>
    <description>api spring boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jersey</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-firefox-driver</artifactId>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-api</artifactId>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-support</artifactId>
        </dependency>

        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-remote-driver</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                </configuration>
            </plugin>
        </plugins>
    </build>


</project>

I can start spring boot from eclipse than make a GET call to the url localhost:8080/api/cenario/teste. So Selenium open the browser and execute the test cenarios on demand, than I show the results on a web page.

But when I generate a jar file with the project, selenium fail to start the browser.

peterh
  • 11,875
  • 18
  • 85
  • 108