Edited at

Espresso webview support

More than 3 years have passed since last update.

Espressoの2.2からひっそりとespresso-webというWebViewサポートのモジュールが追加されているのですが、公式のドキュメントもサンプルもなかったので調査しました。

サンプルはこちら。


公式のドキュメントとサンプルが出たらそちらを正として考えてください。



dependency

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

android.support.test.espresso.webパッケージ以下に配置されています。


overview

espresso本体の方では原則として

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

という形式でコードを書いていくようなAPI設計になっており、espresso-webでもこれを踏襲した形式となっています。

onWebView(ViewMatcher(※ここはoption)).withElement(Atom<R>).perform(Atom<E>).check(WebAssertion<E>);

WebViewを指定し、更に内部でDOMのelementを指定し、performしてcheckという流れです。他にもできるのかもしれませんがミニマムな使い方としてはこれでいいのではないかと思います。

Atomというクラスが多用されていますがこれはJavaScriptのラッパーオブジェクトという事なので、JavaScriptを用いて動作や検証を実現しているという事が推測できます。


withElement

withElement(Atom<R>)でelementを指定していきますが、DriverAtomsにutil的なメソッドがあり、findElement(Locator locator, String value)findMultipleElements(Locator locator, String value)等が利用できそうです。

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


perform

同じくDriverAtomsのメソッドを利用できそうです。clearElement()webClick()webKeys(String text)があります。これだけだと複雑な操作はできないので、今後追加されていくのでしょうか。

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));

余談ですが操作するメソッドの中身はどうなっているのかと思って調べてみると、

    public static Atom<Evaluation> 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<Object> getNonContextualArguments() {
return Lists.newArrayList(new Object[]{text});
}
};
}

となっていて、WebDriverAtomScripts.SEND_KEYS_ANDROIDの中を覗くと大量のJavaScriptがStringで定義されていて怖くなって閉じました。


check

Web.WebInteraction.checkはWebAssersitonを引数にとります。WebAssersitonsのwebContentメソッドがMatcher<Document>をWebAssersitonに変換してくれるので、DomMatchersと併用して使います。

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


まとめ

仕事でアプリを開発しているとWebViewというのはどうしても避けられない事もあるので地味に嬉しい機能です。競合のrobotiumは2年程前からサポートしていたので、乗り換えに当ってのハードルも低くなったと思います。

気になったのはcoreの方だとユーザーがCustomMatcherを定義できたりカスタマイズ性が高い印象ですが、espresso-web側は頑張ろうとするとJavaScriptをゴリゴリ定義しないといけなさそうで辛そうな印象でした(小並感)。