blob: 079afcade5232d1de65bf0c4efae4ea9ca16d1c6 [file] [log] [blame]
// 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.
#include "base/ios/ios_util.h"
#import "base/test/ios/wait_util.h"
#import "ios/chrome/browser/ui/autofill/autofill_app_interface.h"
#import "ios/chrome/test/earl_grey/chrome_actions.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/testing/earl_grey/keyboard_app_interface.h"
#include "ios/web/public/test/element_selector.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "url/gurl.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using base::test::ios::kWaitForActionTimeout;
using chrome_test_util::AutofillSuggestionViewMatcher;
using chrome_test_util::ManualFallbackFormSuggestionViewMatcher;
using chrome_test_util::ManualFallbackKeyboardIconMatcher;
using chrome_test_util::ManualFallbackManageProfilesMatcher;
using chrome_test_util::ManualFallbackProfilesIconMatcher;
using chrome_test_util::ManualFallbackProfilesTableViewMatcher;
using chrome_test_util::ManualFallbackProfileTableViewWindowMatcher;
namespace {
// Using |isKeyboardDocked| requires to inject a UITextField in the window and
// wait for it to be shown. For performance reasons, only try to dock the
// keyboard in |tearDown| if it was undocked during the test.
bool gKeyboardUndockAttempted = false;
constexpr char kFormElementName[] = "name";
constexpr char kFormElementCity[] = "city";
constexpr char kFormHTMLFile[] = "/profile_form.html";
// Returns a matcher for a button in the ProfileTableView. Currently it returns
// the company one.
id<GREYMatcher> ProfileTableViewButtonMatcher() {
// The company name for autofill::test::GetFullProfile() is "Underworld".
return grey_buttonTitle(@"Underworld");
}
// Undocks and split the keyboard by swiping it up. Does nothing if already
// undocked. Some devices, like iPhone or iPad Pro, do not allow undocking or
// splitting, this returns NO if it is the case.
BOOL UndockAndSplitKeyboard() {
if (![ChromeEarlGrey isIPadIdiom]) {
return NO;
}
UITextField* textField = [KeyboardAppInterface showKeyboard];
// Return if already undocked.
if (![KeyboardAppInterface isKeyboardDocked]) {
// If a dummy textfield was created for this, remove it.
[textField removeFromSuperview];
return YES;
}
[[EarlGrey
selectElementWithMatcher:[KeyboardAppInterface keyboardWindowMatcher]]
performAction:[KeyboardAppInterface keyboardUndockAction]];
gKeyboardUndockAttempted = YES;
// If a dummy textfield was created for this, remove it.
[textField removeFromSuperview];
return ![KeyboardAppInterface isKeyboardDocked];
}
// Docks the keyboard by swiping it down. Does nothing if already docked.
void DockKeyboard() {
if (![ChromeEarlGrey isIPadIdiom]) {
return;
}
UITextField* textField = [KeyboardAppInterface showKeyboard];
// Return if already docked.
if ([KeyboardAppInterface isKeyboardDocked]) {
// If we created a dummy textfield for this, remove it.
[textField removeFromSuperview];
return;
}
[[EarlGrey
selectElementWithMatcher:[KeyboardAppInterface keyboardWindowMatcher]]
performAction:[KeyboardAppInterface keyboardDockAction]];
// If we created a dummy textfield for this, remove it.
[textField removeFromSuperview];
GREYCondition* waitForDockedKeyboard = [GREYCondition
conditionWithName:@"Wait For Docked Keyboard Animations"
block:^BOOL {
return [KeyboardAppInterface isKeyboardDocked];
}];
GREYAssertTrue([waitForDockedKeyboard waitWithTimeout:kWaitForActionTimeout],
@"Keyboard animations still present.");
}
// Waits for the keyboard to appear. Returns NO on timeout.
BOOL WaitForKeyboardToAppear() {
GREYCondition* waitForKeyboard = [GREYCondition
conditionWithName:@"Wait for keyboard"
block:^BOOL {
return [EarlGrey isKeyboardShownWithError:nil];
}];
return [waitForKeyboard waitWithTimeout:kWaitForActionTimeout];
}
} // namespace
// Integration Tests for fallback coordinator.
@interface FallbackCoordinatorTestCase : ChromeTestCase
@end
@implementation FallbackCoordinatorTestCase
- (void)setUp {
[super setUp];
// If the previous run was manually stopped then the profile will be in the
// store and the test will fail. We clean it here for those cases.
[AutofillAppInterface clearProfilesStore];
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
const GURL URL = self.testServer->GetURL(kFormHTMLFile);
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"Profile form"];
}
- (void)tearDown {
if (gKeyboardUndockAttempted) {
gKeyboardUndockAttempted = NO;
DockKeyboard();
}
[AutofillAppInterface clearProfilesStore];
// Leaving a picker on iPads causes problems with the docking logic. This
// will dismiss any.
if ([ChromeEarlGrey isIPadIdiom]) {
// Tap in the web view so the popover dismisses.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:grey_tapAtPoint(CGPointMake(0, 0))];
// Verify the table view is not visible.
[[EarlGrey
selectElementWithMatcher:grey_allOf(
grey_kindOfClass([UITableView class]),
grey_not(grey_notVisible()), nil)]
assertWithMatcher:grey_nil()];
}
[super tearDown];
}
// Tests that the when tapping the outside the popover on iPad, suggestions
// continue working.
- (void)testIPadTappingOutsidePopOverResumesSuggestionsCorrectly {
if (![ChromeEarlGrey isIPadIdiom]) {
EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone.");
}
// Add the profile to be tested.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementName)];
// Tap on the profiles icon.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap on a point outside of the popover.
// The way EarlGrey taps doesn't go through the window hierarchy. Because of
// this, the tap needs to be done in the same window as the popover.
[[EarlGrey
selectElementWithMatcher:ManualFallbackProfileTableViewWindowMatcher()]
performAction:grey_tapAtPoint(CGPointMake(0, 0))];
// Verify the profiles controller table view is NOT visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
// Tap on the suggestion.
[[EarlGrey selectElementWithMatcher:AutofillSuggestionViewMatcher()]
performAction:grey_tap()];
// Verify Web Content was filled.
NSString* name = [AutofillAppInterface exampleProfileName];
NSString* javaScriptCondition = [NSString
stringWithFormat:@"document.getElementById('%s').value === '%@'",
kFormElementName, name];
[ChromeEarlGrey waitForJavaScriptCondition:javaScriptCondition];
}
// Tests that the manual fallback view concedes preference to the system picker
// for selection elements.
- (void)testPickerDismissesManualFallback {
// Add the profile to be used.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Tap on the profiles icon.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap any option.
[[EarlGrey selectElementWithMatcher:ProfileTableViewButtonMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is not visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
// TODO(crbug.com/1220724): iOS 15 phones seem to act more like iPads now,
// dismissing the keyboard when tapping on the option above. Confirm that this
// is expected and either fix, or remove this comment.
BOOL isIOS15 = NO;
if (@available(iOS 15, *)) {
isIOS15 = YES;
}
// Verify the status of the icons.
if ([ChromeEarlGrey isIPadIdiom] || isIOS15) {
// Hidden on iPad.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_notVisible()];
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
} else {
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
}
}
// Tests that the input accessory view continues working after a picker is
// present.
- (void)testInputAccessoryBarIsPresentAfterPickers {
// Add the profile to be used.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Tap on the profiles icon.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap any option.
[[EarlGrey selectElementWithMatcher:ProfileTableViewButtonMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is not visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
// TODO(crbug.com/1220724): iOS 15 phones seem to act more like iPads now,
// dismissing the keyboard when tapping on the option above. Confirm that this
// is expected and either fix, or remove this comment.
BOOL isIOS15 = NO;
if (@available(iOS 15, *)) {
isIOS15 = YES;
}
// On iPad the picker is a table view in a popover, we need to dismiss that
// first.
if ([ChromeEarlGrey isIPadIdiom] || isIOS15) {
// Tap in the web view so the popover dismisses.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:grey_tapAtPoint(CGPointMake(0, 0))];
// Verify the table view is not visible.
[[EarlGrey
selectElementWithMatcher:grey_allOf(
grey_kindOfClass([UITableView class]),
grey_not(grey_notVisible()), nil)]
assertWithMatcher:grey_nil()];
}
// Bring up the regular keyboard again.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Wait for the accessory icon to appear.
GREYAssert(WaitForKeyboardToAppear(), @"Keyboard didn't appear.");
// Verify the profiles icon is visible, and therefore also the input accessory
// bar.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
// Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// TODO(crbug.com/1227392): This doesn't appear to work on iOS15 phone. It
// appears the profiles icon is visible and selected (so interaction
// disabled), but the keyboard itself is visible. As a workaround, tap the
// keyboard icon and continue the test.
if (![ChromeEarlGrey isIPadIdiom] && isIOS15) {
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
performAction:grey_tap()];
}
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
}
// Same as before but with the keyboard undocked the re-docked.
- (void)testRedockedInputAccessoryBarIsPresentAfterPickers {
// No need to run if not iPad.
if (![ChromeEarlGrey isIPadIdiom]) {
EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone.");
}
// Add the profile to be used.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
if (!UndockAndSplitKeyboard()) {
EARL_GREY_TEST_DISABLED(
@"Undocking the keyboard does not work on iPhone or iPad Pro");
}
// Give the iPad 2 seconds to settle the split animation.
[[NSRunLoop currentRunLoop]
runUntilDate:[[NSDate date] dateByAddingTimeInterval:2]];
// When keyboard is split, icons are not visible, so we rely on timeout before
// docking again, because EarlGrey synchronization isn't working properly with
// the keyboard.
[ChromeEarlGrey waitForMatcher:ManualFallbackProfilesIconMatcher()];
DockKeyboard();
// Tap on the profiles icon.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap any option.
[[EarlGrey selectElementWithMatcher:ProfileTableViewButtonMatcher()]
performAction:grey_tap()];
// Verify the profiles controller table view is not visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesTableViewMatcher()]
assertWithMatcher:grey_notVisible()];
// On iPad the picker is a table view in a popover, we need to dismiss that
// first. Tap in the previous field, so the popover dismisses.
[[EarlGrey selectElementWithMatcher:grey_keyWindow()]
performAction:grey_tapAtPoint(CGPointMake(0, 0))];
// Verify the table view is not visible.
[[EarlGrey
selectElementWithMatcher:grey_allOf(grey_kindOfClass([UITableView class]),
grey_not(grey_notVisible()), nil)]
assertWithMatcher:grey_nil()];
// Bring up the regular keyboard again.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementName)];
// Wait for the accessory icon to appear.
GREYAssert(WaitForKeyboardToAppear(), @"Keyboard didn't appear.");
// Verify the profiles icon is visible, and therefore also the input accessory
// bar.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
// Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
}
// Test the input accessory bar is present when undocking then docking the
// keyboard.
- (void)testInputAccessoryBarIsPresentAfterUndockingKeyboard {
if (![ChromeEarlGrey isIPadIdiom]) {
EARL_GREY_TEST_SKIPPED(@"Test not applicable for iPhone.");
}
// Add the profile to use for verification.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
if (!UndockAndSplitKeyboard()) {
EARL_GREY_TEST_DISABLED(
@"Undocking the keyboard does not work on iPhone or iPad Pro");
}
// When keyboard is split, icons are not visible, so we rely on timeout before
// docking again, because EarlGrey synchronization isn't working properly with
// the keyboard.
[ChromeEarlGrey waitForMatcher:ManualFallbackProfilesIconMatcher()];
DockKeyboard();
// Verify the profiles icon is visible, and therefore also the input accessory
// bar.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
// Verify the status of the icons.
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_userInteractionEnabled()];
[[EarlGrey selectElementWithMatcher:ManualFallbackKeyboardIconMatcher()]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
}
// Tests that the manual fallback view is present in incognito.
// Disabled due to flakiness. See crbug.com/1115321.
- (void)DISABLED_testIncognitoManualFallbackMenu {
// Add the profile to use for verification.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Verify the profiles icon is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Open a tab in incognito.
[ChromeEarlGrey openNewIncognitoTab];
const GURL URL = self.testServer->GetURL(kFormHTMLFile);
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"Profile form"];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Verify the profiles icon is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests the mediator stops observing objects when the incognito BVC is
// destroyed. Waiting for dealloc was causing a race condition with the
// autorelease pool, and some times a DCHECK will be hit.
- (void)testOpeningIncognitoTabsDoNotLeak {
const GURL URL = self.testServer->GetURL(kFormHTMLFile);
std::string webViewText("Profile form");
[AutofillAppInterface saveExampleProfile];
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Verify the profiles icon is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Open a tab in incognito.
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:webViewText];
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Verify the profiles icon is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
[ChromeEarlGrey closeCurrentTab];
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:webViewText];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Verify the profiles icon is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Open a tab in incognito.
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:webViewText];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Open a regular tab.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:webViewText];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// This will fail if there is more than one profiles icon in the hierarchy.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that the manual fallback view is not duplicated after incognito.
- (void)testReturningFromIncognitoDoesNotDuplicatesManualFallbackMenu {
// Add the profile to use for verification.
[AutofillAppInterface saveExampleProfile];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Verify the profiles icon is visible.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
// Open a tab in incognito.
[ChromeEarlGrey openNewIncognitoTab];
const GURL URL = self.testServer->GetURL(kFormHTMLFile);
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"Profile form"];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// Open a regular tab.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:"Profile form"];
// Bring up the keyboard by tapping the city, which is the element before the
// picker.
[[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
performAction:chrome_test_util::TapWebElementWithId(kFormElementCity)];
// This will fail if there is more than one profiles icon in the hierarchy.
[[EarlGrey selectElementWithMatcher:ManualFallbackFormSuggestionViewMatcher()]
performAction:grey_scrollToContentEdge(kGREYContentEdgeRight)];
[[EarlGrey selectElementWithMatcher:ManualFallbackProfilesIconMatcher()]
assertWithMatcher:grey_sufficientlyVisible()];
}
@end