AndroidとかiOSとかモバイル多め。その他技術的なことも書いていきます。

【UI Automator 2.0】UiObject2#longClick()が効かない問題の対策

UI Automator 2.0を使ってListViewのContextMenuのテストを書きたかったのですが、UiObject2#longClick()ではどうもまくいきませんでした。

f:id:phicdy:20170625112558g:plain

動きを見る感じロングクリックの時間が短いですね・・・ 調べるとUiDevice#swipe()でロングクリックしたい場所の座標をスワイプすることで解決できるようです。

参考:http://stackoverflow.com/questions/21432561/how-to-achieve-long-click-in-uiautomator

UiDevice#swipe()の説明を見ると

Performs a swipe from one coordinate to another using the number of steps to determine smoothness and speed. Each step execution is throttled to 5ms per step. So for a 100 steps, the swipe will take about 1/2 second to complete.

とあるので最後のstepの値でロングクリックの時間を制御できそうです。 以下テストコードです。

@Test
public void deleteFilter() {
    UiDevice device = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    // アプリ起動等
    // ...
    
    // ロングクリック
    UiObject2 filterList = device.wait(Until.findObject(
            By.clazz(ListView.class)), 5000);
    if (filterList == null) fail("Filter list was not found");
    List<UiObject2> filters = filterList.findObjects(
            By.clazz(LinearLayout.class).depth(2));
    if (filters == null) fail("Filter item was not found");
    assertThat(filters.size(), is(1));
    // 動かない
    // filters.get(0).longClick();
    Rect filterRect = filters.get(0).getVisibleBounds();
    device.swipe(filterRect.centerX(), filterRect.centerY(),
            filterRect.centerX(), filterRect.centerY(), 100);

    // 削除をクリック
    UiObject2 dialogContentList = device.wait(Until.findObject(
            By.res("android", "select_dialog_listview")), 5000);
    if (dialogContentList == null) fail("Dialog was not found");
    List<UiObject2> contents = dialogContentList.findObjects(
            By.clazz(RelativeLayout.class).depth(2));
    for (UiObject2 content : contents) {
        UiObject2 contentText = content.findObject(
                By.clazz(TextView.class));
        if (contentText != null && contentText.getText().equals("フィルター削除")) {
            content.click();
            break;
        }
    }

    // 結果確認
    UiObject2 emptyView = device.wait(Until.findObject(
            By.res(BuildConfig.APPLICATION_ID, "filter_emptyView")), 5000);
    assertNotNull(emptyView);
}

うまくいきました!

f:id:phicdy:20170625112639g:plain