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.
No comments:
Post a Comment