Driving a Flex Application via Selenium 2 WebDriver

Posted by | November 22, 2010 | Programming | 13 Comments

A while ago my colleague Julia posted an article on acceptance testing a Flex application using Selenium. Now that Selenium 2 has been released I wondered how easy it would be to achieve the same functionality with WebDriver?

As it turns out it isn’t all that difficult. The interaction with JavaScript in the Browser has changed but that aside the changes required to make FlexSelenium operate with WebDriver are straightforward.

The basic principle still remains that the ActionScript extensions for FlexSelenium need to be compiled into your Flex application to expose access to widgets via JavaScript. The changes required are in the way the Java portion of the framework interacts with the browser JavaScript engine.

The WebDriver framework provides an interface that concrete implementations for each browser can implement in order to provide access to the browser’s JavaScript engine. Both the Firefox and Chrome drivers provide such implementations. The code for FlexWebDriver below uses this interface to execute a piece of anonymous JavaScript to call the exposed functions from FlexSelenium.

import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
publicclass FlexWebDriver {    privatefinal WebDriver webDriver;privatefinal String flashObjectId;    public FlexWebDriver(final WebDriver webDriver, final String flashObjectId) {        this.webDriver = webDriver;
        this.flashObjectId = flashObjectId;
    }

    public String click(final String objectId, final String optionalButtonLabel) {        return call("doFlexClick", objectId, optionalButtonLabel);
   }

    public String click(final String objectId) {
         return click(objectId, "");
    }

//... Omitted for clarity ...

    private String call(final String functionName, final String... args) {final Object result =
            ((JavascriptExecutor)webDriver).executeScript(
                 makeJsFunction(functionName, args),
                 new Object[0]);

         return result != null ? result.toString() : null;
    }

    private String makeJsFunction(final String functionName, final String... args) {
         final StringBuffer functionArgs = new StringBuffer();

        if (args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                if (i > 0) {
                    functionArgs.append(",");
            }
                functionArgs.append(String.format("'%1$s'", args[i]));
         }
        }
        return String.format(
            "return document.%1$s.%2$s(%3$s);",
            flashObjectId,
            functionName,
            functionArgs);
    }
}

The main changes are to use org.openqa.selenium.WebDriver instead of com.thoughtworks.selenium.Selenium, and to build the correct JavaScript function to execute via the JavascriptExecutor interface.

A very trivial example of using this to drive a Flex application:

final FirefoxDriver driver = new FirefoxDriver();

final FlexWebDriver flexDriver = new FlexWebDriver(driver, “my-application”);

 

driver.get(“http://localhost:8080/application”);

 

// Wait for the application to load

 

Assert.assertEquals(“true”, flexDriver.click(“aButton”));

I’ve tested this with Selenium 2.0a7 using the Firefox and Google Chrome browser drivers running under Ubuntu 10.10.

Enjoy.

13 Comments

Leave a Reply

Your email address will not be published.

Get in touch to see how Black Pepper can help your business Contact Us
Download our free whitepaper
In this white paper, we discuss how to apply the techniques and business processes of small Internet start-up companies to large corporate IT projects for maximum success.