blob: 4fc8276720a84831b05bf5024e0157aae4225341 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.chrome.browser.autofill_assistant;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.actionWithAssertions;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.scrollTo;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isDescendantOfA;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withTagValue;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.chromium.chrome.browser.autofill_assistant.AssistantTagsForTesting.RECYCLER_VIEW_TAG;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.getAbsoluteBoundingRect;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.startAutofillAssistant;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilKeyboardMatchesCondition;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewAssertionTrue;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition;
import static org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.PeekMode.HANDLE;
import static org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.PeekMode.HANDLE_HEADER;
import static org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.PeekMode.HANDLE_HEADER_CAROUSELS;
import static org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.ViewportResizing.NO_RESIZE;
import static org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.ViewportResizing.RESIZE_LAYOUT_VIEWPORT;
import static org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.ViewportResizing.RESIZE_VISUAL_VIEWPORT;
import android.graphics.Rect;
import androidx.test.espresso.Espresso;
import androidx.test.espresso.ViewAction;
import androidx.test.espresso.action.GeneralLocation;
import androidx.test.espresso.action.GeneralSwipeAction;
import androidx.test.espresso.action.Press;
import androidx.test.espresso.action.Swipe;
import androidx.test.filters.MediumTest;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.Criteria;
import org.chromium.base.test.util.CriteriaHelper;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.chrome.autofill_assistant.R;
import org.chromium.chrome.browser.autofill_assistant.proto.ActionProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ChipIcon;
import org.chromium.chrome.browser.autofill_assistant.proto.ChipProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ChipType;
import org.chromium.chrome.browser.autofill_assistant.proto.ClientSettingsProto;
import org.chromium.chrome.browser.autofill_assistant.proto.CollectUserDataProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.PeekMode;
import org.chromium.chrome.browser.autofill_assistant.proto.ConfigureBottomSheetProto.ViewportResizing;
import org.chromium.chrome.browser.autofill_assistant.proto.DetailsProto;
import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto;
import org.chromium.chrome.browser.autofill_assistant.proto.PromptProto.Choice;
import org.chromium.chrome.browser.autofill_assistant.proto.SelectorProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ShowCastProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ShowDetailsProto;
import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto;
import org.chromium.chrome.browser.autofill_assistant.proto.SupportedScriptProto.PresentationProto;
import org.chromium.chrome.browser.autofill_assistant.proto.TextInputProto;
import org.chromium.chrome.browser.autofill_assistant.proto.TextInputProto.InputType;
import org.chromium.chrome.browser.autofill_assistant.proto.TextInputSectionProto;
import org.chromium.chrome.browser.autofill_assistant.proto.UserFormSectionProto;
import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Tests autofill assistant bottomsheet.
*/
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@RunWith(ChromeJUnit4ClassRunner.class)
public class AutofillAssistantBottomsheetTest {
@Rule
public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule();
private static final String TEST_PAGE = "/components/test/data/autofill_assistant/html/"
+ "bottomsheet_behaviour_target_website.html";
@Before
public void setUp() {
AutofillAssistantPreferencesUtil.setInitialPreferences(true);
mTestRule.startCustomTabActivityWithIntent(
AutofillAssistantUiTestUtil.createMinimalCustomTabIntentForAutobot(
mTestRule.getTestServer().getURL(TEST_PAGE),
/* startImmediately = */ true));
mTestRule.getActivity()
.getRootUiCoordinatorForTesting()
.getScrimCoordinator()
.disableAnimationForTesting(true);
}
private AutofillAssistantTestScript makeScriptWithActionArray(
ArrayList<ActionProto> actionsList) {
return new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("bottomsheet_behaviour_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Bottomsheet behaviour")))
.build(),
actionsList);
}
private AutofillAssistantTestScript makeScript(
ViewportResizing resizing, PeekMode peekMode, boolean withDetails) {
ArrayList<ActionProto> list = new ArrayList<>();
// Prompt.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder()
.setMessage("Hello world!")
.addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setText("Focus element"))))
.build());
// Set viewport resizing and peek mode.
list.add((ActionProto) ActionProto.newBuilder()
.setConfigureBottomSheet(ConfigureBottomSheetProto.newBuilder()
.setViewportResizing(resizing)
.setPeekMode(peekMode))
.build());
// Focus on the bottom element.
list.add((ActionProto) ActionProto.newBuilder()
.setShowCast(ShowCastProto.newBuilder().setElementToPresent(
SelectorProto.newBuilder().addFilters(
SelectorProto.Filter.newBuilder().setCssSelector(
"p.bottom"))))
.build());
if (withDetails) {
// ShowDetails.
list.add((ActionProto) ActionProto.newBuilder()
.setShowDetails(ShowDetailsProto.newBuilder().setDetails(
DetailsProto.newBuilder()
.setTitle("Details title")
.setPlaceholders(DetailsProto.PlaceholdersConfiguration
.newBuilder()
.setShowImagePlaceholder(true)
.build())))
.build());
}
// Add "Done" button.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder().addChoices(
Choice.newBuilder().setChip(ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setText("Done"))))
.build());
return makeScriptWithActionArray(list);
}
@Test
@MediumTest
@DisabledTest(message = "crbug.com/1059442")
public void testNoResize() {
AutofillAssistantTestService testService = new AutofillAssistantTestService(
Collections.singletonList(makeScript(NO_RESIZE, HANDLE, false)));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Focus element"), isCompletelyDisplayed());
onView(withText("Focus element")).perform(click());
checkElementIsCoveredByBottomsheet("bottom", true);
onView(withId(R.id.swipe_indicator)).perform(swipeDownToMinimize());
waitUntilViewMatchesCondition(withText("Hello world!"), not(isDisplayed()));
// Since no resizing of the viewport happens in this mode, the element is partially covered
// even when the bottomsheet is minimized
checkElementIsCoveredByBottomsheet("bottom", true);
onView(withText("Done")).check(matches(not(isDisplayed())));
onView(withId(R.id.swipe_indicator)).perform(swipeUpToExpand());
checkElementIsCoveredByBottomsheet("bottom", true);
waitUntilViewMatchesCondition(withText("Hello world!"), isDisplayed());
}
@Test
@MediumTest
@DisabledTest(message = "crbug.com/1059442")
public void testResizeLayoutViewport() {
AutofillAssistantTestService testService = new AutofillAssistantTestService(
Collections.singletonList(makeScript(RESIZE_LAYOUT_VIEWPORT, HANDLE, false)));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Focus element"), isCompletelyDisplayed());
onView(withText("Focus element")).perform(click());
// The viewport should be resized so that the bottom element is not covered by the bottom
// sheet.
checkElementIsCoveredByBottomsheet("bottom", false);
onView(withId(R.id.swipe_indicator)).perform(swipeDownToMinimize());
// Minimizing the bottomsheet should completely uncover the bottom element.
waitUntilViewMatchesCondition(withText("Hello world!"), not(isDisplayed()));
checkElementIsCoveredByBottomsheet("bottom", false);
onView(withText("Done")).check(matches(not(isDisplayed())));
onView(withId(R.id.swipe_indicator)).perform(swipeUpToExpand());
checkElementIsCoveredByBottomsheet("bottom", true);
waitUntilViewMatchesCondition(withText("Hello world!"), isDisplayed());
}
@Test
@MediumTest
@DisabledTest(message = "crbug.com/1059442")
public void testResizeVisualViewport() {
AutofillAssistantTestService testService = new AutofillAssistantTestService(
Collections.singletonList(makeScript(RESIZE_VISUAL_VIEWPORT, HANDLE, false)));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Focus element"), isCompletelyDisplayed());
onView(withText("Focus element")).perform(click());
// The viewport should be resized so that the bottom element is not covered by the bottom
// sheet.
checkElementIsCoveredByBottomsheet("bottom", false);
onView(withId(R.id.swipe_indicator)).perform(swipeDownToMinimize());
waitUntilViewMatchesCondition(withText("Hello world!"), not(isDisplayed()));
checkElementIsCoveredByBottomsheet("bottom", false);
onView(withText("Done")).check(matches(not(isDisplayed())));
onView(withId(R.id.swipe_indicator)).perform(swipeUpToExpand());
checkElementIsCoveredByBottomsheet("bottom", true);
waitUntilViewMatchesCondition(withText("Hello world!"), isDisplayed());
}
@Test
@MediumTest
public void testHandleHeader() {
AutofillAssistantTestService testService = new AutofillAssistantTestService(
Collections.singletonList(makeScript(RESIZE_LAYOUT_VIEWPORT, HANDLE_HEADER, true)));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Focus element"), isCompletelyDisplayed());
onView(withText("Focus element")).perform(click());
waitUntilViewMatchesCondition(withText("Details title"), isCompletelyDisplayed());
checkElementIsCoveredByBottomsheet("bottom", true);
onView(withId(R.id.swipe_indicator)).perform(swipeDownToMinimize());
checkElementIsCoveredByBottomsheet("bottom", false);
// The header should be visible even when minimized
onView(withText("Hello world!")).check(matches(isCompletelyDisplayed()));
onView(withText("Details title")).check(matches(not(isDisplayed())));
onView(withText("Done")).check(matches(not(isDisplayed())));
onView(withId(R.id.swipe_indicator)).perform(swipeUpToExpand());
checkElementIsCoveredByBottomsheet("bottom", true);
onView(withText("Details title")).check(matches(isCompletelyDisplayed()));
}
@Test
@MediumTest
public void testHandleHeaderCarousels() {
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(
makeScript(RESIZE_LAYOUT_VIEWPORT, HANDLE_HEADER_CAROUSELS, true)));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Focus element"), isCompletelyDisplayed());
onView(withText("Focus element")).perform(click());
waitUntilViewMatchesCondition(withText("Details title"), isCompletelyDisplayed());
checkElementIsCoveredByBottomsheet("bottom", true);
onView(withId(R.id.swipe_indicator)).perform(swipeDownToMinimize());
checkElementIsCoveredByBottomsheet("bottom", false);
// The header should be visible even when minimized
onView(withText("Hello world!")).check(matches(isCompletelyDisplayed()));
// The button gets initially hidden while swiping down but should reappear shortly after.
waitUntilViewMatchesCondition(withText("Done"), isCompletelyDisplayed());
onView(withText("Details title")).check(matches(not(isDisplayed())));
onView(withId(R.id.swipe_indicator)).perform(swipeUpToExpand());
checkElementIsCoveredByBottomsheet("bottom", true);
onView(withText("Details title")).check(matches(isCompletelyDisplayed()));
}
@Test
@MediumTest
public void testBottomSheetDoesNotObstructNavBar() {
// Create enough additional sections to fill up more than the height of the screen.
List<UserFormSectionProto> additionalSections = new ArrayList<>();
for (int i = 0; i < 20; ++i) {
additionalSections.add(
(UserFormSectionProto) UserFormSectionProto.newBuilder()
.setTextInputSection(TextInputSectionProto.newBuilder().addInputFields(
TextInputProto.newBuilder()
.setHint("Text input " + i)
.setClientMemoryKey("input_" + i)
.setInputType(TextInputProto.InputType.INPUT_TEXT)))
.setTitle("Title " + i)
.build());
}
ArrayList<ActionProto> list = new ArrayList<>();
list.add((ActionProto) ActionProto.newBuilder()
.setCollectUserData(
CollectUserDataProto.newBuilder()
.addAllAdditionalAppendedSections(additionalSections)
.setRequestTermsAndConditions(false))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("bottomsheet_behaviour_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
onView(withId(R.id.control_container)).check(matches(isCompletelyDisplayed()));
onView(withText("Title 0")).perform(click());
waitUntilViewMatchesCondition(
withContentDescription("Text input 0"), isCompletelyDisplayed());
// Typing text will show the soft keyboard, leading to resize of the Chrome window.
onView(withContentDescription("Text input 0")).perform(typeText("Hello World!"));
onView(withId(R.id.control_container)).check(matches(isCompletelyDisplayed()));
onView(allOf(withContentDescription("Close"), isDisplayed()))
.check(matches(isCompletelyDisplayed()));
// Closing the soft keyboard will restore the window size.
Espresso.closeSoftKeyboard();
onView(withContentDescription("Text input 0")).check(matches(isDisplayed()));
onView(withId(R.id.control_container)).check(matches(isCompletelyDisplayed()));
onView(withText("Continue")).check(matches(isCompletelyDisplayed()));
// Scroll down.
onView(withText("Title 19")).check(matches(not(isDisplayed())));
onView(withText("Title 19")).perform(scrollTo()).check(matches(isDisplayed()));
// Scroll up.
onView(withText("Title 0")).check(matches(not(isDisplayed())));
onView(withText("Title 0")).perform(scrollTo()).check(matches(isDisplayed()));
}
@Test
@MediumTest
public void testCancelSnackbarUndo() {
ArrayList<ActionProto> list = new ArrayList<>();
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder().addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.CANCEL_ACTION)
.setIcon(ChipIcon.ICON_CLEAR)
.setText("Cancel"))))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("bottomsheet_behaviour_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Cancel"), isCompletelyDisplayed());
onView(withText("Cancel")).perform(click());
waitUntilViewMatchesCondition(withText(R.string.undo), isCompletelyDisplayed());
onView(withText("Cancel")).check(doesNotExist());
onView(withText(R.string.undo)).perform(click());
waitUntilViewMatchesCondition(withText("Cancel"), isDisplayed());
}
@Test
@MediumTest
public void testCancelSnackbarTimeout() {
ClientSettingsProto clientSettings = (ClientSettingsProto) ClientSettingsProto.newBuilder()
.setCancelDelayMs(2000)
.build();
ArrayList<ActionProto> list = new ArrayList<>();
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder().addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.CANCEL_ACTION)
.setIcon(ChipIcon.ICON_CLEAR)
.setText("Cancel"))))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("bottomsheet_behaviour_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script), clientSettings);
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Cancel"), isCompletelyDisplayed());
onView(withText("Cancel")).perform(click());
waitUntilViewMatchesCondition(withText(R.string.undo), isCompletelyDisplayed());
onView(withText("Cancel")).check(doesNotExist());
waitUntilViewAssertionTrue(withText(R.string.undo), doesNotExist(), 3000L);
onView(withId(R.id.autofill_assistant)).check(doesNotExist());
}
@Test
@MediumTest
@DisabledTest(message = "Flaky test. crbug.com/1114818")
public void testBottomSheetAutoCollapseAndExpand() {
ArrayList<ActionProto> list = new ArrayList<>();
// Prompt.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder()
.setMessage("Hello world!")
.addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setText("Focus element"))))
.build());
// Focus on the bottom element.
list.add((ActionProto) ActionProto.newBuilder()
.setShowCast(ShowCastProto.newBuilder().setElementToPresent(
SelectorProto.newBuilder().addFilters(
SelectorProto.Filter.newBuilder().setCssSelector(
"p.bottom"))))
.build());
// Set handle and header peek mode and auto collapse to that state.
list.add((ActionProto) ActionProto.newBuilder()
.setConfigureBottomSheet(ConfigureBottomSheetProto.newBuilder()
.setViewportResizing(NO_RESIZE)
.setPeekMode(HANDLE_HEADER)
.setCollapse(true))
.build());
// Add sticky "Next" button. Disable auto expanding the sheet for prompt actions.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder()
.addChoices(Choice.newBuilder().setChip(
ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setSticky(true)
.setText("Sticky next")))
.setDisableForceExpandSheet(true))
.build());
// Expand the sheet.
list.add((ActionProto) ActionProto.newBuilder()
.setConfigureBottomSheet(ConfigureBottomSheetProto.newBuilder()
.setViewportResizing(NO_RESIZE)
.setExpand(true))
.build());
// Add "Done" button.
list.add((ActionProto) ActionProto.newBuilder()
.setPrompt(PromptProto.newBuilder().addChoices(
Choice.newBuilder().setChip(ChipProto.newBuilder()
.setType(ChipType.DONE_ACTION)
.setText("Done"))))
.build());
AutofillAssistantTestScript script = makeScriptWithActionArray(list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("Focus element"), isCompletelyDisplayed());
onView(withText("Focus element")).perform(click());
// Check that the sheet is in peek state and has a sticky button. There is
// a second button still in the hidden carousel.
waitUntilViewMatchesCondition(
allOf(withText("Sticky next"), isDescendantOfA(withId(R.id.header))),
isCompletelyDisplayed());
onView(allOf(withText("Sticky next"), isDescendantOfA(withTagValue(is(RECYCLER_VIEW_TAG)))))
.check(matches(not(isDisplayed())));
onView(allOf(withText("Sticky next"), isDescendantOfA(withId(R.id.header))))
.perform(click());
// Check that the sheet is now expanded and the done button is part of the recycler view,
// not the header.
waitUntilViewMatchesCondition(
allOf(withText("Done"), isDescendantOfA(withTagValue(is(RECYCLER_VIEW_TAG)))),
isCompletelyDisplayed());
}
/**
* When the keyboard is shown, the continue button becomes invisible.
*/
@Test
@DisabledTest(message = "Test is flaky, see crbug.com/1054058")
@MediumTest
public void testOpeningKeyboardMakesContinueChipInvisible() {
ArrayList<ActionProto> list = new ArrayList<>();
UserFormSectionProto userFormSectionProto =
UserFormSectionProto.newBuilder()
.setTitle("User form")
.setTextInputSection(
TextInputSectionProto.newBuilder()
.addInputFields(TextInputProto.newBuilder()
.setHint("Field 1")
.setInputType(InputType.INPUT_TEXT)
.setClientMemoryKey("field_1"))
.addInputFields(TextInputProto.newBuilder()
.setHint("Field 2")
.setInputType(InputType.INPUT_TEXT)
.setClientMemoryKey("field_2")))
.build();
list.add((ActionProto) ActionProto.newBuilder()
.setCollectUserData(
CollectUserDataProto.newBuilder()
.setRequestTermsAndConditions(false)
.addAdditionalPrependedSections(userFormSectionProto))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("form_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Payment")))
.build(),
list);
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script));
startAutofillAssistant(mTestRule.getActivity(), testService);
waitUntilViewMatchesCondition(withText("User form"), isDisplayed());
onView(withText("User form")).perform(click());
waitUntilViewMatchesCondition(withText("Field 1"), isDisplayed());
onView(withContentDescription("Continue")).check(matches(isDisplayed()));
onView(withText("Field 1")).perform(click());
waitUntilKeyboardMatchesCondition(mTestRule, true);
onView(withContentDescription("Continue")).check(matches(not(isDisplayed())));
onView(allOf(withContentDescription("Close"), isDisplayed())).perform(click());
waitUntilKeyboardMatchesCondition(mTestRule, false);
onView(withContentDescription("Continue")).check(matches(isDisplayed()));
}
private ViewAction swipeDownToMinimize() {
return actionWithAssertions(
new GeneralSwipeAction(Swipe.FAST, GeneralLocation.CENTER, view -> {
float[] coordinates = GeneralLocation.CENTER.calculateCoordinates(view);
coordinates[1] =
view.getContext().getResources().getDisplayMetrics().heightPixels;
return coordinates;
}, Press.FINGER));
}
private ViewAction swipeUpToExpand() {
return actionWithAssertions(
new GeneralSwipeAction(Swipe.FAST, GeneralLocation.CENTER, view -> {
float[] coordinates = GeneralLocation.CENTER.calculateCoordinates(view);
coordinates[1] = 0;
return coordinates;
}, Press.FINGER));
}
private void checkElementIsCoveredByBottomsheet(String elementId, boolean shouldBeCovered) {
CriteriaHelper.pollInstrumentationThread(() -> {
float y = GeneralLocation.TOP_CENTER.calculateCoordinates(
mTestRule.getActivity().findViewById(
R.id.autofill_assistant_bottom_sheet_toolbar))[1];
Rect el = null;
try {
el = getAbsoluteBoundingRect(mTestRule, elementId);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
String errorMsg = "Timeout while waiting for element '" + elementId + "' to become "
+ (shouldBeCovered ? "covered" : "not covered") + " by the bottomsheet";
if (shouldBeCovered) {
Criteria.checkThat(errorMsg, (float) el.bottom, Matchers.greaterThan(y));
} else {
Criteria.checkThat(errorMsg, (float) el.bottom, Matchers.lessThanOrEqualTo(y));
}
});
}
}