Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3776da90 authored by Ben Reich's avatar Ben Reich
Browse files

Add test to assert selection bar shows up when search item is selected

As part of the material 3 refresh, the selection bar was rewritten to
not use an ActionBar. There are a number of implicit behaviours bulit
into the action bar that need to be hoisted into the new code.
Unfortunately it looks like these aren't covered by tests.

This test asserts that when a search is currently happening, selection
of any items in the search view should show a "N selected" bar up the
top.

Bug: 412895530
Test: atest com.android.documentsui.SearchViewUiTest
Flag: EXEMPT adding test to validate behaviour with flag off
Change-Id: Ibcd303d804514dda1ffb8a1455a63ac8305a74bf
parent ff6cd248
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.documentsui.conditions

import androidx.test.uiautomator.UiObject2
import androidx.test.uiautomator.UiObject2Condition

/**
 * A UI Automator condition that is met when the UiObject2 that it is acting on has the number of
 * children elements that matches the supplied `predicate`. The companion object contains some
 * shorthand helpers for common cases. The object that it is checking the child count of must exist.
 */
class HasChildCountCondition(
    private val predicate: (count: Int) -> Boolean
) : UiObject2Condition<Boolean>() {
    override fun apply(o: UiObject2?): Boolean? {
        requireNotNull(o) { "Supplied object to validate for child count must exist" }
        return predicate(o.childCount)
    }

    companion object {
        @JvmStatic
        fun hasOneChild(): HasChildCountCondition {
            return HasChildCountCondition({ it == 1 })
        }

        @JvmStatic
        fun hasMoreThanOneChild(): HasChildCountCondition {
            return HasChildCountCondition({ it > 1 })
        }
    }
}
+35 −1
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText;

import static com.android.documentsui.StubProvider.ROOT_0_ID;
import static com.android.documentsui.StubProvider.ROOT_1_ID;
import static com.android.documentsui.conditions.HasChildCountCondition.hasMoreThanOneChild;
import static com.android.documentsui.conditions.HasChildCountCondition.hasOneChild;
import static com.android.documentsui.flags.Flags.FLAG_USE_MATERIAL3;
import static com.android.documentsui.flags.Flags.FLAG_USE_SEARCH_V2_READ_ONLY;

@@ -41,6 +43,7 @@ import android.provider.Settings;
import androidx.test.filters.LargeTest;
import androidx.test.filters.Suppress;
import androidx.test.uiautomator.By;
import androidx.test.uiautomator.UiObject2;
import androidx.test.uiautomator.UiObjectNotFoundException;
import androidx.test.uiautomator.Until;

@@ -63,6 +66,9 @@ public class SearchViewUiTest extends ActivityTestJunit4<FilesActivity> {
    @Rule
    public final TestFilesRule mTestFilesRule = new TestFilesRule();

    // UI timeout to wait for elements to appear, set to 5 seconds.
    private final int mTimeout = 5000;

    @Before
    public void setUpTest() throws UiObjectNotFoundException, RemoteException {
        // Drawer interferes with a lot of search action; going to try to close any opened ones
@@ -354,7 +360,35 @@ public class SearchViewUiTest extends ActivityTestJunit4<FilesActivity> {
                .perform(new RelaxedClickAction());

        // Ensure the selection has cleared and the "1 file selected" text is not displayed.
        device.wait(Until.findObject(By.text(TestFilesRule.FILE_NAME_2).selected(false)), 5000);
        device.wait(Until.findObject(By.text(TestFilesRule.FILE_NAME_2).selected(false)), mTimeout);
        onView(withText("1 selected")).check(doesNotExist());
    }

    @Test
    @RequiresFlagsDisabled(
            FLAG_USE_MATERIAL3) // TODO(b/412895530): Enable for `use_material3` once fixed.
    public void testSelectionWhileSearchingHidesSearchBar() throws UiObjectNotFoundException {
        String pkg = bots.directory.mTargetPackage;

        // The `mTestFilesRule` creates more than 1 file, so ensure that that is the case before
        // proceeding.
        UiObject2 directoryList = device.findObject(By.res(pkg + ":id/dir_list"));
        directoryList.wait(hasMoreThanOneChild(), mTimeout);

        // Click the search icon and wait until the only result is the file that was searced for.
        bots.search.clickIcon();
        bots.search.setInputText(TestFilesRule.FILE_NAME_1);
        directoryList.wait(hasOneChild(), mTimeout);
        bots.directory.waitForDocument(TestFilesRule.FILE_NAME_1);

        // Select the document. This implicitly verifies that the bar at the top shows the text "1
        // selected" which, in all conditions, occludes the search input box.
        bots.directory.selectDocument(TestFilesRule.FILE_NAME_1, 1);

        // Deselect the document and click the clear button on the search view (if the selection bar
        // at the top is visible this won't be possible).
        bots.directory.selectDocument(TestFilesRule.FILE_NAME_1);
        bots.search.clickSearchViewClearButton();
        device.wait(Until.findObject(By.res(pkg + ":id/history_list")), mTimeout);
    }
}