Commit 25117a7b authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

[Android Mfill] Reenable integration tests

This CL reenables all Autofill and Manual Filling Integration tests that
previously flaked due to keyboard timing, unstable UI or were disabled
because autofill chips were not yet available.

Minor fix: Rescroll the chips when switching the focused field.

Bug: 838922, 836027, 847959, 894428, 911056, 919988
Change-Id: I2fcfdc4016da5952cddf79f2d5c33180d89b7e1f
Reviewed-on: https://chromium-review.googlesource.com/c/1459552Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Commit-Queue: Friedrich [CET] <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#630704}
parent 6c34bd1a
......@@ -744,6 +744,7 @@ android_library("chrome_test_java") {
data = [
"//chrome/test/data/android/",
"//chrome/test/data/autofill/",
"//chrome/test/data/banners/",
"//chrome/test/data/browsing_data/",
"//chrome/test/data/encoding_tests/auto_detect/Big5_with_no_encoding_specified.html",
......
......@@ -90,6 +90,7 @@ class KeyboardAccessoryView extends LinearLayout {
}
void setVisible(boolean visible) {
if (!visible || getVisibility() != VISIBLE) mBarItemsView.scrollToPosition(0);
if (visible) {
show();
} else {
......
......@@ -4,96 +4,49 @@
package org.chromium.chrome.browser.autofill;
import static org.chromium.ui.base.LocalizationUtils.setRtlForTesting;
import android.support.test.filters.MediumTest;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.RetryOnFailure;
import org.chromium.base.test.util.UrlUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeActivity;
import org.chromium.chrome.browser.ChromeFeatureList;
import org.chromium.chrome.browser.ChromeSwitches;
import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
import org.chromium.chrome.browser.tab.Tab;
import org.chromium.chrome.test.ChromeActivityTestRule;
import org.chromium.chrome.browser.autofill.keyboard_accessory.ManualFillingTestHelper;
import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.content_public.browser.WebContents;
import org.chromium.content_public.browser.test.util.Criteria;
import org.chromium.content_public.browser.test.util.CriteriaHelper;
import org.chromium.content_public.browser.test.util.DOMUtils;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
/**
* Integration tests for autofill keyboard accessory.
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@RetryOnFailure
@EnableFeatures({ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY})
@EnableFeatures({ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY,
ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY})
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class AutofillKeyboardAccessoryIntegrationTest {
@Rule
public ChromeActivityTestRule<ChromeActivity> mActivityTestRule =
new ChromeActivityTestRule<>(ChromeActivity.class);
private final AtomicReference<WebContents> mWebContentsRef = new AtomicReference<>();
private final AtomicReference<ViewGroup> mContainerRef = new AtomicReference<>();
private void loadTestPage(boolean isRtl)
throws InterruptedException, ExecutionException, TimeoutException {
mActivityTestRule.startMainActivityWithURL(UrlUtils.encodeHtmlDataUri("<html"
+ (isRtl ? " dir=\"rtl\"" : "") + "><head>"
+ "<meta name=\"viewport\""
+ "content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>"
+ "<body><form method=\"POST\">"
+ "<input type=\"text\" id=\"fn\" autocomplete=\"given-name\" autofocus/><br>"
+ "<input type=\"text\" id=\"ln\" autocomplete=\"family-name\" /><br>"
+ "<textarea id=\"sa\" autocomplete=\"street-address\"></textarea><br>"
+ "<input type=\"text\" id=\"a1\" autocomplete=\"address-line1\" /><br>"
+ "<input type=\"text\" id=\"a2\" autocomplete=\"address-line2\" /><br>"
+ "<input type=\"text\" id=\"ct\" autocomplete=\"address-level2\" /><br>"
+ "<input type=\"text\" id=\"zc\" autocomplete=\"postal-code\" /><br>"
+ "<input type=\"text\" id=\"em\" autocomplete=\"email\" /><br>"
+ "<input type=\"text\" id=\"ph\" autocomplete=\"tel\" /><br>"
+ "<input type=\"text\" id=\"fx\" autocomplete=\"fax\" /><br>"
+ "<select id=\"co\" autocomplete=\"country\"><br>"
+ "<option value=\"BR\">Brazil</option>"
+ "<option value=\"US\">United States</option>"
+ "</select>"
+ "<input type=\"submit\" />"
+ "</form></body></html>"));
new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com",
"Johnathan Smithonian-Jackson", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco",
"", "94102", "", "US", "(415) 888-9999", "john.sj@acme-mail.inc", "en"));
new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com",
"Jane Erika Donovanova", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco", "",
"94102", "", "US", "(415) 999-0000", "donovanova.j@acme-mail.inc", "en"));
new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com",
"Marcus McSpartangregor", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco", "",
"94102", "", "US", "(415) 999-0000", "marc@acme-mail.inc", "en"));
setRtlForTesting(isRtl);
ThreadUtils.runOnUiThreadBlocking(() -> {
Tab tab = mActivityTestRule.getActivity().getActivityTab();
mWebContentsRef.set(tab.getWebContents());
mContainerRef.set(tab.getContentView());
});
DOMUtils.waitForNonZeroNodeBounds(mWebContentsRef.get(), "fn");
public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
private ManualFillingTestHelper mHelper = new ManualFillingTestHelper(mActivityTestRule);
private void loadTestPage() throws InterruptedException, ExecutionException, TimeoutException {
mHelper.loadTestPage("/chrome/test/data/autofill/autofill_test_form.html", false, false);
ManualFillingTestHelper.createAutofillTestProfiles();
DOMUtils.waitForNonZeroNodeBounds(mHelper.getWebContents(), "NAME_FIRST");
}
/**
......@@ -101,11 +54,13 @@ public class AutofillKeyboardAccessoryIntegrationTest {
*/
@Test
@MediumTest
@EnableFeatures({ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY})
public void testAutofocusedFieldDoesNotShowKeyboardAccessory()
throws ExecutionException, InterruptedException, TimeoutException {
loadTestPage(false);
Assert.assertTrue("Keyboard accessory should be hidden.", isAccessoryGone());
loadTestPage();
CriteriaHelper.pollUiThread(() -> {
View accessory = mActivityTestRule.getActivity().findViewById(R.id.keyboard_accessory);
return accessory == null || !accessory.isShown();
});
}
/**
......@@ -113,18 +68,11 @@ public class AutofillKeyboardAccessoryIntegrationTest {
*/
@Test
@MediumTest
@EnableFeatures({ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY})
@DisabledTest(message = "crbug.com/854224")
public void testTapInputFieldShowsKeyboardAccessory()
throws ExecutionException, InterruptedException, TimeoutException {
loadTestPage(false);
DOMUtils.clickNode(mWebContentsRef.get(), "fn");
CriteriaHelper.pollUiThread(Criteria.equals(true,
()
-> mActivityTestRule.getKeyboardDelegate().isKeyboardShowing(
mActivityTestRule.getActivity(), mContainerRef.get())));
Assert.assertTrue("Keyboard accessory should be showing.", isAccessoryVisible());
loadTestPage();
mHelper.clickNodeAndShowKeyboard("NAME_FIRST");
mHelper.waitForKeyboardAccessoryToBeShown();
}
/**
......@@ -132,24 +80,23 @@ public class AutofillKeyboardAccessoryIntegrationTest {
*/
@Test
@MediumTest
@EnableFeatures({ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY})
@DisabledTest(message = "crbug.com/836027")
public void testSwitchFieldsRescrollsKeyboardAccessory()
throws ExecutionException, InterruptedException, TimeoutException {
loadTestPage(false);
DOMUtils.clickNode(mWebContentsRef.get(), "em");
CriteriaHelper.pollUiThread(Criteria.equals(true,
()
-> mActivityTestRule.getKeyboardDelegate().isKeyboardShowing(
mActivityTestRule.getActivity(), mContainerRef.get())));
loadTestPage();
mHelper.clickNodeAndShowKeyboard("EMAIL_ADDRESS");
mHelper.waitForKeyboardAccessoryToBeShown();
// Scroll to the second position and check it actually happened.
ThreadUtils.runOnUiThreadBlocking(() -> getSuggestionsComponent().scrollToPosition(2));
assertSuggestionsScrollState(false, "Should keep the manual scroll position.");
DOMUtils.clickNode(mWebContentsRef.get(), "ln");
assertSuggestionsScrollState(true, "Should be scrolled back to position 0.");
CriteriaHelper.pollUiThread(() -> {
return getSuggestionsComponent().computeHorizontalScrollOffset() > 0;
}, "Should keep the manual scroll position.");
// Clicking any other node should now scroll the items back to the initial position.
mHelper.clickNodeAndShowKeyboard("NAME_LAST");
CriteriaHelper.pollUiThread(() -> {
return getSuggestionsComponent().computeHorizontalScrollOffset() == 0;
}, "Should be scrolled back to position 0.");
}
/**
......@@ -158,70 +105,26 @@ public class AutofillKeyboardAccessoryIntegrationTest {
*/
@Test
@MediumTest
@EnableFeatures({ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY})
@DisabledTest(message = "crbug.com/847959")
public void testSelectSuggestionHidesKeyboardAccessory()
throws ExecutionException, InterruptedException, TimeoutException {
loadTestPage(false);
DOMUtils.clickNode(mWebContentsRef.get(), "fn");
CriteriaHelper.pollUiThread(Criteria.equals(true,
()
-> mActivityTestRule.getKeyboardDelegate().isKeyboardShowing(
mActivityTestRule.getActivity(), mContainerRef.get())));
Assert.assertTrue("Keyboard accessory should be visible.", isAccessoryVisible());
ThreadUtils.runOnUiThreadBlocking(() -> getSuggestionAt(0).performClick());
CriteriaHelper.pollUiThread(Criteria.equals(false,
()
-> mActivityTestRule.getKeyboardDelegate().isKeyboardShowing(
mActivityTestRule.getActivity(), mContainerRef.get())));
Assert.assertTrue("Keyboard accessory should be hidden.", isAccessoryGone());
}
loadTestPage();
mHelper.clickNodeAndShowKeyboard("NAME_FIRST");
mHelper.waitForKeyboardAccessoryToBeShown();
private void assertSuggestionsScrollState(boolean isScrollingReset, String failureReason) {
CriteriaHelper.pollUiThread(new Criteria(failureReason) {
@Override
public boolean isSatisfied() {
return isScrollingReset
? getSuggestionsComponent().computeHorizontalScrollOffset() <= 0
: getSuggestionsComponent().computeHorizontalScrollOffset() > 0;
}
});
ThreadUtils.runOnUiThreadBlocking(() -> getFirstSuggestion().performClick());
mHelper.waitForKeyboardAccessoryToDisappear();
}
private RecyclerView getSuggestionsComponent() {
final ViewGroup keyboardAccessory = ThreadUtils.runOnUiThreadBlockingNoException(
() -> mActivityTestRule.getActivity().findViewById(R.id.keyboard_accessory));
if (keyboardAccessory == null) return null; // It might still be loading, so don't assert!
final View recyclerView = keyboardAccessory.findViewById(R.id.bar_items_view);
if (recyclerView == null) return null; // It might still be loading, so don't assert!
return (RecyclerView) recyclerView;
assert keyboardAccessory != null;
return (RecyclerView) keyboardAccessory.findViewById(R.id.bar_items_view);
}
private View getSuggestionAt(int index) {
private View getFirstSuggestion() {
ViewGroup recyclerView = getSuggestionsComponent();
if (recyclerView == null) return null; // It might still be loading, so don't assert!
return recyclerView.getChildAt(index);
}
private boolean isAccessoryVisible() throws ExecutionException {
return ThreadUtils.runOnUiThreadBlocking(() -> {
LinearLayout keyboard =
mActivityTestRule.getActivity().findViewById(R.id.keyboard_accessory);
return keyboard != null && keyboard.getVisibility() == View.VISIBLE;
});
}
private boolean isAccessoryGone() throws ExecutionException {
return ThreadUtils.runOnUiThreadBlocking(() -> {
LinearLayout keyboard =
mActivityTestRule.getActivity().findViewById(R.id.keyboard_accessory);
return keyboard == null || keyboard.getVisibility() == View.GONE;
});
assert recyclerView != null;
return recyclerView.getChildAt(0);
}
}
......@@ -37,7 +37,6 @@ import org.junit.runner.RunWith;
import org.chromium.base.ThreadUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.DisabledTest;
import org.chromium.base.test.util.Restriction;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeFeatureList;
......@@ -68,9 +67,7 @@ import java.util.concurrent.atomic.AtomicReference;
*/
@RunWith(ChromeJUnit4ClassRunner.class)
@EnableFeatures({ChromeFeatureList.PASSWORDS_KEYBOARD_ACCESSORY,
ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY,
// TODO(crbug.com/894428): Remove and use the embedded test server instead of data urls.
ChromeFeatureList.AUTOFILL_ALLOW_NON_HTTP_ACTIVATION})
ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY})
@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
public class ManualFillingIntegrationTest {
@Rule
......@@ -263,7 +260,6 @@ public class ManualFillingIntegrationTest {
@Test
@SmallTest
@DisabledTest(message = "https://crbug.com/919988")
@Restriction(UiRestriction.RESTRICTION_TYPE_PHONE)
public void testInvokingTabSwitcherHidesAccessory()
throws InterruptedException, TimeoutException {
......
......@@ -39,6 +39,8 @@ import org.chromium.base.ThreadUtils;
import org.chromium.chrome.R;
import org.chromium.chrome.browser.ChromeTabbedActivity;
import org.chromium.chrome.browser.ChromeWindow;
import org.chromium.chrome.browser.autofill.AutofillTestHelper;
import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.AccessorySheetData;
import org.chromium.chrome.browser.autofill.keyboard_accessory.KeyboardAccessoryData.Provider;
import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
......@@ -54,6 +56,7 @@ import org.chromium.net.test.EmbeddedTestServer;
import org.chromium.ui.DropdownItem;
import org.chromium.ui.DropdownPopupWindowInterface;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
......@@ -77,7 +80,7 @@ public class ManualFillingTestHelper {
return (FakeKeyboard) mActivityTestRule.getKeyboardDelegate();
}
ManualFillingTestHelper(ChromeTabbedActivityTestRule activityTestRule) {
public ManualFillingTestHelper(ChromeTabbedActivityTestRule activityTestRule) {
mActivityTestRule = activityTestRule;
}
......@@ -86,6 +89,11 @@ public class ManualFillingTestHelper {
}
public void loadTestPage(String url, boolean isRtl) throws InterruptedException {
loadTestPage(url, isRtl, false);
}
public void loadTestPage(String url, boolean isRtl, boolean waitForNode)
throws InterruptedException {
mEmbeddedTestServer = EmbeddedTestServer.createAndStartServer(
InstrumentationRegistry.getInstrumentation().getContext());
ChromeWindow.setKeyboardVisibilityDelegateFactory(FakeKeyboard::new);
......@@ -108,7 +116,7 @@ public class ManualFillingTestHelper {
activity.getManualFillingController().registerPasswordProvider(
mSheetSuggestionsProvider);
});
DOMUtils.waitForNonZeroNodeBounds(mWebContentsRef.get(), PASSWORD_NODE_ID);
if (waitForNode) DOMUtils.waitForNonZeroNodeBounds(mWebContentsRef.get(), PASSWORD_NODE_ID);
cacheCredentials(new String[0], new String[0]); // This caches the empty state.
}
......@@ -121,6 +129,10 @@ public class ManualFillingTestHelper {
// Helpers interacting with the web page.
// --------------------------------------
public WebContents getWebContents() {
return mWebContentsRef.get();
}
public void focusPasswordField() throws TimeoutException, InterruptedException {
DOMUtils.focusNode(mActivityTestRule.getWebContents(), PASSWORD_NODE_ID);
ThreadUtils.runOnUiThreadBlocking(
......@@ -143,7 +155,13 @@ public class ManualFillingTestHelper {
.getMediatorForTesting()
.showWhenKeyboardIsVisible();
});
};
}
getKeyboard().showKeyboard(mActivityTestRule.getActivity().getCurrentFocus());
}
public void clickNodeAndShowKeyboard(String node)
throws TimeoutException, InterruptedException {
DOMUtils.clickNode(mWebContentsRef.get(), node);
getKeyboard().showKeyboard(mActivityTestRule.getActivity().getCurrentFocus());
}
......@@ -262,6 +280,19 @@ public class ManualFillingTestHelper {
});
}
public static void createAutofillTestProfiles()
throws InterruptedException, ExecutionException, TimeoutException {
new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com",
"Johnathan Smithonian-Jackson", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco",
"", "94102", "", "US", "(415) 888-9999", "john.sj@acme-mail.inc", "en"));
new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com",
"Jane Erika Donovanova", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco", "",
"94102", "", "US", "(415) 999-0000", "donovanova.j@acme-mail.inc", "en"));
new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www.example.com",
"Marcus McSpartangregor", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco", "",
"94102", "", "US", "(415) 999-0000", "marc@acme-mail.inc", "en"));
}
// --------------------------------------------------
// Generic helpers to match, check or wait for views.
// TODO(fhorschig): Consider Moving to ViewUtils.
......
......@@ -37,6 +37,7 @@ import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
import org.chromium.chrome.test.util.browser.RecyclerViewTestUtils;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
/**
......@@ -124,13 +125,13 @@ public class ManualFillingUiCaptureTest {
@EnableFeatures(ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY)
@Feature({"KeyboardAccessoryModern", "LTR", "UiCatalogue"})
public void testCaptureKeyboardAccessoryV2WithPasswords()
throws InterruptedException, TimeoutException {
throws InterruptedException, TimeoutException, ExecutionException {
mHelper.loadTestPage(false);
ManualFillingTestHelper.createAutofillTestProfiles();
mHelper.cacheTestCredentials();
mHelper.focusPasswordField();
mHelper.waitForKeyboardAccessoryToBeShown();
mHelper.addGenerationButton();
mHelper.addAutofillChips();
waitForActionsInAccessory();
waitForUnrelatedChromeUi();
......@@ -156,13 +157,13 @@ public class ManualFillingUiCaptureTest {
@EnableFeatures(ChromeFeatureList.AUTOFILL_KEYBOARD_ACCESSORY)
@Feature({"KeyboardAccessoryModern", "RTL", "UiCatalogue"})
public void testCaptureKeyboardAccessoryV2WithPasswordsRTL()
throws InterruptedException, TimeoutException {
throws InterruptedException, TimeoutException, ExecutionException {
mHelper.loadTestPage(true);
ManualFillingTestHelper.createAutofillTestProfiles();
mHelper.cacheTestCredentials();
mHelper.focusPasswordField();
mHelper.waitForKeyboardAccessoryToBeShown();
mHelper.addGenerationButton();
mHelper.addAutofillChips();
waitForActionsInAccessory();
waitForUnrelatedChromeUi();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment