user2680405
user2680405

Reputation: 21

RobotFramework Selenium2Library and External Libraries- pass webdriver?

I have created a Java library that utilizes an instance of Selenium Web Driver. I would like to run the test I have written with this library, as well as the Selenium2Library. In a way, the Java Library would add some functionality that I need (working with Ajax elements), but much of the test could be written with Selenium2 keywords.

Is there a way to pass the webdriver instantiated in Selenium2Library to my external library so that they can run the same test?

Thank you for your input!

Upvotes: 2

Views: 5096

Answers (1)

ombre42
ombre42

Reputation: 2384

The current browser is stored in a WebDriverCache field that is protected. You could extend Selenium2Library and expose the WebDriver, but I think in this simple use case, you are better off using reflection instead. This way you can work with the original Selenium2Library. Others may feel differently. I will demonstrate both.

Both solutions provide a Get Current Browser keyword which you could take the result from and pass that into your library's constructor, etc.

Here you is a library with a keyword that will use reflection to access WebDriverCache and expose it:

// default package
import java.lang.reflect.Field;

import org.openqa.selenium.WebDriver;
import org.robotframework.selenium2library.keywords.BrowserManagement;
import org.robotframework.selenium2library.utils.WebDriverCache;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Misc {
    public static void goToGoogle() {
        getCurrentBrowser().get("http://www.google.com");
    }

    public static WebDriverCache getWebDriverCache() {
        try
        {
            BrowserManagement bm = (BrowserManagement) getLibraryInstance("Selenium2Library");
            Field cacheField = BrowserManagement.class.getDeclaredField("webDriverCache");
            cacheField.setAccessible(true);
            return (WebDriverCache) cacheField.get(bm);
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static WebDriver getCurrentBrowser() {
        return getWebDriverCache().getCurrent();
    }

    private static Object getLibraryInstance(String library) throws ScriptException {
        ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
        engine.put("library", library);
        engine.eval("from robot.libraries.BuiltIn import BuiltIn");
        engine.eval("instance = BuiltIn().get_library_instance(library)");
        return engine.get("instance");
    }
}

Below you can see how it is used, mixing Selenium2Library keywords with keywords from Misc:

*** Settings ***
Test Teardown    Close All Browsers
Library    Selenium2Library
Library    Misc

*** Test Cases ***
Get Current Browser Test
    Open Browser    http://slashdot.org
    Go To Google
    Title Should Be    Google

If you want to use a custom Selenium2Library instead (inheritence), here is an example:

// default package
import org.openqa.selenium.WebDriver;


public class MySelenium2Library extends Selenium2Library
{
    public WebDriver getCurrentBrowser() {
        return this.webDriverCache.getCurrent();
    }
}

Interact with WebDriver instance directly from Robot Framework to make the example simpler:

*** Settings ***
Test Teardown    Close All Browsers
Library    MySelenium2Library

*** Test Cases ***
Get Current Browser Test
    Open Browser    http://slashdot.org
    ${driver}=    Get Current Browser
    Call Method    ${driver}    get    http://www.google.com
    Title Should Be    Google

Upvotes: 1

Related Questions