espresso-web introduction

2015-07-14

Since espresso 2.2 release, webview support module was added to the lineup silentry.

Unfortunately there is no official documents or sample yet, but it’s already can be used. So I’m gonna show you sample and api usage.

This is just unofficial guide. When official stuff being published, it will become deprecated soon.

dependency

The dependency is espresso-web, not espresso-core.

1
2
3
4
5
dependencies {
androidTestCompile 'com.android.support.test:runner:0.3'
androidTestCompile 'com.android.support.test:rules:0.3'
androidTestCompile 'com.android.support.test.espresso:espresso-web:2.2'
}

package

Related classes are under the android.support.test.espresso.web package.

overview

When it comes to espresso-core, you can write tests like following syntax.

1
onView(ViewMatcher).perform(ViewAction).check(ViewAssertion);

espresso-web also provides similar api design.

1
onWebView(ViewMatcher ※option).withElement(Atom).perform(Atom).check(WebAssertion);

You can specify target WebView, DOM element and perform action and check the result of assertion. This is just minimum package, but it’s enough to start.

The class called Atom is frequently used. It’s actually a thin wrapper around javascript. So it turns out specifying element and action are executed by javascript evaluation.

withElement

To specify target element by withElement(Atom<r>), you can use util methods collection declared in DriverAtoms like findElement(Locator locator, String value), findMultipleElements(Locator locator, String value).

1
onWebView().withElement(findElement(Locator.ID, "email_input"))

perform

To execute web action, you can also use DriverAtoms utils collection.

I found three main methods clearElement(), webClick(), webKeys(String text). But they can do only simple web action, so it may be increased in a future release, I guess.

1
2
private static final String EMAIL_TO_BE_TYPED = "email_to_be_typed";
onWebView().withElement(findElement(Locator.ID, "email_input")).perform(webKeys(EMAIL_TO_BE_TYPED));

It’s off the subject but dive into the declare of web action(ex. webKeys(String)), I found the following signature.

1
2
3
4
5
6
7
8
9
10
11
public static Atom webKeys(final String text) {
Preconditions.checkNotNull(text);
return new SimpleAtom(WebDriverAtomScripts.SEND_KEYS_ANDROID) {
public void handleNoElementReference() {
throw new RuntimeException("webKeys: Need an element to type on!");
}
public List getNonContextualArguments() {
return Lists.newArrayList(new Object[]{text});
}
};
}

And go to the WebDriverAtomScripts.SEND_KEYS_ANDROID…there is a bunch of javascript code as string variable!!! Crazy.

check

Web.WebInteraction.check gets WebAssersiton as argument.

WebAssersitons.webContent converts Matcher<document> domMatcherto WebAssersiton. So you should use it and DomMatchers together.

1
onWebView().check(webContent(hasElementWithId("email_input")));

Conclusion

When developing giant app in work, WebView is kinda “inexorable” stuff. So espresso-web lowers a hurdle to put espresso on your production environment(actually robotium started WebView support from a few years ago…).

The one thing on my mind is customizing, It is definitely hard part to create your own Atom or WebAssertion because it is the javascript part.