Commit bed2f341 authored by Friedrich Horschig's avatar Friedrich Horschig Committed by Commit Bot

Revert "Clear password search on X and close it with back button"

This reverts commit dcb5b1f4.

Reason for revert:
Regressed on some devices. Failure reason is not obvious enough for confident immediate fix.

Bug: 834676

Original change's description:
> Clear password search on X and close it with back button
> 
> Right now, clicking the X button in the search will close it.
> To start a new search, you have to open a new search.
> That experience isn't very discoverable, so UX developed an improved
> workflow - details in the bug.
> 
> The new flow needs these changes:
> - the X button _only_ clears the query text field now
> - the X button is _only_ available when a query was entered
> - closing the search happens only via the "navigate up" button
>   in the action bar.
> - the three-dots overflow menu is hidden while a search is active
>   (already the case on small screens - now large screens do the same)
> 
> Tests cover all of these cases.
> 
> Bug: 821755
> Change-Id: Ieb2e16c096750d66874aa4c4999759629332491b
> Reviewed-on: https://chromium-review.googlesource.com/966070
> Reviewed-by: Theresa <twellington@chromium.org>
> Commit-Queue: Friedrich Horschig <fhorschig@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#550955}

TBR=twellington@chromium.org,fhorschig@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: 821755
Change-Id: I9035e5aed91dca19bcff94e195cf060ef61f2b29
Reviewed-on: https://chromium-review.googlesource.com/1019150Reviewed-by: default avatarFriedrich Horschig <fhorschig@chromium.org>
Commit-Queue: Friedrich Horschig <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/master@{#552101}
parent 5d199a9f
......@@ -4,18 +4,9 @@
package org.chromium.chrome.browser.preferences;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.StrictMode;
import android.preference.PreferenceFragment;
import android.support.annotation.XmlRes;
import android.support.v7.widget.ActionMenuView;
import android.view.View;
import android.view.ViewGroup;
import javax.annotation.Nullable;
/**
* A helper class for Preferences.
......@@ -37,42 +28,4 @@ public class PreferenceUtils {
StrictMode.setThreadPolicy(oldPolicy);
}
}
/**
* A helper that is used to set the visibility of the overflow menu view in a given activity.
*
* @param activity The Activity containing the action bar with the menu.
* @param visibility The new visibility of the overflow menu view.
* @return True if the visibility could be set, false otherwise (e.g. because no menu exists).
*/
public static boolean setOverflowMenuVisibility(@Nullable Activity activity, int visibility) {
if (activity == null) return false;
ViewGroup actionBar = activity.findViewById(org.chromium.chrome.R.id.action_bar);
int i = actionBar.getChildCount();
ActionMenuView menuView = null;
while (i-- > 0) {
if (actionBar.getChildAt(i) instanceof ActionMenuView) {
menuView = (ActionMenuView) actionBar.getChildAt(i);
break;
}
}
if (menuView == null) return false;
View overflowButton = menuView.getChildAt(menuView.getChildCount() - 1);
if (overflowButton == null) return false;
overflowButton.setVisibility(visibility);
return true;
}
/**
* Convert a given icon to a plain white version by applying the MATRIX_TRANSFORM_TO_WHITE color
* filter. The resulting drawable will be brighter than a usual grayscale conversion.
*
* For grayscale conversion, use the function ColorMatrix#setSaturation(0) instead.
* @param icon The drawable to be converted.
* @return Returns the bright white version of the passed drawable.
*/
public static Drawable convertToPlainWhite(Drawable icon) {
icon.mutate().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
return icon;
}
}
......@@ -213,8 +213,6 @@ public class Preferences extends AppCompatActivity implements
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Fragment activeFragment = getFragmentManager().findFragmentById(android.R.id.content);
if (activeFragment != null && activeFragment.onOptionsItemSelected(item)) return true;
if (item.getItemId() == android.R.id.home) {
finish();
return true;
......
// Copyright 2018 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.preferences;
import static org.chromium.chrome.browser.preferences.PreferenceUtils.convertToPlainWhite;
import android.support.annotation.NonNull;
import android.support.v7.widget.SearchView;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.ImageView;
import javax.annotation.Nullable;
/**
* A helper class for applying the default search behavior to search items in Chromium settings.
*/
public class SearchUtils {
/**
* This interface allows to react to changed search queries when initialized with
* {@link SearchUtils#initializeSearchView(MenuItem, String, QueryChangeListener)}.
*/
public interface QueryChangeListener {
/**
* Called whenever the search query changes. This usually is immediately after a user types
* and doesn't wait for submission of the whole query.
* @param query Current query as entered by the user. Can be a partial query or empty.
*/
void onQueryTextChange(String query);
}
/**
* Initializes an Android default search item by setting listeners and default states of the
* search icon, box and close icon.
* @param searchItem The existing item that can trigger the search action view.
* @param initialQuery The query that the search field should be opened with.
* @param changeListener The listener to be notified when the user changes the query.
*/
public static void initializeSearchView(@NonNull MenuItem searchItem,
@Nullable String initialQuery, @NonNull QueryChangeListener changeListener) {
SearchView searchView = getSearchView(searchItem);
searchView.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
ImageView mSearchClearButton = findSearchClearButton(searchView);
mSearchClearButton.setImageDrawable(convertToPlainWhite(mSearchClearButton.getDrawable()));
// Restore the search view if a query was recovered.
if (initialQuery != null) {
searchItem.expandActionView();
searchView.setIconified(false);
searchView.setQuery(initialQuery, false);
}
// Clicking the menu item hides the clear button and triggers search for an empty query.
searchItem.setOnMenuItemClickListener((MenuItem m) -> {
updateSearchClearButtonVisibility(searchItem, "");
changeListener.onQueryTextChange("");
return false; // Continue with the default action.
});
// Make the close button a clear button.
searchView.findViewById(org.chromium.chrome.R.id.search_close_btn)
.setOnClickListener((View v) -> {
searchView.setQuery("", false);
updateSearchClearButtonVisibility(searchItem, "");
changeListener.onQueryTextChange("");
});
// Ensure that a changed search view triggers the search - independent from use code path.
searchView.setOnSearchClickListener(view -> {
updateSearchClearButtonVisibility(searchItem, "");
changeListener.onQueryTextChange("");
});
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true; // Consume event.
}
@Override
public boolean onQueryTextChange(String query) {
// TODO(fhorschig) Exit early if a tracked query indicates no changes.
updateSearchClearButtonVisibility(searchItem, query);
changeListener.onQueryTextChange(query);
return true; // Consume event.
}
});
}
/**
* Handles an item in {@link android.support.v4.app.Fragment#onOptionsItemSelected(MenuItem)} if
* it is a search item and returns true. If it is not applicable, it returns false.
* @param selectedItem The user-selected menu item.
* @param searchItem The menu item known to contain the search view.
* @param query The current search query.
* @return Returns true if the item is a search item and could be handled. False otherwise.
*/
public static boolean handleSearchNavigation(
@NonNull MenuItem selectedItem, @NonNull MenuItem searchItem, @Nullable String query) {
if (selectedItem.getItemId() != android.R.id.home || query == null) return false;
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setQuery(null, false);
searchView.setIconified(true);
searchItem.collapseActionView();
return true;
}
/**
* Shorthand to easily access a search item's action view.
* @param searchItem The menu item containing search item.
* @return The search view associated with the menu item.
*/
public static SearchView getSearchView(MenuItem searchItem) {
return (SearchView) searchItem.getActionView();
}
private static void updateSearchClearButtonVisibility(MenuItem searchItem, String query) {
ImageView clearButton = findSearchClearButton(getSearchView(searchItem));
clearButton.setVisibility(query == null || query.equals("") ? View.GONE : View.VISIBLE);
}
private static ImageView findSearchClearButton(SearchView searchView) {
return searchView.findViewById(org.chromium.chrome.R.id.search_close_btn);
}
}
......@@ -7,6 +7,9 @@ package org.chromium.chrome.browser.preferences.password;
import android.app.Activity;
import android.app.FragmentManager;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
......@@ -15,13 +18,14 @@ import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.support.v7.widget.Toolbar;
import android.support.v7.widget.SearchView;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import org.chromium.base.ApiCompatibilityUtils;
import org.chromium.base.VisibleForTesting;
......@@ -33,10 +37,8 @@ import org.chromium.chrome.browser.preferences.ChromeBasePreference;
import org.chromium.chrome.browser.preferences.ChromeSwitchPreference;
import org.chromium.chrome.browser.preferences.ManagedPreferenceDelegate;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.PreferenceUtils;
import org.chromium.chrome.browser.preferences.Preferences;
import org.chromium.chrome.browser.preferences.PreferencesLauncher;
import org.chromium.chrome.browser.preferences.SearchUtils;
import org.chromium.chrome.browser.preferences.TextMessagePreference;
import org.chromium.ui.text.SpanApplier;
......@@ -83,7 +85,6 @@ public class SavePasswordsPreferences
private boolean mNoPasswordExceptions;
private MenuItem mHelpItem;
private MenuItem mSearchItem;
private String mSearchQuery;
private Preference mLinkPref;
......@@ -91,7 +92,7 @@ public class SavePasswordsPreferences
private ChromeBaseCheckBoxPreference mAutoSignInSwitch;
private TextMessagePreference mEmptyView;
private boolean mSearchRecorded;
private Menu mMenu;
private Menu mMenuForTesting;
/**
* For controlling the UX flow of exporting passwords.
......@@ -138,22 +139,56 @@ public class SavePasswordsPreferences
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
menu.clear();
mMenu = menu;
mMenuForTesting = menu;
inflater.inflate(R.menu.save_password_preferences_action_bar_menu, menu);
menu.findItem(R.id.export_passwords).setVisible(ExportFlow.providesPasswordExport());
menu.findItem(R.id.export_passwords).setEnabled(false);
mSearchItem = menu.findItem(R.id.menu_id_search);
mSearchItem.setVisible(providesPasswordSearch());
MenuItem searchItem = menu.findItem(R.id.menu_id_search);
searchItem.setVisible(providesPasswordSearch());
if (providesPasswordSearch()) {
mHelpItem = menu.findItem(R.id.menu_id_general_help);
mSearchItem.setIcon(PreferenceUtils.convertToPlainWhite(mSearchItem.getIcon()));
SearchUtils.initializeSearchView(mSearchItem, mSearchQuery, (query) -> {
maybeRecordTriggeredPasswordSearch(true);
filterPasswords(query);
});
setUpSearchAction(searchItem);
}
}
/**
* Prepares the searchItem's icon and searchView. Sets up listeners to clicks and interactions
* with the searchItem or its searchView.
* @param searchItem the item containing the SearchView. Must not be null.
*/
private void setUpSearchAction(MenuItem searchItem) {
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
searchItem.setIcon(convertToPlainWhite(searchItem.getIcon()));
if (mSearchQuery != null) { // If a query was recovered, restore the search view.
searchItem.expandActionView();
searchView.setIconified(false);
searchView.setQuery(mSearchQuery, false);
}
searchItem.setOnMenuItemClickListener((MenuItem m) -> {
filterPasswords("");
return false; // Continue with the default action.
});
searchView.findViewById(R.id.search_close_btn).setOnClickListener((View v) -> {
searchView.setQuery(null, false);
searchView.setIconified(true);
filterPasswords(null); // Reset filter to bring back all preferences.
});
searchView.setOnSearchClickListener(view -> filterPasswords(""));
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true; // Continue with default action - nothing.
}
@Override
public boolean onQueryTextChange(String query) {
maybeRecordTriggeredPasswordSearch(true);
return filterPasswords(query);
}
});
}
/**
* Record the search only, if the feature is enabled and it hasn't been recorded for this
* instance of the view.
......@@ -180,23 +215,16 @@ public class SavePasswordsPreferences
mExportFlow.startExporting();
return true;
}
if (SearchUtils.handleSearchNavigation(item, mSearchItem, mSearchQuery)) {
filterPasswords(null);
return true;
}
return super.onOptionsItemSelected(item);
}
private void filterPasswords(String query) {
private boolean filterPasswords(String query) {
mSearchQuery = query;
if (mSearchQuery == null) {
mHelpItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
PreferenceUtils.setOverflowMenuVisibility(getActivity(), View.VISIBLE);
} else {
mHelpItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
PreferenceUtils.setOverflowMenuVisibility(getActivity(), View.GONE);
}
// Hide the help option. It's not useful during search but might be clicked by accident.
mHelpItem.setShowAsAction(mSearchQuery != null ? MenuItem.SHOW_AS_ACTION_NEVER
: MenuItem.SHOW_AS_ACTION_IF_ROOM);
rebuildPasswordLists();
return false; // Query has been handled. Don't trigger default action of SearchView.
}
/**
......@@ -403,6 +431,19 @@ public class SavePasswordsPreferences
return true;
}
/**
* Convert a given icon to a plain white version by applying the MATRIX_TRANSFORM_TO_WHITE color
* filter. The resulting drawable will be brighter than a usual grayscale conversion.
*
* For grayscale conversion, use the function ColorMatrix#setSaturation(0) instead.
* @param icon The drawable to be converted.
* @return Returns the bright white version of the passed drawable.
*/
private static Drawable convertToPlainWhite(Drawable icon) {
icon.mutate().setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
return icon;
}
private void createSavePasswordsSwitch() {
if (mSearchQuery != null) {
return; // Don't create this option when the preferences are filtered for passwords.
......@@ -498,11 +539,6 @@ public class SavePasswordsPreferences
@VisibleForTesting
Menu getMenuForTesting() {
return mMenu;
}
@VisibleForTesting
Toolbar getToolbarForTesting() {
return getActivity().findViewById(R.id.action_bar);
return mMenuForTesting;
}
}
......@@ -4,8 +4,6 @@
package org.chromium.chrome.browser.preferences.website;
import static org.chromium.chrome.browser.preferences.SearchUtils.handleSearchNavigation;
import android.content.DialogInterface;
import android.content.res.Resources;
import android.os.Build;
......@@ -16,7 +14,9 @@ import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.SearchView;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.Menu;
......@@ -24,6 +24,7 @@ import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
......@@ -43,7 +44,6 @@ import org.chromium.chrome.browser.preferences.ManagedPreferencesUtils;
import org.chromium.chrome.browser.preferences.PrefServiceBridge;
import org.chromium.chrome.browser.preferences.PreferenceUtils;
import org.chromium.chrome.browser.preferences.ProtectedContentResetCredentialConfirmDialogFragment;
import org.chromium.chrome.browser.preferences.SearchUtils;
import org.chromium.chrome.browser.preferences.website.Website.StoredDataClearedCallback;
import org.chromium.chrome.browser.profiles.Profile;
import org.chromium.chrome.browser.widget.TintedDrawable;
......@@ -71,14 +71,14 @@ public class SingleCategoryPreferences extends PreferenceFragment
// The view to show when the list is empty.
private TextView mEmptyView;
// The item for searching the list of items.
private MenuItem mSearchItem;
// The view for searching the list of items.
private SearchView mSearchView;
// The clear button displayed in the Storage view.
private Button mClearButton;
// The Site Settings Category we are showing.
private SiteSettingsCategory mCategory;
// If not blank, represents a substring to use to search for site names.
private String mSearch;
private String mSearch = "";
// Whether to group by allowed/blocked list.
private boolean mGroupByAllowBlock;
// Whether the Blocked list should be shown expanded.
......@@ -132,7 +132,7 @@ public class SingleCategoryPreferences extends PreferenceFragment
// Find origins matching the current search.
List<WebsitePreference> websites = new ArrayList<>();
for (Website site : sites) {
if (mSearch == null || mSearch.isEmpty() || site.getTitle().contains(mSearch)) {
if (mSearch.isEmpty() || site.getTitle().contains(mSearch)) {
websites.add(new WebsitePreference(getActivity(), site, mCategory));
}
}
......@@ -378,11 +378,26 @@ public class SingleCategoryPreferences extends PreferenceFragment
menu.clear();
inflater.inflate(R.menu.website_preferences_menu, menu);
mSearchItem = menu.findItem(R.id.search);
SearchUtils.initializeSearchView(mSearchItem, mSearch, (query) -> {
mSearch = query;
getInfoForOrigins();
});
MenuItem searchItem = menu.findItem(R.id.search);
mSearchView = (SearchView) MenuItemCompat.getActionView(searchItem);
mSearchView.setImeOptions(EditorInfo.IME_FLAG_NO_FULLSCREEN);
SearchView.OnQueryTextListener queryTextListener =
new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return true;
}
@Override
public boolean onQueryTextChange(String query) {
if (query.equals(mSearch)) return true;
mSearch = query;
getInfoForOrigins();
return true;
}
};
mSearchView.setOnQueryTextListener(queryTextListener);
if (mCategory.showProtectedMediaSites()) {
// Add a menu item to reset protected media identifier device credentials.
......@@ -415,11 +430,6 @@ public class SingleCategoryPreferences extends PreferenceFragment
getActivity(), getString(helpContextResId), Profile.getLastUsedProfile(), null);
return true;
}
if (handleSearchNavigation(item, mSearchItem, mSearch)) {
mSearch = null;
getInfoForOrigins();
return true;
}
return false;
}
......@@ -432,11 +442,11 @@ public class SingleCategoryPreferences extends PreferenceFragment
return false;
}
if (mSearch != null) {
if (!mSearch.isEmpty()) {
// Clear out any lingering searches, so that the full list is shown
// when coming back to this page.
mSearch = null;
SearchUtils.getSearchView(mSearchItem).setQuery("", false);
mSearch = "";
mSearchView.setQuery("", false);
}
if (preference instanceof WebsitePreference) {
......
......@@ -986,7 +986,6 @@ chrome_java_sources = [
"java/src/org/chromium/chrome/browser/preferences/ProtectedContentResetCredentialConfirmDialogFragment.java",
"java/src/org/chromium/chrome/browser/preferences/SearchEngineAdapter.java",
"java/src/org/chromium/chrome/browser/preferences/SearchEnginePreference.java",
"java/src/org/chromium/chrome/browser/preferences/SearchUtils.java",
"java/src/org/chromium/chrome/browser/preferences/SeekBarLinkedCheckBoxPreference.java",
"java/src/org/chromium/chrome/browser/preferences/SeekBarPreference.java",
"java/src/org/chromium/chrome/browser/preferences/SignInPreference.java",
......
......@@ -39,9 +39,6 @@ import static org.hamcrest.Matchers.nullValue;
import static org.hamcrest.Matchers.sameInstance;
import static org.hamcrest.Matchers.startsWith;
import static org.chromium.chrome.test.util.ViewUtils.VIEW_GONE;
import static org.chromium.chrome.test.util.ViewUtils.VIEW_INVISIBLE;
import static org.chromium.chrome.test.util.ViewUtils.VIEW_NULL;
import static org.chromium.chrome.test.util.ViewUtils.waitForView;
import android.app.Activity;
......@@ -1597,8 +1594,7 @@ public class SavePasswordsPreferencesTest {
// Trigger the search, close it and wait for UI to be restored.
Espresso.onView(withSearchMenuIdOrText()).perform(click());
Espresso.onView(withContentDescription(R.string.abc_action_bar_up_description))
.perform(click());
Espresso.onView(withId(R.id.search_close_btn)).perform(click());
Espresso.onView(isRoot()).check(
(root, e)
-> waitForView(
......@@ -1739,9 +1735,7 @@ public class SavePasswordsPreferencesTest {
Espresso.onView(withText(R.string.section_saved_passwords_exceptions))
.check(doesNotExist());
Espresso.onView(withContentDescription(R.string.abc_action_bar_up_description))
.perform(click());
InstrumentationRegistry.getInstrumentation().waitForIdleSync(); // Close search view.
Espresso.onView(withId(R.id.search_close_btn)).perform(click()); // Close search view.
Espresso.onView(withText(R.string.section_saved_passwords_exceptions)).perform(scrollTo());
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
......@@ -1758,43 +1752,17 @@ public class SavePasswordsPreferencesTest {
@EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
public void testSearchIconClickedHidesGeneralPrefs() throws Exception {
setPasswordSource(ZEUS_ON_EARTH);
final SavePasswordsPreferences prefs =
(SavePasswordsPreferences) PreferencesTest
.startPreferences(InstrumentationRegistry.getInstrumentation(),
SavePasswordsPreferences.class.getName())
.getFragmentForTest();
final AtomicReference<Boolean> menuInitiallyVisible = new AtomicReference<>();
ThreadUtils.runOnUiThreadBlocking(
()
-> menuInitiallyVisible.set(
prefs.getToolbarForTesting().isOverflowMenuShowing()));
PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
SavePasswordsPreferences.class.getName());
Espresso.onView(withText(R.string.passwords_auto_signin_title))
.check(matches(isDisplayed()));
Espresso.onView(withText(startsWith("View and manage"))).check(matches(isDisplayed()));
if (menuInitiallyVisible.get()) { // Check overflow menu only on large screens that have it.
Espresso.onView(withContentDescription(R.string.abc_action_menu_overflow_description))
.check(matches(isDisplayed()));
}
Espresso.onView(withSearchMenuIdOrText()).perform(click());
Espresso.onView(withText(R.string.passwords_auto_signin_title)).check(doesNotExist());
Espresso.onView(withText(startsWith("View and manage"))).check(doesNotExist());
Espresso.onView(isRoot()).check(
(root, e)
-> waitForView((ViewGroup) root,
withContentDescription(
R.string.abc_action_menu_overflow_description),
VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL));
Espresso.onView(withContentDescription(R.string.abc_action_bar_up_description))
.perform(click());
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
if (menuInitiallyVisible.get()) { // If the overflow menu was there, it should be restored.
Espresso.onView(withContentDescription(R.string.abc_action_menu_overflow_description))
.check(matches(isDisplayed()));
}
}
/**
......@@ -1816,47 +1784,13 @@ public class SavePasswordsPreferencesTest {
Espresso.onView(withText(R.string.passwords_auto_signin_title)).check(doesNotExist());
Espresso.onView(withText(startsWith("View and manage"))).check(doesNotExist());
Espresso.onView(withContentDescription(R.string.abc_action_bar_up_description))
.perform(click());
Espresso.pressBack(); // Close keyboard.
InstrumentationRegistry.getInstrumentation().waitForIdleSync();
Espresso.onView(withId(R.id.search_close_btn)).perform(click());
Espresso.onView(withText(R.string.passwords_auto_signin_title))
.check(matches(isDisplayed()));
Espresso.onView(withText(startsWith("View and manage"))).check(matches(isDisplayed()));
Espresso.onView(withId(R.id.menu_id_search)).check(matches(isDisplayed()));
}
/**
* Check that clearing the search also hides the clear button.
*/
@Test
@SmallTest
@Feature({"Preferences"})
@EnableFeatures(ChromeFeatureList.PASSWORD_SEARCH)
public void testSearchViewCloseIconExistsOnlyToClearQueries() throws Exception {
setPasswordSourceWithMultipleEntries(GREEK_GODS);
PreferencesTest.startPreferences(InstrumentationRegistry.getInstrumentation(),
SavePasswordsPreferences.class.getName());
// Trigger search which shouldn't have the button yet.
Espresso.onView(withSearchMenuIdOrText()).perform(click());
Espresso.onView(isRoot()).check(
(root, e)
-> waitForView((ViewGroup) root, withId(R.id.search_close_btn),
VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL));
// Type something and see the button appear.
Espresso.onView(withId(R.id.search_src_text))
// Trigger search which shouldn't have the button yet.
.perform(click(), typeText("Zeu"), closeSoftKeyboard());
Espresso.onView(withId(R.id.search_close_btn)).check(matches(isDisplayed()));
// Clear the search which should hide the button again.
Espresso.onView(withId(R.id.search_close_btn)).perform(click()); // Clear search.
Espresso.onView(isRoot()).check(
(root, e)
-> waitForView((ViewGroup) root, withId(R.id.search_close_btn),
VIEW_INVISIBLE | VIEW_GONE | VIEW_NULL));
}
/**
......
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