Friday, December 21, 2012

Where to Find cybervillainsCA.cer in Selenium

In the WebTestingExplorer documentation, we instruction users to create a Firefox profile (just for testing!!!) that trusts the cybervillainsCA.cer certificate normally bundled with Selenium distributions. The main reason we do this is to make it possible to inspect HTTPS traffic in a proxy and check for bugs in real-time as we explore the web application.

I've had several questions about how, exactly, to find cybervillainsCA.cer. The search results on this topic are unimpressive enough that I decided to write this quick blog post, hopefully attract some search engine love, and clear this up for everybody. So here you go:

1. Download selenium-server-standalone-x.xx.x.jar (as of this writing, at version 2.28.0).
2. Execute the following commands from a terminal from wherever you saved it:
  1. mkdir selenium
  2. cp selenium-server-standalone-*.jar selenium
  3. cd selenium
  4. jar xvf selenium-server-standalone-*.jar
  5. ls sslSupport/cybervillains.cer
After step 4, you may get an error from jar. Ignore it. After step 5, you have verified that the file is there, and you can do whatever you need to with it. Enjoy!

Sunday, December 16, 2012

Waiting for GWT RPCs in WebDriver Tests

When writing WebDriver tests for GWT applications, we often find ourselves writing WebDriverWait's to synchronize the tests with asynchronous GWT RPC's. These waits are often based on some DOM-observable result of the RPC completing -- for example, waiting until a label is changed by code in the onSuccess handler.

This has a couple of drawbacks. First, we would prefer to assert on the results of the RPC, not rely on them to control our tests. An assertion failure is preferable to a wait timeout when the onSuccess handler does something incorrectly. Second, if the behavior of RPC handling changes, our wait conditions will break and have to be maintained.

We would rather attach our wait condition to the RPC itself, rather than side-effects. Unfortunately, GWT's RPC mechanism does not build in anything for this, and we have to do it ourselves. In the remainder of this post, I will outline a simple (perhaps simplistic) way to do this.

The overall approach is to maintain a hidden field as the RPC goes out and comes back. In the .ui.xml:

<g:Hidden ui:field="ready" name="ready"/>

And the UiBinder declaration:

@UiField Hidden ready;

We'll create a helper method that updates this field based on whether we are "ready" or "busy" running an RPC:

public void setReady(boolean isReady) {
  if (isReady) {
    ready.setValue("ready");
  } else {
    ready.setValue("busy");
  }
}

Then our RPC call will follow this pattern:

public void onAction() {
  view.setReady(false);
  service.getData(new AsyncCallback<String>() {
    @Override
    public void onFailure(Throwable caught) {
      // Show failure message...
      setReady(true);
    }

    @Override
    public void onSuccess(String result) {
      // Show the result...
      setReady(true);
    }
  });  
}

Now in our WebDriver test, we can write a WebDriverWait like this:

WebDriverWait wait = new WebDriverWait(driver, 5000);
wait.until(ExpectedConditions.textToBePresentInElementValue(By.id("ready"), "ready");

There are some obvious drawbacks to this simplistic approach -- for example, it is not very extensible to an environment with multiple or batched RPC's. In a future post, I'll take on some of those challenges.