chromium/ios/chrome/browser/autofill/ui_bundled/manual_fill/expanded_manual_fill_egtest.mm

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <string_view>

#import "base/strings/sys_string_conversions.h"
#import "components/autofill/core/browser/autofill_test_utils.h"
#import "components/password_manager/core/common/password_manager_features.h"
#import "ios/chrome/browser/autofill/ui_bundled/autofill_app_interface.h"
#import "ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_constants.h"
#import "ios/chrome/browser/autofill/ui_bundled/manual_fill/manual_fill_matchers.h"
#import "ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_app_interface.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h"
#import "ios/chrome/browser/ui/settings/password/password_settings_app_interface.h"
#import "ios/chrome/common/ui/elements/form_input_accessory_view.h"
#import "ios/chrome/grit/ios_strings.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_matchers.h"
#import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "net/test/embedded_test_server/default_handlers.h"
#import "ui/base/l10n/l10n_util.h"

using chrome_test_util::ButtonWithAccessibilityLabelId;
using manual_fill::ChipButton;
using manual_fill::ExpandedManualFillHeaderView;
using manual_fill::ExpandedManualFillView;
using manual_fill::KeyboardAccessoryManualFillButton;
using manual_fill::ManualFillDataType;
using manual_fill::SegmentedControlAddressTab;
using manual_fill::SegmentedControlPasswordTab;
using net::test_server::EmbeddedTestServer;

namespace {
constexpr char kAddressFormURL[] = "/profile_form.html";
constexpr char kMultiFieldFormURL[] = "/multi_field_form.html";
constexpr char kPaymentMethodFormURL[] = "/credit_card.html";
constexpr char kPasswordFormURL[] = "/simple_login_form.html";

const char kCardNameFieldID[] = "CCName";
const char kNameFieldID[] = "name";
const char kOtherStuffFieldID[] = "otherstuff";
const char kPasswordFieldID[] = "pw";

// Matcher for the close button.
id<GREYMatcher> CloseButton() {
  return grey_accessibilityLabel(l10n_util::GetNSString(
      IDS_IOS_EXPANDED_MANUAL_FILL_CLOSE_BUTTON_ACCESSIBILITY_LABEL));
}

id<GREYMatcher> ExpandedManualFillHeaderView() {
  return grey_accessibilityID(manual_fill::kExpandedManualFillHeaderViewID);
}

// Matcher for the segmented control's payment method tab.
id<GREYMatcher> SegmentedControlPaymentMethodTab() {
  return grey_allOf(
      grey_accessibilityLabel(l10n_util::GetNSString(
          IDS_IOS_EXPANDED_MANUAL_FILL_PAYMENT_TAB_ACCESSIBILITY_LABEL)),
      grey_ancestor(ExpandedManualFillHeaderView()), nil);
}

// Matcher for the keyboard accessory's password icon.
id<GREYMatcher> KeyboardAccessoryPasswordManualFillButton() {
  return grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString(
                        IDS_IOS_AUTOFILL_PASSWORD_AUTOFILL_DATA)),
                    grey_ancestor(grey_accessibilityID(
                        kFormInputAccessoryViewAccessibilityID)),
                    nil);
}

// Matcher for the password suggestion chip.
id<GREYMatcher> KeyboardAccessoryPasswordSuggestionChip() {
  return grey_text(@"concrete username");
}

