blob: b2cfad93033575e0665d41409212011b0d652e70 [file] [log] [blame]
// Copyright 2020 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 android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.scrollTo;
import static android.support.test.espresso.action.ViewActions.typeText;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
import static android.support.test.espresso.matcher.ViewMatchers.withContentDescription;
import static android.support.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.checkElementExists;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.fullyCovers;
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.tapElement;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntil;
import static org.chromium.chrome.browser.autofill_assistant.AutofillAssistantUiTestUtil.waitUntilViewMatchesCondition;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.matcher.ViewMatchers.Visibility;
import android.support.test.filters.MediumTest;
import org.junit.After;
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.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.ChipProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ClientSettingsProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ClientSettingsProto.IntegrationTestSettings;
import org.chromium.chrome.browser.autofill_assistant.proto.CollectUserDataProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ElementAreaProto;
import org.chromium.chrome.browser.autofill_assistant.proto.ElementAreaProto.Rectangle;
import org.chromium.chrome.browser.autofill_assistant.proto.ElementReferenceProto;
import org.chromium.chrome.browser.autofill_assistant.proto.FocusElementProto;
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.customtabs.CustomTabsTestUtils;
import org.chromium.chrome.browser.flags.ChromeSwitches;
import org.chromium.chrome.browser.util.AccessibilityUtil;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.content_public.browser.test.util.TestThreadUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Tests autofill assistant with accessibility enabled.
*/
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
@RunWith(ChromeJUnit4ClassRunner.class)
public class AutofillAssistantAccessibilityIntegrationTest {
@Rule
public CustomTabActivityTestRule mTestRule = new CustomTabActivityTestRule();
private static final String TEST_PAGE = "/components/test/data/autofill_assistant/html/"
+ "autofill_assistant_target_website.html";
private void runScript(AutofillAssistantTestScript script) {
AutofillAssistantTestService testService =
new AutofillAssistantTestService(Collections.singletonList(script),
(ClientSettingsProto) ClientSettingsProto.newBuilder()
.setIntegrationTestSettings(
IntegrationTestSettings.newBuilder()
.setDisableHeaderAnimations(true)
.setDisableCarouselChangeAnimations(true))
.setTalkbackSheetSizeFraction(0.5f)
.build());
startAutofillAssistant(mTestRule.getActivity(), testService);
}
@Before
public void setUp() {
AutofillAssistantPreferencesUtil.setInitialPreferences(true);
mTestRule.startCustomTabActivityWithIntent(CustomTabsTestUtils.createMinimalCustomTabIntent(
InstrumentationRegistry.getTargetContext(),
mTestRule.getTestServer().getURL(TEST_PAGE)));
mTestRule.getActivity().getScrim().disableAnimationForTesting(true);
}
@After
public void tearDown() {
AccessibilityUtil.setAccessibilityEnabledForTesting(null);
}
@Test
@MediumTest
@DisabledTest(message = "crbug.com/1081604")
public void testBottomSheetHasRestrictedFixedHeight() throws Exception {
ArrayList<ActionProto> list = new ArrayList<>();
// Show an element on top that should not be covered by the bottom sheet.
ElementReferenceProto element = (ElementReferenceProto) ElementReferenceProto.newBuilder()
.addSelectors("#touch_area_one")
.build();
ElementAreaProto elementArea =
(ElementAreaProto) ElementAreaProto.newBuilder()
.addTouchable(Rectangle.newBuilder().addElements(element))
.addTouchable(Rectangle.newBuilder().addElements(
ElementReferenceProto.newBuilder().addSelectors(
"#touch_area_four")))
.build();
list.add((ActionProto) ActionProto.newBuilder()
.setFocusElement(FocusElementProto.newBuilder()
.setElement(element)
.setTouchableElementArea(elementArea))
.build());
// Create enough additional sections to fill up more than the height of the screen.
List<UserFormSectionProto> additionalSections = new ArrayList<>();
for (int i = 1; i <= 20; ++i) {
additionalSections.add(
(UserFormSectionProto) UserFormSectionProto.newBuilder()
.setTextInputSection(TextInputSectionProto.newBuilder().addInputFields(
TextInputProto.newBuilder()
.setHint("Text input " + i)
.setClientMemoryKey("input_" + i)
.setInputType(InputType.INPUT_TEXT)))
.setTitle("Title " + i)
.build());
}
list.add((ActionProto) ActionProto.newBuilder()
.setCollectUserData(
CollectUserDataProto.newBuilder()
.addAllAdditionalAppendedSections(additionalSections)
.setRequestTermsAndConditions(false))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("autofill_assistant_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
AccessibilityUtil.setAccessibilityEnabledForTesting(true);
runScript(script);
waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
onView(withId(R.id.control_container)).check(matches(isCompletelyDisplayed()));
onView(withText("Title 1")).check(matches(isDisplayed()));
onView(withText("Title 20")).check(matches(not(isDisplayed())));
assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(true));
tapElement(mTestRule, "touch_area_one");
waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_one"));
// Typing text will show the soft keyboard, leading to resize of the Chrome window.
onView(withText("Title 1")).perform(scrollTo(), click());
waitUntilViewMatchesCondition(withContentDescription("Text input 1"),
withEffectiveVisibility(Visibility.VISIBLE));
onView(withContentDescription("Text input 1"))
.perform(scrollTo(), typeText("Hello World!"));
onView(withId(R.id.control_container)).check(matches(isCompletelyDisplayed()));
assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true));
tapElement(mTestRule, "touch_area_four");
waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_four"));
}
@Test
@MediumTest
public void testBottomSheetListensToAccessibilityChanges() throws Exception {
ArrayList<ActionProto> list = new ArrayList<>();
// Show an element on top that may or may not be covered by the bottom sheet.
ElementReferenceProto element = (ElementReferenceProto) ElementReferenceProto.newBuilder()
.addSelectors("#touch_area_one")
.build();
ElementAreaProto elementArea =
(ElementAreaProto) ElementAreaProto.newBuilder()
.addTouchable(Rectangle.newBuilder().addElements(element))
.addTouchable(Rectangle.newBuilder().addElements(
ElementReferenceProto.newBuilder().addSelectors(
"#touch_area_four")))
.build();
list.add((ActionProto) ActionProto.newBuilder()
.setFocusElement(FocusElementProto.newBuilder()
.setElement(element)
.setTouchableElementArea(elementArea))
.build());
// Create enough additional sections to fill up more than the height of the screen.
List<UserFormSectionProto> additionalSections = new ArrayList<>();
for (int i = 1; i <= 20; ++i) {
additionalSections.add(
(UserFormSectionProto) UserFormSectionProto.newBuilder()
.setTextInputSection(TextInputSectionProto.newBuilder().addInputFields(
TextInputProto.newBuilder()
.setHint("Text input " + i)
.setClientMemoryKey("input_" + i)
.setInputType(InputType.INPUT_TEXT)))
.setTitle("Title " + i)
.build());
}
list.add((ActionProto) ActionProto.newBuilder()
.setCollectUserData(
CollectUserDataProto.newBuilder()
.addAllAdditionalAppendedSections(additionalSections)
.setRequestTermsAndConditions(false))
.build());
AutofillAssistantTestScript script = new AutofillAssistantTestScript(
(SupportedScriptProto) SupportedScriptProto.newBuilder()
.setPath("autofill_assistant_target_website.html")
.setPresentation(PresentationProto.newBuilder().setAutostart(true).setChip(
ChipProto.newBuilder().setText("Autostart")))
.build(),
list);
runScript(script);
waitUntilViewMatchesCondition(withText("Continue"), isCompletelyDisplayed());
// Without accessibility enabled, the bottom sheet fills the entire screen, tapping the
// element is not possible.
onView(withId(R.id.control_container)).check(matches(isCompletelyDisplayed()));
onView(withText("Title 1")).check(matches(isDisplayed()));
onView(withText("Title 20")).check(matches(not(isDisplayed())));
assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(true));
onView(withId(R.id.bottom_sheet_content))
.check(matches(fullyCovers(getAbsoluteBoundingRect(mTestRule, "touch_area_one"))));
// Enabling accessibility restricts the height, the element can now be tapped and will be
// removed.
TestThreadUtils.runOnUiThreadBlocking(
() -> AccessibilityUtil.setAccessibilityEnabledForTesting(true));
assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_one"), is(true));
waitUntilViewMatchesCondition(withId(R.id.bottom_sheet_content),
not(fullyCovers(getAbsoluteBoundingRect(mTestRule, "touch_area_one"))));
tapElement(mTestRule, "touch_area_one");
waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_one"));
// Disabling accessibility again removes the height restriction so the bottom sheet will
// fill the entire screen again, preventing the tap on the element.
TestThreadUtils.runOnUiThreadBlocking(
() -> AccessibilityUtil.setAccessibilityEnabledForTesting(false));
assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true));
waitUntilViewMatchesCondition(withId(R.id.bottom_sheet_content),
fullyCovers(getAbsoluteBoundingRect(mTestRule, "touch_area_four")));
// Enabling accessibility again to make sure element can actually be removed.
TestThreadUtils.runOnUiThreadBlocking(
() -> AccessibilityUtil.setAccessibilityEnabledForTesting(true));
assertThat(checkElementExists(mTestRule.getWebContents(), "touch_area_four"), is(true));
waitUntilViewMatchesCondition(withId(R.id.bottom_sheet_content),
not(fullyCovers(getAbsoluteBoundingRect(mTestRule, "touch_area_four"))));
tapElement(mTestRule, "touch_area_four");
waitUntil(() -> !checkElementExists(mTestRule.getWebContents(), "touch_area_four"));
}
}