jbehave-junit-runner icon indicating copy to clipboard operation
jbehave-junit-runner copied to clipboard

jbehave-junit-runner requires causes Selenium WebDriver based tests to fail when Spring @Autowired

Open crazyfrozenpenguin opened this issue 12 years ago • 0 comments

Another issue for the troubleshooting section.

JBehave Steps that make use Selenium WebDriver will fail because jbehave-junit-runner will cause the test to instantiate a WebDriver before it is required.

One workaround is to create a WebDriver Proxy/Wrapper that will delay the instantiation of the target Selenium WebDriver until it is really necessary.

For example:

public class WebDriverProxy implements WebDriver, JavascriptExecutor {

@SuppressWarnings("rawtypes")
private final Class webDriverClass;
private WebDriver driver;

@SuppressWarnings("rawtypes")
public WebDriverProxy(final Class webDriverClass) {
    this.webDriverClass = webDriverClass;
}

public WebDriver getDriver() {
    if (this.driver == null) {
        try {
            this.driver = (WebDriver) this.webDriverClass.newInstance();
        }
        catch (final InstantiationException e) {
            e.printStackTrace();
        }
        catch (final IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    return this.driver;
}

@PreDestroy
public void clean() {
    quit();
}

public void get(final String url) {
    getDriver().get(url);
}

public String getCurrentUrl() {
    return getDriver().getCurrentUrl();
}

public String getTitle() {
    return getDriver().getTitle();
}

public List<WebElement> findElements(final By by) {
    return getDriver().findElements(by);
}

public WebElement findElement(final By by) {
    return getDriver().findElement(by);
}

public String getPageSource() {
    return getDriver().getPageSource();
}

public void close() {
    getDriver().close();
}

public void quit() {
    getDriver().quit();
}

public Set<String> getWindowHandles() {
    return getDriver().getWindowHandles();
}

public String getWindowHandle() {
    return getDriver().getWindowHandle();
}

public TargetLocator switchTo() {
    return getDriver().switchTo();
}

public Navigation navigate() {
    return getDriver().navigate();
}

public Options manage() {
    return getDriver().manage();
}

public Object executeScript(final String script, final Object... args) {
    return ((JavascriptExecutor) getDriver()).executeScript(script, args);
}

public Object executeAsyncScript(final String script, final Object... args) {
    return ((JavascriptExecutor) getDriver()).executeAsyncScript(script, args);
}

}

and configure it in Spring:

<bean id="webDriver" class="com.foo.WebDriverProxy">
    <constructor-arg value="org.openqa.selenium.firefox.FirefoxDriver"/>
</bean>

then use it in your JBehave Steps:

@Component("fooSteps")
public class FooSteps {

    @Autowired
    private WebDriver driver;

    ...
}

crazyfrozenpenguin avatar Oct 22 '12 16:10 crazyfrozenpenguin