// Checks that the chip button with `title` is sufficiently visible.
void CheckChipButtonVisibility(std::u16string title) {
  [[EarlGrey selectElementWithMatcher:ChipButton(title)]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Checks that the header view is as expected according to whether or not the
// device is in landscape mode.
void CheckHeader(bool is_landscape) {
  [[EarlGrey selectElementWithMatcher:ExpandedManualFillHeaderView()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // The header's top view should only be part of the UI when in portrait mode.
  id<GREYMatcher> header_top_view =
      grey_accessibilityID(manual_fill::kExpandedManualFillHeaderTopViewID);
  [[EarlGrey selectElementWithMatcher:header_top_view]
      assertWithMatcher:is_landscape ? grey_notVisible()
                                     : grey_sufficientlyVisible()];

  // Check Chrome logo and close button.
  id<GREYMatcher> chrome_logo;
  id<GREYMatcher> close_button;
  if (is_landscape) {
    chrome_logo =
        grey_accessibilityID(manual_fill::kExpandedManualFillChromeLogoID);
    close_button = grey_accessibilityLabel(l10n_util::GetNSString(
        IDS_IOS_EXPANDED_MANUAL_FILL_CLOSE_BUTTON_ACCESSIBILITY_LABEL));
  } else {
    // Chrome logo and close button should be placed inside the header's top
    // view in portrait mode.
    chrome_logo = grey_allOf(
        grey_accessibilityID(manual_fill::kExpandedManualFillChromeLogoID),
        grey_ancestor(header_top_view), nil);
    close_button = grey_allOf(
        grey_accessibilityLabel(l10n_util::GetNSString(
            IDS_IOS_EXPANDED_MANUAL_FILL_CLOSE_BUTTON_ACCESSIBILITY_LABEL)),
        grey_ancestor(header_top_view), nil);
  }

  [[EarlGrey selectElementWithMatcher:chrome_logo]
      assertWithMatcher:grey_sufficientlyVisible()];

  [[EarlGrey selectElementWithMatcher:close_button]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Check data type tabs.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPasswordTab()]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey selectElementWithMatcher:SegmentedControlPaymentMethodTab()]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey selectElementWithMatcher:SegmentedControlAddressTab()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Loads a form depending on the desired `data_type`.
void LoadForm(EmbeddedTestServer* test_server, ManualFillDataType data_type) {
  std::string_view form_url;
  std::string form_text;
  switch (data_type) {
    case ManualFillDataType::kPassword:
      form_url = kPasswordFormURL;
      form_text = "Login form.";
      break;
    case ManualFillDataType::kPaymentMethod:
      form_url = kPaymentMethodFormURL;
      form_text = "Autofill Test";
      break;
    case ManualFillDataType::kAddress:
      form_url = kAddressFormURL;
      form_text = "Profile form";
      break;
    case ManualFillDataType::kOther:
      form_url = kMultiFieldFormURL;
      form_text = "hello!";
      break;
  }

  [ChromeEarlGrey loadURL:test_server->GetURL(form_url)];
  [ChromeEarlGrey waitForWebStateContainingText:form_text];
}

// Saves a password for the login form.
void SavePasswordForLoginForm(EmbeddedTestServer* test_server) {
  [AutofillAppInterface
      savePasswordFormForURLSpec:base::SysUTF8ToNSString(
                                     test_server->GetURL(kPasswordFormURL)
                                         .spec())];
}

// Dismisses the payment bottom sheet by tapping the "Use Keyboard" button.
void DismissPaymentBottomSheet() {
  id<GREYMatcher> useKeyboardButton =
      chrome_test_util::ButtonWithAccessibilityLabelId(
          IDS_IOS_PAYMENT_BOTTOM_SHEET_USE_KEYBOARD);
  [[EarlGrey selectElementWithMatcher:useKeyboardButton]
      performAction:grey_tap()];
}

// Makes sure that the payment suggestions are appearing in the keyboard
// accessory.
void MakeSurePaymentMethodSuggestionsAreVisisble() {
  // Needed in order to see the payment method suggestions.
  [AutofillAppInterface considerCreditCardFormSecureForTesting];

  DismissPaymentBottomSheet();

  // Wait for the payment suggestions to appear after dismissing the payment
  // bottom sheet.
  autofill::CreditCard card = autofill::test::GetCreditCard();
  id<GREYMatcher> cc_chip = grey_text(base::SysUTF16ToNSString(card.GetInfo(
      autofill::CREDIT_CARD_NAME_FULL, l10n_util::GetLocaleOverride())));
  [ChromeEarlGrey waitForUIElementToAppearWithMatcher:cc_chip];
}

// Matcher for the "Autofill Form" button shown in the cells.
id<GREYMatcher> AutofillFormButton() {
  return grey_allOf(grey_accessibilityID(
                        manual_fill::kExpandedManualFillAutofillFormButtonID),
                    grey_interactable(), nullptr);
}

}  // namespace

// Test case for the expanded manual fill view.
@interface ExpandedManualFillTestCase : WebHttpServerChromeTestCase
@end

@implementation ExpandedManualFillTestCase

- (AppLaunchConfiguration)appConfigurationForTestCase {
  AppLaunchConfiguration config;
  config.relaunch_policy = ForceRelaunchByCleanShutdown;

  // Enable the Keyboard Accessory Upgrade feature.
  config.features_enabled.push_back(kIOSKeyboardAccessoryUpgrade);

  return config;
}

- (void)setUp {
  [super setUp];

  // The tested UI is not availble on iPad, so there's no need for any setup.
  if ([ChromeEarlGrey isIPadIdiom]) {
    return;
  }

  // Set up server.
  net::test_server::RegisterDefaultHandlers(self.testServer);
  GREYAssertTrue(self.testServer->Start(), @"Server did not start.");

  [AutofillAppInterface clearCreditCardStore];

  // Save a password, credit card and address.
  SavePasswordForLoginForm(self.testServer);
  [AutofillAppInterface saveLocalCreditCard];
  [AutofillAppInterface saveExampleAccountProfile];

  // Disable the password bottom sheet.
  [PasswordSuggestionBottomSheetAppInterface disableBottomSheet];

  // Mock successful reauth for opening the Password Manager.
  [PasswordSettingsAppInterface setUpMockReauthenticationModule];
  [PasswordSettingsAppInterface mockReauthenticationModuleExpectedResult:
                                    ReauthenticationResult::kSuccess];
}

- (void)tearDown {
  [super tearDown];

  // Clear the stores.
  [AutofillAppInterface clearProfilePasswordStore];
  [AutofillAppInterface clearCreditCardStore];
  [AutofillAppInterface clearProfilesStore];

  [PasswordSettingsAppInterface removeMockReauthenticationModule];
}

// Opens the expanded manual fill view for a given `dataType`. `fieldToFill` is
// the ID of the form field that should be focused prior to opening the expanded
// manual fill view.
- (void)openExpandedManualFillViewForDataType:(ManualFillDataType)dataType
                                  fieldToFill:(std::string)fieldToFill {
  // Load form.
  LoadForm(self.testServer, dataType);

  // Tap on the provided field.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
      performAction:chrome_test_util::TapWebElementWithId(fieldToFill)];

  if (dataType == ManualFillDataType::kPaymentMethod) {
    MakeSurePaymentMethodSuggestionsAreVisisble();
  }

  // Open the expanded manual fill view.
  [ChromeEarlGrey
      waitForUIElementToAppearWithMatcher:KeyboardAccessoryManualFillButton()];
  [[EarlGrey selectElementWithMatcher:KeyboardAccessoryManualFillButton()]
      performAction:grey_tap()];

  // Confirm that the expanded manual fill view is visible.
  [[EarlGrey selectElementWithMatcher:ExpandedManualFillView()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

- (void)openAllPasswordListFromPasswordTab {
  // Tap the "Select Password..." action.
  [[EarlGrey selectElementWithMatcher:manual_fill::OtherPasswordsMatcher()]
      performAction:grey_tap()];

  // Acknowledge concerns using other passwords on a website.
  id<GREYMatcher> confirmDialogButton =
      grey_allOf(ButtonWithAccessibilityLabelId(
                     IDS_IOS_CONFIRM_USING_OTHER_PASSWORD_CONTINUE),
                 grey_interactable(), nullptr);
  [[EarlGrey selectElementWithMatcher:confirmDialogButton]
      performAction:grey_tap()];

  // Verify that the all password list is visible.
  [[EarlGrey
      selectElementWithMatcher:manual_fill::OtherPasswordsDismissMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

#pragma mark - Tests

// Tests that the expanded manual fill view header is correctly laid out
// according to the device's orientation.
- (void)testExpandedManualFillViewDeviceOrientation {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPassword
                                  fieldToFill:kPasswordFieldID];

  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeRight
                                error:nil];
  CheckHeader(/*is_landscape=*/true);

  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
                                error:nil];
  CheckHeader(/*is_landscape=*/true);

  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait error:nil];
  CheckHeader(/*is_landscape=*/false);
}

// Tests that password manual filling options are visible when the expanded
// manual fill view is opened from a field for which there are password
// suggestions.
- (void)testOpeningExpandedManualFillViewForPassword {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for a password field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPassword
                                  fieldToFill:kPasswordFieldID];

  // The password view controller should be visible.
  [[EarlGrey selectElementWithMatcher:manual_fill::PasswordTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Tests that payment method manual filling options are visible when the
// expanded manual fill view is opened from a field for which there are payment
// method suggestions.
- (void)testOpeningExpandedManualFillViewForPaymentMethod {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for a payment method field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPaymentMethod
                                  fieldToFill:kCardNameFieldID];

  // The payment method view controller should be visible.
  [[EarlGrey selectElementWithMatcher:manual_fill::CreditCardTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Tests that address manual filling options are visible when the expanded
// manual fill view is opened from a field for which there are address
// suggestions.
- (void)testOpeningExpandedManualFillViewForAddress {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for an address field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kAddress
                                  fieldToFill:kNameFieldID];

  // The address view controller should be visible.
  [[EarlGrey selectElementWithMatcher:manual_fill::ProfilesTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Tests that the right manual filling options are visible when switching from
// one data type to the other.
- (void)testSwitchingDataTypes {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPassword
                                  fieldToFill:kPasswordFieldID];

  // Select the address tab and confirm that the address view controller is
  // visible.
  [[EarlGrey selectElementWithMatcher:SegmentedControlAddressTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:manual_fill::ProfilesTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Select the payment method tab and confirm that the payment method view
  // controller is visible.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPaymentMethodTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:manual_fill::CreditCardTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Select the password tab and confirm that the password view controller is
  // visible.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPasswordTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:manual_fill::PasswordTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Tests that tapping the close button hides the expanded manual fill view to
// show the keyboard and keyboard accessory bar.
- (void)testClosingExpandedManualFillView {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPassword
                                  fieldToFill:kPasswordFieldID];

  // Tap the close button.
  [[EarlGrey selectElementWithMatcher:CloseButton()] performAction:grey_tap()];

  // The expanded manual fill view should not be visible anymore.
  [[EarlGrey selectElementWithMatcher:ExpandedManualFillView()]
      assertWithMatcher:grey_notVisible()];

  // The keyboard accessory and keyboard should be visible.
  [ChromeEarlGrey waitForUIElementToAppearWithMatcher:
                      KeyboardAccessoryPasswordSuggestionChip()];
  [[EarlGrey selectElementWithMatcher:KeyboardAccessoryManualFillButton()]
      assertWithMatcher:grey_sufficientlyVisible()];
  [ChromeEarlGrey waitForKeyboardToAppear];
}

// Tests that saved passwords for the current site are visible even when the
// expanded manual fill view was not initially opened from a password form.
- (void)testPasswordsVisibleWhenOpenedFromDifferentDataType {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for an address field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kAddress
                                  fieldToFill:kNameFieldID];

  // Select the password tab and confirm that the password view controller is
  // visible.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPasswordTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:manual_fill::PasswordTableViewMatcher()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Confirm that the password option is visible.
  CheckChipButtonVisibility(u"concrete username");
}

// Tests that the "Autofill Form" button does not exist for the other data types
// than payments if a payments field is in focus.
- (void)testNoAutofillFormButtonForNonPaymentTypes {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for a payment field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPaymentMethod
                                  fieldToFill:kCardNameFieldID];

  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Navigate to the address tab and check that the "Autofill Form" button does
  // not exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlAddressTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Navigate to the password tab and check that the "Autofill Form" button does
  // not exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPasswordTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Navigate to the all password list and check that the "Autofill Form"
  // button does not exist.
  [self openAllPasswordListFromPasswordTab];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];
}

// Tests that the "Autofill Form" button does not exist for the other data types
// than addresses if an address field is in focus.
- (void)testNoAutofillFormButtonForNonAddressTypes {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for an address field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kAddress
                                  fieldToFill:kNameFieldID];

  // Scroll down and check that the "Autofill Form" button exists.
  [[EarlGrey selectElementWithMatcher:manual_fill::ProfilesTableViewMatcher()]
      performAction:grey_scrollToContentEdge(kGREYContentEdgeBottom)];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Navigate to the payment tab and check that the "Autofill Form" button does
  // not exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPaymentMethodTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Navigate to the password tab and check that the "Autofill Form" button does
  // not exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPasswordTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Navigate to the all password list and check that the "Autofill Form"
  // button does not exist.
  [self openAllPasswordListFromPasswordTab];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];
}

// Tests that the "Autofill Form" button does not exist for the other data types
// than passwords if a password field is in focus.
- (void)testNoAutofillFormButtonForNonPasswordTypes {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Open the expanded manual fill view for a password field.
  [self openExpandedManualFillViewForDataType:ManualFillDataType::kPassword
                                  fieldToFill:kPasswordFieldID];

  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_sufficientlyVisible()];

  // Navigate to the address tab and check that the "Autofill Form" button does
  // not exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlAddressTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Navigate to the payment tab and check that the "Autofill Form" button does
  // not exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPaymentMethodTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Go back to the password tab to open the all password list. Check that the
  // "Autofill Form" button exists.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPasswordTab()]
      performAction:grey_tap()];
  [self openAllPasswordListFromPasswordTab];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_sufficientlyVisible()];
}

// Tests that the "Autofill Form" button does not exist for all of the data
// types if the type of the focused field can't be associated with any of them.
- (void)testNoAutofillFormButtonForRandomType {
  if ([ChromeEarlGrey isIPadIdiom]) {
    EARL_GREY_TEST_SKIPPED(
        @"Expanded manual fill view is only available on iPhone.");
  }

  // Load form.
  LoadForm(self.testServer, ManualFillDataType::kOther);

  // Tap on a field that's not associated to password, payment or address.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()]
      performAction:chrome_test_util::TapWebElementWithId(kOtherStuffFieldID)];

  // Open the expanded manual fill view by tapping the password icon.
  [[EarlGrey
      selectElementWithMatcher:KeyboardAccessoryPasswordManualFillButton()]
      performAction:grey_tap()];

  // Check that the "Autofill Form" button does not exist.
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Move to the address tab and check that the "Autofill Form" button does not
  // exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlAddressTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];

  // Move to the payment tab and check that the "Autofill Form" button does not
  // exist.
  [[EarlGrey selectElementWithMatcher:SegmentedControlPaymentMethodTab()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:AutofillFormButton()]
      assertWithMatcher:grey_notVisible()];
}

@end