// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/test/earl_grey/chrome_matchers_app_interface.h"
#import "base/apple/foundation_util.h"
#import "base/strings/string_number_conversions.h"
#import "base/strings/sys_string_conversions.h"
#import "components/safe_browsing/core/common/features.h"
#import "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/autofill/model/form_suggestion_constants.h"
#import "ios/chrome/browser/bookmarks/ui_bundled/bookmark_ui_constants.h"
#import "ios/chrome/browser/download/ui_bundled/download_manager_constants.h"
#import "ios/chrome/browser/history/ui_bundled/history_ui_constants.h"
#import "ios/chrome/browser/incognito_interstitial/ui_bundled/incognito_interstitial_constants.h"
#import "ios/chrome/browser/location_bar/ui_bundled/location_bar_constants.h"
#import "ios/chrome/browser/location_bar/ui_bundled/location_bar_steady_view.h"
#import "ios/chrome/browser/ntp/ui_bundled/new_tab_page_constants.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/shared/ui/symbols/symbols.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_cell.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_switch_item.h"
#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_url_item.h"
#import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
#import "ios/chrome/browser/ui/authentication/cells/signin_promo_view_constants.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
#import "ios/chrome/browser/ui/omnibox/keyboard_assist/omnibox_assistive_keyboard_views_utils.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_constants.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_ui_features.h"
#import "ios/chrome/browser/ui/omnibox/popup/omnibox_popup_accessibility_identifier_constants.h"
#import "ios/chrome/browser/ui/popup_menu/popup_menu_constants.h"
#import "ios/chrome/browser/ui/recent_tabs/recent_tabs_constants.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_view_controller.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/autofill/autofill_settings_constants.h"
#import "ios/chrome/browser/ui/settings/cells/clear_browsing_data_constants.h"
#import "ios/chrome/browser/ui/settings/clear_browsing_data/clear_browsing_data_ui_constants.h"
#import "ios/chrome/browser/ui/settings/google_services/google_services_settings_constants.h"
#import "ios/chrome/browser/ui/settings/google_services/manage_accounts/accounts_table_view_controller_constants.h"
#import "ios/chrome/browser/ui/settings/notifications/notifications_constants.h"
#import "ios/chrome/browser/ui/settings/notifications/tracking_price/tracking_price_constants.h"
#import "ios/chrome/browser/ui/settings/password/password_settings/password_settings_constants.h"
#import "ios/chrome/browser/ui/settings/password/passwords_table_view_constants.h"
#import "ios/chrome/browser/ui/settings/privacy/privacy_constants.h"
#import "ios/chrome/browser/ui/settings/privacy/privacy_table_view_controller.h"
#import "ios/chrome/browser/ui/settings/safety_check/safety_check_ui_swift.h"
#import "ios/chrome/browser/ui/settings/settings_navigation_controller.h"
#import "ios/chrome/browser/ui/settings/settings_navigation_controller_constants.h"
#import "ios/chrome/browser/ui/settings/settings_root_table_constants.h"
#import "ios/chrome/browser/ui/settings/settings_table_view_controller_constants.h"
#import "ios/chrome/browser/ui/settings/tabs/tabs_settings_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_groups/tab_groups_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_strip/ui/swift_constants_for_objective_c.h"
#import "ios/chrome/browser/ui/toolbar/primary_toolbar_view.h"
#import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h"
#import "ios/chrome/common/ui/promo_style/constants.h"
#import "ios/chrome/grit/ios_branded_strings.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/app/tab_test_util.h"
#import "ios/chrome/test/app/window_test_util.h"
#import "ios/testing/earl_grey/earl_grey_app.h"
#import "ios/web/public/test/earl_grey/web_view_matchers.h"
#import "ui/base/l10n/l10n_util.h"
#import "ui/base/test/ios/ui_image_test_utils.h"
namespace {
// Identifier the for cell at given `index` in the tab grid.
NSString* IdentifierForGridCellAtIndex(unsigned int index) {
return [NSString stringWithFormat:@"%@%u", kGridCellIdentifierPrefix, index];
}
// Identifier for the group cell at given `index` in the tab grid.
NSString* IdentifierForGridGroupCellAtIndex(unsigned int index) {
return [NSString
stringWithFormat:@"%@%u", kGroupGridCellIdentifierPrefix, index];
}
// Identifier the for cell at given `index` in the tab strip.
NSString* IdentifierForStripCellAtIndex(unsigned int index) {
return [NSString stringWithFormat:@"%@%u",
TabStripCollectionViewConstants
.tabStripTabCellPrefixIdentifier,
index];
}
// Identifier for the group cell at given `index` in the tab strip.
NSString* IdentifierForStripGroupCellAtIndex(unsigned int index) {
return [NSString stringWithFormat:@"%@%u",
TabStripCollectionViewConstants
.tabStripTabCellPrefixIdentifier,
index];
}
id<GREYMatcher> TableViewSwitchIsToggledOn(BOOL is_toggled_on) {
GREYMatchesBlock matches = ^BOOL(id element) {
TableViewSwitchCell* switch_cell =
base::apple::ObjCCastStrict<TableViewSwitchCell>(element);
UISwitch* switch_view = switch_cell.switchView;
return (switch_view.on && is_toggled_on) ||
(!switch_view.on && !is_toggled_on);
};
GREYDescribeToBlock describe = ^void(id<GREYDescription> description) {
NSString* name =
[NSString stringWithFormat:@"tableViewSwitchToggledState(%@)",
is_toggled_on ? @"ON" : @"OFF"];
[description appendText:name];
};
return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
}
id<GREYMatcher> TableViewSwitchIsEnabled(BOOL is_enabled) {
GREYMatchesBlock matches = ^BOOL(id element) {
TableViewSwitchCell* switch_cell =
base::apple::ObjCCastStrict<TableViewSwitchCell>(element);
UISwitch* switch_view = switch_cell.switchView;
return (switch_view.enabled && is_enabled) ||
(!switch_view.enabled && !is_enabled);
};
GREYDescribeToBlock describe = ^void(id<GREYDescription> description) {
NSString* name =
[NSString stringWithFormat:@"tableViewSwitchEnabledState(%@)",
is_enabled ? @"YES" : @"NO"];
[description appendText:name];
};
return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
}
// Returns the subview of `parentView` corresponding to the
// ContentSuggestionsViewController. Returns nil if it is not in its subviews.
UIView* SubviewWithAccessibilityIdentifier(NSString* accessibility_id,
UIView* parent_view) {
if (parent_view.accessibilityIdentifier == accessibility_id) {
return parent_view;
}
for (UIView* view in parent_view.subviews) {
UIView* result_view =
SubviewWithAccessibilityIdentifier(accessibility_id, view);
if (result_view)
return result_view;
}
return nil;
}
UIWindow* WindowWithAccessibilityIdentifier(NSString* accessibility_id) {
for (UIScene* scene in UIApplication.sharedApplication.connectedScenes) {
UIWindowScene* windowScene =
base::apple::ObjCCastStrict<UIWindowScene>(scene);
for (UIWindow* window in windowScene.windows) {
if ([window.accessibilityIdentifier isEqualToString:accessibility_id]) {
return window;
}
}
}
return nil;
}
} // namespace
@implementation ChromeMatchersAppInterface
+ (id<GREYMatcher>)windowWithNumber:(int)windowNumber {
return grey_allOf(
grey_accessibilityID([NSString stringWithFormat:@"%d", windowNumber]),
grey_kindOfClass([UIWindow class]), nil);
}
+ (id<GREYMatcher>)blockerWindowWithNumber:(int)windowNumber {
return grey_allOf(grey_accessibilityID([NSString
stringWithFormat:@"blocker-%d", windowNumber]),
grey_kindOfClass([UIWindow class]), nil);
}
+ (id<GREYMatcher>)buttonWithAccessibilityLabel:(NSString*)label {
return grey_allOf(grey_accessibilityLabel(label),
grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
}
+ (id<GREYMatcher>)buttonWithAccessibilityLabelID:(int)messageID {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabel:l10n_util::GetNSStringWithFixup(messageID)];
}
+ (id<GREYMatcher>)buttonWithAccessibilityLabelID:(int)messageID
numberForPlural:(int)number {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabel:l10n_util::GetPluralNSStringF(messageID,
number)];
}
+ (id<GREYMatcher>)buttonWithForegroundColor:(NSString*)colorName {
GREYMatchesBlock matches = ^BOOL(id element) {
if (![element isKindOfClass:UIButton.class]) {
return NO;
}
UIButton* button = base::apple::ObjCCastStrict<UIButton>(element);
return CGColorEqualToColor(
[UIColor colorNamed:colorName].CGColor,
button.configuration.baseForegroundColor.CGColor);
};
NSString* descriptionString =
[NSString stringWithFormat:@"Foreground color %@", colorName];
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:descriptionString];
};
id<GREYMatcher> foregroundColorMatcher =
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
return grey_allOf(grey_accessibilityTrait(UIAccessibilityTraitButton),
foregroundColorMatcher, nil);
}
+ (id<GREYMatcher>)buttonWithBackgroundColor:(NSString*)colorName {
GREYMatchesBlock matches = ^BOOL(id element) {
if (![element isKindOfClass:UIButton.class]) {
return NO;
}
UIButton* button = base::apple::ObjCCastStrict<UIButton>(element);
return CGColorEqualToColor(
[UIColor colorNamed:colorName].CGColor,
button.configuration.background.backgroundColor.CGColor);
};
NSString* descriptionString =
[NSString stringWithFormat:@"Background color %@", colorName];
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:descriptionString];
};
id<GREYMatcher> backgroundColorMatcher =
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
return grey_allOf(grey_accessibilityTrait(UIAccessibilityTraitButton),
backgroundColorMatcher, nil);
}
+ (id<GREYMatcher>)contextMenuItemWithAccessibilityLabel:(NSString*)label {
return grey_allOf(grey_accessibilityLabel(label),
grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
}
+ (id<GREYMatcher>)contextMenuItemWithAccessibilityLabelID:(int)messageID {
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabel:l10n_util::GetNSStringWithFixup(
messageID)];
}
+ (id<GREYMatcher>)imageViewWithImageNamed:(NSString*)imageName {
UIImage* expectedImage = [UIImage imageNamed:imageName];
GREYMatchesBlock matches = ^BOOL(UIImageView* imageView) {
return ui::test::uiimage_utils::UIImagesAreEqual(expectedImage,
imageView.image);
};
NSString* descriptionString =
[NSString stringWithFormat:@"Images matching image named %@", imageName];
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:descriptionString];
};
id<GREYMatcher> imageMatcher =
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
return imageMatcher;
}
+ (id<GREYMatcher>)imageViewWithCustomSymbolNamed:(NSString*)symbolName
pointSize:(CGFloat)pointSize {
UIImage* expectedImage =
CustomSymbolTemplateWithPointSize(symbolName, pointSize);
GREYMatchesBlock matches = ^BOOL(UIImageView* imageView) {
return ui::test::uiimage_utils::UIImagesAreEqual(expectedImage,
imageView.image);
};
NSString* descriptionString = [NSString
stringWithFormat:@"Images matching custom symbol named %@ of size %f",
symbolName, pointSize];
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:descriptionString];
};
id<GREYMatcher> imageMatcher =
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
return imageMatcher;
}
+ (id<GREYMatcher>)imageViewWithImage:(UIImage*)image {
GREYMatchesBlock matches = ^BOOL(UIImageView* imageView) {
return ui::test::uiimage_utils::UIImagesAreEqual(image, imageView.image);
};
NSString* descriptionString =
[NSString stringWithFormat:@"Images matching image %@", image];
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:descriptionString];
};
id<GREYMatcher> imageMatcher =
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
return imageMatcher;
}
+ (id<GREYMatcher>)buttonWithImage:(int)imageID {
UIImage* expectedImage = NativeImage(imageID);
GREYMatchesBlock matches = ^BOOL(UIButton* button) {
return ui::test::uiimage_utils::UIImagesAreEqual(expectedImage,
[button currentImage]);
};
NSString* descriptionString =
[NSString stringWithFormat:@"Images matching %i", imageID];
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:descriptionString];
};
id<GREYMatcher> imageMatcher =
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
return grey_allOf(grey_accessibilityTrait(UIAccessibilityTraitButton),
imageMatcher, nil);
}
+ (id<GREYMatcher>)staticTextWithAccessibilityLabelID:(int)messageID {
return [ChromeMatchersAppInterface
staticTextWithAccessibilityLabel:(l10n_util::GetNSStringWithFixup(
messageID))];
}
+ (id<GREYMatcher>)staticTextWithAccessibilityLabel:(NSString*)label {
return grey_allOf(grey_accessibilityLabel(label),
grey_accessibilityTrait(UIAccessibilityTraitStaticText),
nil);
}
+ (id<GREYMatcher>)headerWithAccessibilityLabelID:(int)messageID {
return [ChromeMatchersAppInterface
headerWithAccessibilityLabel:(l10n_util::GetNSStringWithFixup(
messageID))];
}
+ (id<GREYMatcher>)headerWithAccessibilityLabel:(NSString*)label {
return grey_allOf(grey_accessibilityLabel(label),
grey_accessibilityTrait(UIAccessibilityTraitHeader),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)navigationBarTitleWithAccessibilityLabelID:(int)labelID {
return grey_allOf(
grey_accessibilityID(l10n_util::GetNSStringWithFixup(labelID)),
grey_kindOfClass([UINavigationBar class]), nil);
}
+ (id<GREYMatcher>)textFieldForCellWithLabelID:(int)messageID {
return grey_allOf(grey_accessibilityID([l10n_util::GetNSStringWithFixup(
messageID) stringByAppendingString:@"_textField"]),
grey_kindOfClass([UITextField class]), nil);
}
+ (id<GREYMatcher>)iconViewForCellWithLabelID:(int)messageID
iconType:(NSString*)iconType {
return grey_allOf(grey_accessibilityID([l10n_util::GetNSStringWithFixup(
messageID) stringByAppendingString:iconType]),
grey_kindOfClass([UIImageView class]), nil);
}
+ (id<GREYMatcher>)primaryToolbar {
return grey_kindOfClass([PrimaryToolbarView class]);
}
+ (id<GREYMatcher>)cancelButton {
return
[ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_CANCEL)];
}
+ (id<GREYMatcher>)navigationBarCancelButton {
return grey_allOf(
grey_ancestor(grey_kindOfClass([UINavigationBar class])),
[self cancelButton],
grey_not(grey_accessibilityTrait(UIAccessibilityTraitNotEnabled)), nil);
}
+ (id<GREYMatcher>)closeTabMenuButton {
return grey_allOf(
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
(IDS_IOS_CONTENT_CONTEXT_CLOSETAB)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)forwardButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_ACCNAME_FORWARD)];
}
+ (id<GREYMatcher>)backButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_ACCNAME_BACK)];
}
+ (id<GREYMatcher>)reloadButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_ACCNAME_RELOAD)];
}
+ (id<GREYMatcher>)stopButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_ACCNAME_STOP)];
}
+ (id<GREYMatcher>)omnibox {
return grey_allOf(grey_kindOfClass([OmniboxTextFieldIOS class]),
grey_userInteractionEnabled(), nil);
}
+ (id<GREYMatcher>)omniboxAtBottom {
return grey_allOf(
[ChromeMatchersAppInterface defocusedLocationView],
grey_ancestor(grey_kindOfClassName(@"SecondaryToolbarView")),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)omniboxOnTop {
return grey_allOf([ChromeMatchersAppInterface defocusedLocationView],
grey_ancestor(grey_kindOfClassName(@"PrimaryToolbarView")),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)defocusedLocationView {
return grey_kindOfClass([LocationBarSteadyView class]);
}
+ (id<GREYMatcher>)pageSecurityInfoButton {
return grey_accessibilityLabel(@"Page Security Info");
}
+ (id<GREYMatcher>)pageSecurityInfoIndicator {
return grey_allOf(
grey_accessibilityLabel(@"Page Security Info"),
grey_ancestor(grey_kindOfClass([LocationBarSteadyView class])), nil);
}
+ (id<GREYMatcher>)omniboxText:(NSString*)text {
GREYElementMatcherBlock* matcher = [GREYElementMatcherBlock
matcherWithMatchesBlock:^BOOL(id element) {
OmniboxTextFieldIOS* omnibox =
base::apple::ObjCCast<OmniboxTextFieldIOS>(element);
return [omnibox.text isEqualToString:text];
}
descriptionBlock:^void(id<GREYDescription> description) {
[description
appendText:[NSString stringWithFormat:@"Omnibox contains text '%@'",
text]];
}];
return matcher;
}
+ (id<GREYMatcher>)omniboxContainingText:(NSString*)text {
GREYElementMatcherBlock* matcher = [GREYElementMatcherBlock
matcherWithMatchesBlock:^BOOL(id element) {
OmniboxTextFieldIOS* omnibox =
base::apple::ObjCCast<OmniboxTextFieldIOS>(element);
return [omnibox.text containsString:text];
}
descriptionBlock:^void(id<GREYDescription> description) {
[description
appendText:[NSString stringWithFormat:@"Omnibox contains text '%@'",
text]];
}];
return matcher;
}
+ (id<GREYMatcher>)omniboxContainingAutocompleteText:(NSString*)text {
if (!text) {
text = @"";
}
GREYElementMatcherBlock* matcher = [GREYElementMatcherBlock
matcherWithMatchesBlock:^BOOL(id element) {
OmniboxTextFieldIOS* omnibox =
base::apple::ObjCCast<OmniboxTextFieldIOS>(element);
NSArray* textComponents =
[omnibox.accessibilityValue componentsSeparatedByString:@"||||"];
return textComponents.count >= 2 &&
[textComponents[1] isEqualToString:text];
}
descriptionBlock:^void(id<GREYDescription> description) {
[description
appendText:[NSString stringWithFormat:
@"Omnibox contains autocomplete text '%@'",
text]];
}];
return matcher;
}
+ (id<GREYMatcher>)locationViewContainingText:(NSString*)text {
GREYElementMatcherBlock* matcher = [GREYElementMatcherBlock
matcherWithMatchesBlock:^BOOL(LocationBarSteadyView* element) {
return [element.locationLabel.text containsString:text];
}
descriptionBlock:^void(id<GREYDescription> description) {
[description
appendText:[NSString
stringWithFormat:
@"LocationBarSteadyView contains text '%@'",
text]];
}];
return matcher;
}
+ (id<GREYMatcher>)toolsMenuButton {
return grey_allOf(grey_accessibilityID(kToolbarToolsMenuButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)openNewTabButton {
return grey_allOf(
[ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_TOOLS_MENU_NEW_TAB)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)shareButton {
return grey_allOf(
[ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:(IDS_IOS_TOOLS_MENU_SHARE)],
grey_not([self tabShareButton]), grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)showFullURLFromWebContextMenu {
return grey_allOf(
[ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:
(IDS_IOS_SHARE_FULL_URL_BUTTON_ACCESSIBILITY_LABEL)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabShareButton {
return grey_allOf(
grey_anyOf(grey_accessibilityID(kToolbarShareButtonIdentifier),
grey_accessibilityID(kOmniboxShareButtonIdentifier), nil),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)showTabsButton {
return grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)addToReadingListButton {
return grey_allOf([ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:
(IDS_IOS_CONTENT_CONTEXT_ADDTOREADINGLIST)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)addToBookmarksButton {
return grey_allOf(
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
(IDS_IOS_CONTENT_CONTEXT_ADDTOBOOKMARKS)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tableViewSwitchCell:(NSString*)accessibilityIdentifier
isToggledOn:(BOOL)isToggledOn {
return [ChromeMatchersAppInterface tableViewSwitchCell:accessibilityIdentifier
isToggledOn:isToggledOn
isEnabled:YES];
}
+ (id<GREYMatcher>)tableViewSwitchCell:(NSString*)accessibilityIdentifier
isToggledOn:(BOOL)isToggledOn
isEnabled:(BOOL)isEnabled {
return grey_allOf(grey_accessibilityID(accessibilityIdentifier),
TableViewSwitchIsToggledOn(isToggledOn),
TableViewSwitchIsEnabled(isEnabled),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)syncSwitchCell:(NSString*)accessibilityLabel
isToggledOn:(BOOL)isToggledOn {
return grey_allOf(
grey_accessibilityLabel(accessibilityLabel),
grey_accessibilityValue(
isToggledOn ? l10n_util::GetNSString(IDS_IOS_SETTING_ON)
: l10n_util::GetNSString(IDS_IOS_SETTING_OFF)),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)openLinkInNewTabButton {
return
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB)];
}
+ (id<GREYMatcher>)openLinkInIncognitoButton {
int stringId = IDS_IOS_OPEN_IN_INCOGNITO_ACTION_TITLE;
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:(stringId)];
}
+ (id<GREYMatcher>)openLinkInNewWindowButton {
return
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
IDS_IOS_CONTENT_CONTEXT_OPENINNEWWINDOW];
}
+ (id<GREYMatcher>)navigationBarDoneButton {
return grey_allOf(
[ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_NAVIGATION_BAR_DONE_BUTTON)],
grey_userInteractionEnabled(), grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)bookmarksNavigationBarDoneButton {
return grey_accessibilityID(kBookmarksHomeNavigationBarDoneButtonIdentifier);
}
+ (id<GREYMatcher>)bookmarksNavigationBarBackButton {
UINavigationBar* navBar = base::apple::ObjCCastStrict<UINavigationBar>(
SubviewWithAccessibilityIdentifier(kBookmarkNavigationBarIdentifier,
GetAnyKeyWindow()));
return grey_allOf(grey_buttonTitle(navBar.backItem.title),
grey_ancestor(grey_kindOfClass([UINavigationBar class])),
nil);
}
+ (id<GREYMatcher>)addAccountButton {
return grey_accessibilityID(kSettingsAccountsTableViewAddAccountCellId);
}
+ (id<GREYMatcher>)signOutAccountsButton {
return grey_accessibilityID(kSettingsAccountsTableViewSignoutCellId);
}
+ (id<GREYMatcher>)clearBrowsingDataCell {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_CLEAR_BROWSING_DATA_TITLE)];
}
+ (id<GREYMatcher>)clearBrowsingDataButton {
return grey_accessibilityID(kClearBrowsingDataButtonIdentifier);
}
+ (id<GREYMatcher>)clearBrowsingDataView {
return grey_accessibilityID(kClearBrowsingDataViewAccessibilityIdentifier);
}
+ (id<GREYMatcher>)confirmClearBrowsingDataButton {
return grey_allOf(
grey_accessibilityLabel(l10n_util::GetNSString(IDS_IOS_CLEAR_BUTTON)),
grey_accessibilityTrait(UIAccessibilityTraitButton),
grey_not(grey_accessibilityID(kClearBrowsingDataButtonIdentifier)),
grey_userInteractionEnabled(), nil);
}
+ (id<GREYMatcher>)settingsDoneButton {
return grey_accessibilityID(kSettingsDoneButtonId);
}
+ (id<GREYMatcher>)autofillCreditCardEditTableView {
return grey_accessibilityID(kAutofillCreditCardEditTableViewId);
}
+ (id<GREYMatcher>)addressesAndMoreButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_AUTOFILL_ADDRESSES_SETTINGS_TITLE)];
}
+ (id<GREYMatcher>)paymentMethodsButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_AUTOFILL_PAYMENT_METHODS)];
}
+ (id<GREYMatcher>)languagesButton {
return grey_accessibilityID(kSettingsLanguagesCellId);
}
+ (id<GREYMatcher>)addCreditCardView {
return grey_accessibilityID(kAddCreditCardViewID);
}
+ (id<GREYMatcher>)autofillCreditCardTableView {
return grey_accessibilityID(kAutofillCreditCardTableViewId);
}
+ (id<GREYMatcher>)addCreditCardButton {
return grey_accessibilityID(kSettingsAddCreditCardButtonID);
}
+ (id<GREYMatcher>)addCreditCardCancelButton {
return grey_accessibilityID(kSettingsAddCreditCardCancelButtonID);
}
+ (id<GREYMatcher>)toolsMenuView {
return grey_accessibilityID(kPopupMenuToolsMenuTableViewId);
}
+ (id<GREYMatcher>)omniboxPopupRow {
return grey_kindOfClassName(@"UITableViewCell");
}
+ (id<GREYMatcher>)omniboxPopupRowWithString:(NSString*)string {
id<GREYMatcher> textMatcher = grey_descendant(
[ChromeMatchersAppInterface staticTextWithAccessibilityLabel:string]);
id<GREYMatcher> popupRow =
grey_allOf([ChromeMatchersAppInterface omniboxPopupRow], textMatcher,
grey_sufficientlyVisible(), nil);
return popupRow;
}
+ (id<GREYMatcher>)omniboxPopupList {
return grey_accessibilityID(kOmniboxPopupTableViewAccessibilityIdentifier);
}
+ (id<GREYMatcher>)OKButton {
return [ChromeMatchersAppInterface buttonWithAccessibilityLabelID:(IDS_OK)];
}
+ (id<GREYMatcher>)primarySignInButton {
return grey_allOf(grey_accessibilityID(kSigninPromoPrimaryButtonId),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)secondarySignInButton {
return grey_allOf(grey_accessibilityID(kSigninPromoSecondaryButtonId),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)identityChooserScrim {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_TOOLBAR_CLOSE_MENU)];
}
+ (id<GREYMatcher>)fakeFakeAddAccountScreenCancelButton {
return grey_allOf(grey_buttonTitle(@"Cancel"), grey_sufficientlyVisible(),
nil);
}
+ (id<GREYMatcher>)settingsAccountButton {
return grey_accessibilityID(kSettingsAccountCellId);
}
+ (id<GREYMatcher>)settingsAccountsCollectionView {
return grey_accessibilityID(kSettingsLegacyAccountsTableViewId);
}
+ (id<GREYMatcher>)settingsSafetyCheckTableView {
return grey_accessibilityID(
SafetyCheckTableViewController.accessibilityIdentifier);
}
+ (id<GREYMatcher>)settingsPrivacyTableView {
return grey_accessibilityID(kPrivacyTableViewId);
}
+ (id<GREYMatcher>)settingsPrivacySafeBrowsingTableView {
return grey_accessibilityID(kPrivacySafeBrowsingTableViewId);
}
+ (id<GREYMatcher>)settingsNotificationsTableView {
return grey_accessibilityID(kNotificationsTableViewId);
}
+ (id<GREYMatcher>)settingsInactiveTabsTableView {
return grey_accessibilityID(kInactiveTabsSettingsTableViewId);
}
+ (id<GREYMatcher>)settingsTabsTableView {
return grey_accessibilityID(kTabsSettingsTableViewId);
}
+ (id<GREYMatcher>)settingsTrackingPriceTableView {
return grey_accessibilityID(kTrackingPriceTableViewId);
}
+ (id<GREYMatcher>)contentSettingsButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_CONTENT_SETTINGS_TITLE)];
}
+ (id<GREYMatcher>)googleServicesSettingsButton {
return grey_allOf(grey_kindOfClass([UITableViewCell class]),
grey_accessibilityID(kSettingsGoogleServicesCellId),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)inactiveTabsSettingsButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_OPTIONS_MOVE_INACTIVE_TABS)];
}
+ (id<GREYMatcher>)tabsSettingsButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_TABS_MANAGEMENT_SETTINGS)];
}
+ (id<GREYMatcher>)manageSyncSettingsButton {
return grey_allOf(grey_kindOfClass([UITableViewCell class]),
grey_accessibilityID(kSettingsGoogleSyncAndServicesCellId),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)googleServicesSettingsView {
return grey_accessibilityID(kGoogleServicesSettingsViewIdentifier);
}
+ (id<GREYMatcher>)settingsNavigationBar {
return grey_allOf(
grey_kindOfClass([UINavigationBar class]),
grey_accessibilityID(
password_manager::kSettingsNavigationBarAccessibilityID),
nil);
}
+ (id<GREYMatcher>)settingsMenuBackButton:(NSString*)buttonTitle {
return grey_allOf(
grey_anyOf(grey_accessibilityLabel(buttonTitle),
grey_accessibilityLabel(@"Back"), grey_buttonTitle(@"Back"),
grey_descendant(grey_buttonTitle(buttonTitle)), nil),
grey_kindOfClassName(@"_UIButtonBarButton"),
grey_ancestor(grey_kindOfClass([UINavigationBar class])), nil);
}
+ (id<GREYMatcher>)settingsMenuBackButton {
UINavigationBar* navBar = base::apple::ObjCCastStrict<UINavigationBar>(
SubviewWithAccessibilityIdentifier(
password_manager::kSettingsNavigationBarAccessibilityID,
GetAnyKeyWindow()));
return
[ChromeMatchersAppInterface settingsMenuBackButton:navBar.backItem.title];
}
+ (id<GREYMatcher>)settingsMenuBackButtonInWindowWithNumber:(int)windowNumber {
UINavigationBar* navBar = base::apple::ObjCCastStrict<UINavigationBar>(
SubviewWithAccessibilityIdentifier(
password_manager::kSettingsNavigationBarAccessibilityID,
WindowWithAccessibilityIdentifier(
[NSString stringWithFormat:@"%d", windowNumber])));
return
[ChromeMatchersAppInterface settingsMenuBackButton:navBar.backItem.title];
}
+ (id<GREYMatcher>)settingsMenuPrivacyButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_SETTINGS_PRIVACY_TITLE)];
}
+ (id<GREYMatcher>)settingsMenuNotificationsButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:(IDS_IOS_NOTIFICATIONS_TITLE)];
}
+ (id<GREYMatcher>)settingsMenuPasswordsButton {
return grey_accessibilityID(kSettingsPasswordsCellId);
}
+ (id<GREYMatcher>)settingsMenuSafetyCheckButton {
return grey_accessibilityID(kSettingsSafetyCheckCellId);
}
// TODO(crbug.com/40106317): Remove this stub.
+ (id<GREYMatcher>)paymentRequestView {
return nil;
}
// TODO(crbug.com/40106317): Remove this stub.
+ (id<GREYMatcher>)paymentRequestErrorView {
return nil;
}
+ (id<GREYMatcher>)voiceSearchButton {
return grey_allOf(grey_accessibilityID(kSettingsVoiceSearchCellId),
grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
}
+ (id<GREYMatcher>)voiceSearchInputAccessoryButton {
return grey_accessibilityID(kVoiceSearchInputAccessoryViewID);
}
+ (id<GREYMatcher>)settingsCollectionView {
return grey_allOf(grey_accessibilityID(kSettingsTableViewId),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)clearBrowsingHistoryButton {
// Needs to use grey_sufficientlyVisible() to make the difference between a
// cell used by the tableview and a invisible recycled cell.
return grey_allOf(
grey_accessibilityID(kClearBrowsingHistoryCellAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)historyTableView {
return grey_accessibilityID(kHistoryTableViewIdentifier);
}
+ (id<GREYMatcher>)clearCookiesButton {
// Needs to use grey_sufficientlyVisible() to make the difference between a
// cell used by the tableview and a invisible recycled cell.
return grey_allOf(
grey_accessibilityID(kClearCookiesCellAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)clearCacheButton {
// Needs to use grey_sufficientlyVisible() to make the difference between a
// cell used by the tableview and a invisible recycled cell.
return grey_allOf(
grey_accessibilityID(kClearCacheCellAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)clearSavedPasswordsButton {
// Needs to use grey_sufficientlyVisible() to make the difference between a
// cell used by the tableview and a invisible recycled cell.
return grey_allOf(
grey_accessibilityID(kClearSavedPasswordsCellAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)clearAutofillButton {
// Needs to use grey_sufficientlyVisible() to make the difference between a
// cell used by the tableview and a invisible recycled cell.
return grey_allOf(
grey_accessibilityID(kClearAutofillCellAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)contentSuggestionCollectionView {
return grey_accessibilityID(kContentSuggestionsCollectionIdentifier);
}
+ (id<GREYMatcher>)ntpCollectionView {
return grey_accessibilityID(kNTPCollectionViewIdentifier);
}
+ (id<GREYMatcher>)ntpIncognitoView {
return grey_accessibilityID(kNTPIncognitoViewIdentifier);
}
+ (id<GREYMatcher>)ntpFeedMenuEnableButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:IDS_IOS_DISCOVER_FEED_MENU_TURN_ON_ITEM];
}
+ (id<GREYMatcher>)ntpFeedMenuDisableButton {
return [ChromeMatchersAppInterface
buttonWithAccessibilityLabelID:IDS_IOS_DISCOVER_FEED_MENU_TURN_OFF_ITEM];
}
// TODO(crbug.com/40106317): Remove this stub.
+ (id<GREYMatcher>)warningMessageView {
return nil;
}
// TODO(crbug.com/40106317): Remove this stub.
+ (id<GREYMatcher>)paymentRequestPickerRow {
return nil;
}
// TODO(crbug.com/40106317): Remove this stub.
+ (id<GREYMatcher>)paymentRequestPickerSearchBar {
return nil;
}
+ (id<GREYMatcher>)openNewWindowMenuButton {
return grey_accessibilityID(kToolsMenuNewWindowId);
}
+ (id<GREYMatcher>)copyActivityButton {
id<GREYMatcher> copyStaticText = [ChromeMatchersAppInterface
staticTextWithAccessibilityLabel:l10n_util::GetNSString(
IDS_IOS_SHARE_MENU_COPY)];
return grey_allOf(
copyStaticText,
grey_ancestor(grey_kindOfClassName(@"UIActivityActionGroupCell")), nil);
}
+ (id<GREYMatcher>)copyLinkButton {
int stringId = IDS_IOS_COPY_LINK_ACTION_TITLE;
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:stringId];
}
+ (id<GREYMatcher>)editButton {
int stringId = IDS_IOS_EDIT_ACTION_TITLE;
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:stringId];
}
+ (id<GREYMatcher>)moveButton {
return [ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
IDS_IOS_BOOKMARK_CONTEXT_MENU_MOVE];
}
+ (id<GREYMatcher>)readingListMarkAsReadButton {
return
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
IDS_IOS_READING_LIST_MARK_AS_READ_ACTION];
}
+ (id<GREYMatcher>)readingListMarkAsUnreadButton {
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:
IDS_IOS_READING_LIST_MARK_AS_UNREAD_ACTION];
}
+ (id<GREYMatcher>)deleteButton {
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:IDS_IOS_DELETE_ACTION_TITLE];
}
+ (id<GREYMatcher>)contextMenuCopyButton {
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:(IDS_IOS_CONTENT_CONTEXT_COPY)];
}
+ (id<GREYMatcher>)NTPOmnibox {
return grey_allOf(
grey_accessibilityLabel(l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT)),
grey_minimumVisiblePercent(0.2), nil);
}
+ (id<GREYMatcher>)fakeOmnibox {
return grey_accessibilityID(ntp_home::FakeOmniboxAccessibilityID());
}
+ (id<GREYMatcher>)discoverHeaderLabel {
return grey_accessibilityID(ntp_home::DiscoverHeaderTitleAccessibilityID());
}
+ (id<GREYMatcher>)ntpLogo {
return grey_accessibilityID(ntp_home::NTPLogoAccessibilityID());
}
+ (id<GREYMatcher>)webViewMatcher {
return web::WebViewInWebState(chrome_test_util::GetCurrentWebState());
}
+ (id<GREYMatcher>)webStateScrollViewMatcher {
return web::WebViewScrollView(chrome_test_util::GetCurrentWebState());
}
+ (id<GREYMatcher>)webStateScrollViewMatcherInWindowWithNumber:
(int)windowNumber {
return web::WebViewScrollView(
chrome_test_util::GetCurrentWebStateForWindowWithNumber(windowNumber));
}
+ (id<GREYMatcher>)historyClearBrowsingDataButton {
return grey_accessibilityID(kHistoryToolbarClearBrowsingButtonIdentifier);
}
+ (id<GREYMatcher>)openInButton {
return grey_allOf(
grey_accessibilityID(kDownloadManagerOpenInAccessibilityIdentifier),
grey_interactable(), nil);
}
+ (id<GREYMatcher>)openPDFButton {
return grey_allOf(
grey_accessibilityID(kDownloadManagerOpenAccessibilityIdentifier),
grey_interactable(), nil);
}
+ (id<GREYMatcher>)tabGridCellAtIndex:(unsigned int)index {
return grey_allOf(grey_accessibilityID(IdentifierForGridCellAtIndex(index)),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridGroupCellAtIndex:(unsigned int)index {
return grey_allOf(
grey_accessibilityID(IdentifierForGridGroupCellAtIndex(index)),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridGroupCellWithName:(NSString*)groupName
count:(NSInteger)count {
return grey_allOf(
grey_accessibilityLabel(l10n_util::GetNSStringF(
IDS_IOS_TAB_GROUP_CELL_ACCESSIBILITY_TITLE,
base::SysNSStringToUTF16(groupName), base::NumberToString16(count))),
grey_kindOfClassName(@"GroupGridCell"), grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabStripCellAtIndex:(unsigned int)index {
return grey_allOf(grey_accessibilityID(IdentifierForStripCellAtIndex(index)),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabStripGroupCellAtIndex:(unsigned int)index {
return grey_allOf(
grey_accessibilityID(IdentifierForStripGroupCellAtIndex(index)),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridDoneButton {
return grey_allOf(grey_accessibilityID(kTabGridDoneButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridCloseAllButton {
return grey_allOf(grey_accessibilityID(kTabGridCloseAllButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridUndoCloseAllButton {
return grey_allOf(grey_accessibilityID(kTabGridUndoCloseAllButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridSelectShowHistoryCell {
return grey_allOf(grey_accessibilityID(
kRecentTabsShowFullHistoryCellAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridRegularTabsEmptyStateView {
return grey_allOf(
grey_accessibilityID(kTabGridRegularTabsEmptyStateIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridNewTabButton {
return grey_allOf(
[self buttonWithAccessibilityLabelID:IDS_IOS_TAB_GRID_CREATE_NEW_TAB],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridNewIncognitoTabButton {
return grey_allOf([self buttonWithAccessibilityLabelID:
IDS_IOS_TAB_GRID_CREATE_NEW_INCOGNITO_TAB],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridOpenTabsPanelButton {
return grey_accessibilityID(kTabGridRegularTabsPageButtonIdentifier);
}
+ (id<GREYMatcher>)tabGridIncognitoTabsPanelButton {
return grey_accessibilityID(kTabGridIncognitoTabsPageButtonIdentifier);
}
+ (id<GREYMatcher>)tabGridOtherDevicesPanelButton {
return grey_accessibilityID(kTabGridRemoteTabsPageButtonIdentifier);
}
+ (id<GREYMatcher>)tabGroupSnackBar:(NSInteger)tabGroupCount {
NSString* messageLabel =
base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16(
IDS_IOS_TAB_GROUP_SNACKBAR_LABEL, tabGroupCount));
return grey_allOf(
grey_accessibilityID(@"MDCSnackbarMessageTitleAutomationIdentifier"),
grey_text(messageLabel), nil);
}
+ (id<GREYMatcher>)tabGridTabGroupsPanelButton {
return grey_accessibilityID(kTabGridTabGroupsPageButtonIdentifier);
}
+ (id<GREYMatcher>)tabGridThirdPanelButton {
if (IsTabGroupSyncEnabled()) {
return [self tabGridTabGroupsPanelButton];
}
return [self tabGridOtherDevicesPanelButton];
}
+ (id<GREYMatcher>)tabGridNormalModePageControl {
return grey_allOf(
grey_kindOfClassName(@"UIControl"),
grey_descendant(
[ChromeMatchersAppInterface tabGridIncognitoTabsPanelButton]),
grey_descendant([ChromeMatchersAppInterface tabGridOpenTabsPanelButton]),
grey_descendant([ChromeMatchersAppInterface tabGridThirdPanelButton]),
grey_ancestor(grey_kindOfClassName(@"UIToolbar")),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridInactiveTabsButton {
return grey_allOf(
grey_accessibilityID(kInactiveTabsButtonAccessibilityIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridBackground {
return grey_accessibilityID(kGridBackgroundIdentifier);
}
+ (id<GREYMatcher>)regularTabGrid {
return grey_accessibilityID(kRegularTabGridIdentifier);
}
+ (id<GREYMatcher>)incognitoTabGrid {
return grey_accessibilityID(kIncognitoTabGridIdentifier);
}
+ (id<GREYMatcher>)tabGridCloseButtonForCellAtIndex:(unsigned int)index {
return grey_allOf(
grey_ancestor(grey_accessibilityID(IdentifierForGridCellAtIndex(index))),
grey_accessibilityID(kGridCellCloseButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridCloseButtonForGroupCellAtIndex:(unsigned int)index {
return grey_allOf(grey_ancestor(grey_accessibilityID(
IdentifierForGridGroupCellAtIndex(index))),
grey_accessibilityID(kGridCellCloseButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)settingsPasswordMatcher {
return grey_accessibilityID(kPasswordsSettingsTableViewId);
}
+ (id<GREYMatcher>)settingsPasswordSearchMatcher {
return grey_accessibilityID(kPasswordsSearchBarID);
}
+ (id<GREYMatcher>)settingsProfileMatcher {
return grey_accessibilityID(kAutofillProfileTableViewID);
}
+ (id<GREYMatcher>)settingsCreditCardMatcher {
return grey_accessibilityID(kAutofillCreditCardTableViewId);
}
+ (id<GREYMatcher>)autofillSuggestionViewMatcher {
return grey_accessibilityID(kFormSuggestionLabelAccessibilityIdentifier);
}
+ (id<GREYMatcher>)settingsBottomToolbarDeleteButton {
return grey_accessibilityID(kSettingsToolbarDeleteButtonId);
}
+ (id<GREYMatcher>)settingsSearchEngineButton {
return grey_accessibilityID(kSettingsSearchEngineCellId);
}
+ (id<GREYMatcher>)settingsAddressBarButton {
return grey_accessibilityID(kSettingsAddressBarCellId);
}
+ (id<GREYMatcher>)contentViewSmallerThanScrollView {
GREYMatchesBlock matches = ^BOOL(UIView* view) {
UIScrollView* scrollView = base::apple::ObjCCast<UIScrollView>(view);
return scrollView &&
scrollView.contentSize.height < scrollView.bounds.size.height;
};
GREYDescribeToBlock describe = ^void(id<GREYDescription> description) {
[description
appendText:@"Not a scroll view or the scroll view content is bigger "
@"than the scroll view bounds"];
};
return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
}
+ (id<GREYMatcher>)historyEntryForURL:(NSString*)URL title:(NSString*)title {
GREYMatchesBlock matches = ^BOOL(TableViewURLCell* cell) {
return [cell.titleLabel.text isEqualToString:title] &&
[cell.URLLabel.text isEqualToString:URL];
};
GREYDescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:@"view containing URL text: "];
[description appendText:URL];
[description appendText:@" title text: "];
[description appendText:title];
};
return grey_allOf(
grey_kindOfClass([TableViewURLCell class]),
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)settingsToolbarAddButton {
return grey_accessibilityID(kSettingsToolbarAddButtonId);
}
+ (id<GREYMatcher>)cellCanBeSwipedToDismissed {
GREYMatchesBlock matches = ^BOOL(id element) {
if (![element isKindOfClass:UITableViewCell.class])
return NO;
UITableViewCell* cell =
base::apple::ObjCCastStrict<UITableViewCell>(element);
// Try to find the TableView containing the cell.
UIView* potential_table_view = [cell superview];
while (![potential_table_view isKindOfClass:UITableView.class] &&
potential_table_view.superview) {
potential_table_view = potential_table_view.superview;
}
if (![potential_table_view isKindOfClass:UITableView.class])
return NO;
UITableView* table_view =
base::apple::ObjCCastStrict<UITableView>(potential_table_view);
NSIndexPath* index_path = [table_view indexPathForCell:cell];
return [table_view.dataSource tableView:table_view
canEditRowAtIndexPath:index_path];
};
GREYDescribeToBlock describe = ^void(id<GREYDescription> description) {
[description appendText:@"cellCanBeSwipedToDismissed"];
};
return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
}
+ (id<GREYMatcher>)passwordsTableViewMatcher {
return grey_accessibilityID(kPasswordsTableViewID);
}
+ (id<GREYMatcher>)defaultBrowserSettingsTableViewMatcher {
return grey_accessibilityID(kDefaultBrowserSettingsTableViewId);
}
+ (id<GREYMatcher>)safetyCheckTableViewMatcher {
return grey_accessibilityID(
SafetyCheckTableViewController.accessibilityIdentifier);
}
#pragma mark - Overflow Menu Destinations
+ (id<GREYMatcher>)bookmarksDestinationButton {
return grey_accessibilityID(kToolsMenuBookmarksId);
}
+ (id<GREYMatcher>)downloadsDestinationButton {
return grey_accessibilityID(kToolsMenuDownloadsId);
}
+ (id<GREYMatcher>)historyDestinationButton {
return grey_accessibilityID(kToolsMenuHistoryId);
}
+ (id<GREYMatcher>)passwordsDestinationButton {
return grey_accessibilityID(kToolsMenuPasswordsId);
}
+ (id<GREYMatcher>)priceNotificationsDestinationButton {
return grey_anyOf(
grey_accessibilityID(kToolsMenuPriceNotifications),
grey_accessibilityID([NSString
stringWithFormat:@"%@-newBadge", kToolsMenuPriceNotifications]),
nullptr);
}
+ (id<GREYMatcher>)readingListDestinationButton {
return grey_accessibilityID(kToolsMenuReadingListId);
}
+ (id<GREYMatcher>)recentTabsDestinationButton {
return grey_accessibilityID(kToolsMenuOtherDevicesId);
}
+ (id<GREYMatcher>)settingsDestinationButton {
// The settings button could have a dot or something on it, changing its ID to
// "kToolsMenuSettingsId - Dot" or something else. The matcher needs to be
// adapted to match both.
GREYMatchesBlock matches = ^BOOL(id element) {
return [[element accessibilityIdentifier] hasPrefix:kToolsMenuSettingsId];
};
GREYDescribeToBlock describe = ^void(id<GREYDescription> description) {
[description appendText:[NSString stringWithFormat:@"starts with('%@')",
kToolsMenuSettingsId]];
};
return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe];
}
+ (id<GREYMatcher>)siteInfoDestinationButton {
return grey_accessibilityID(kToolsMenuSiteInformation);
}
+ (id<GREYMatcher>)whatsNewDestinationButton {
return grey_accessibilityID(kToolsMenuWhatsNewId);
}
#pragma mark - Overflow Menu Actions
+ (id<GREYMatcher>)settingsActionButton {
return grey_accessibilityID(kToolsMenuSettingsActionId);
}
#pragma mark - Promo style view controller
// Returns matcher for the primary action button.
+ (id<GREYMatcher>)promoStylePrimaryActionButtonMatcher {
return grey_accessibilityID(kPromoStylePrimaryActionAccessibilityIdentifier);
}
// Returns matcher for the secondary action button.
+ (id<GREYMatcher>)promoStyleSecondaryActionButtonMatcher {
return grey_accessibilityID(
kPromoStyleSecondaryActionAccessibilityIdentifier);
}
#pragma mark - Incognito Interstitial
+ (id<GREYMatcher>)incognitoInterstitial {
return grey_accessibilityID(kIncognitoInterstitialAccessibilityIdentifier);
}
+ (id<GREYMatcher>)incognitoInterstitialLabelForURL:(NSString*)url {
return grey_allOf(grey_accessibilityID(
kIncognitoInterstitialURLLabelAccessibilityIdentifier),
grey_accessibilityLabel(url), nullptr);
}
+ (id<GREYMatcher>)incognitoInterstitialOpenInChromeIncognitoButton {
return grey_allOf(
[ChromeMatchersAppInterface promoStylePrimaryActionButtonMatcher],
grey_accessibilityLabel(l10n_util::GetNSString(
IDS_IOS_INCOGNITO_INTERSTITIAL_OPEN_IN_CHROME_INCOGNITO)),
nullptr);
}
+ (id<GREYMatcher>)incognitoInterstitialOpenInChromeButton {
return grey_allOf(
[ChromeMatchersAppInterface promoStyleSecondaryActionButtonMatcher],
grey_accessibilityLabel(l10n_util::GetNSString(
IDS_IOS_INCOGNITO_INTERSTITIAL_OPEN_IN_CHROME)),
nullptr);
}
+ (id<GREYMatcher>)incognitoInterstitialCancelButton {
return grey_accessibilityID(
kIncognitoInterstitialCancelButtonAccessibilityIdentifier);
}
#pragma mark - Manual Fallback
+ (id<GREYMatcher>)activityViewHeaderWithURLHost:(NSString*)host
title:(NSString*)pageTitle {
// The title of the activity view starts as the URL, then asynchronously
// changes to the page title. Sometimes, the activity view fails to update
// the text to the page title, causing test flake. Allow matcher to pass
// with either value for the activity view title.
GREYMatchesBlock matches = ^BOOL(id element) {
NSString* label = [element accessibilityLabel];
NSLog(@"label is %@ %d %d", label, [label containsString:host],
[label containsString:pageTitle]);
return [label containsString:host] || [label containsString:pageTitle];
};
GREYDescribeToBlock describe = ^void(id<GREYDescription> description) {
[description
appendText:[NSString stringWithFormat:
@"accessibilityLabel containing %@ or %@",
host, pageTitle]];
};
return grey_allOf(
grey_kindOfClassName(@"LPLinkView"),
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe],
nil);
}
+ (id<GREYMatcher>)useSuggestedPasswordMatcher {
return grey_allOf(
[self
buttonWithAccessibilityLabelID:IDS_IOS_USE_SUGGESTED_STRONG_PASSWORD],
grey_interactable(), nullptr);
}
#pragma mark - Tab Grid Selection Mode
+ (id<GREYMatcher>)tabGridEditButton {
return grey_accessibilityID(kTabGridEditButtonIdentifier);
}
+ (id<GREYMatcher>)tabGridEditMenuCloseAllButton {
int ID = IsTabGroupSyncEnabled()
? IDS_IOS_CONTENT_CONTEXT_CLOSEALLTABSANDGROUPS
: IDS_IOS_CONTENT_CONTEXT_CLOSEALLTABS;
return grey_allOf(
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:ID],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridSelectTabsMenuButton {
return grey_allOf(
[ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
(IDS_IOS_CONTENT_CONTEXT_SELECTTABS)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridEditAddToButton {
return grey_allOf(grey_accessibilityID(kTabGridEditAddToButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridEditCloseTabsButton {
return grey_allOf(grey_accessibilityID(kTabGridEditCloseTabsButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridEditSelectAllButton {
return grey_allOf(grey_accessibilityID(kTabGridEditSelectAllButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridEditShareButton {
return grey_allOf(grey_accessibilityID(kTabGridEditShareButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
#pragma mark - Tab Grid Search Mode
+ (id<GREYMatcher>)tabGridSearchTabsButton {
return grey_allOf(grey_accessibilityID(kTabGridSearchButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridSearchBar {
return grey_allOf(grey_accessibilityID(kTabGridSearchBarIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridSearchCancelButton {
return grey_allOf(grey_accessibilityID(kTabGridCancelButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGridSearchModeToolbar {
return grey_allOf(
grey_kindOfClassName(@"UIToolbar"),
grey_descendant([ChromeMatchersAppInterface tabGridSearchBar]),
grey_descendant([ChromeMatchersAppInterface tabGridSearchCancelButton]),
grey_sufficientlyVisible(), nil);
}
#pragma mark - Create Tab Group View
+ (id<GREYMatcher>)tabGroupCreationView {
return grey_allOf(grey_accessibilityID(kCreateTabGroupViewIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)createTabGroupTextField {
return grey_allOf(grey_accessibilityID(kCreateTabGroupTextFieldIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)createTabGroupTextFieldClearButton {
return grey_allOf(
grey_accessibilityID(kCreateTabGroupTextFieldClearButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)createTabGroupCreateButton {
return grey_allOf(grey_accessibilityID(kCreateTabGroupCreateButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)createTabGroupCancelButton {
return grey_allOf(grey_accessibilityID(kCreateTabGroupCancelButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
#pragma mark - Tab Group View
+ (id<GREYMatcher>)tabGroupView {
return grey_allOf(grey_accessibilityID(kTabGroupViewIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGroupViewTitle:(NSString*)title {
return grey_allOf(grey_accessibilityID(kTabGroupViewTitleIdentifier),
grey_accessibilityLabel(title), nil);
}
+ (id<GREYMatcher>)tabGroupOverflowMenuButton {
return grey_allOf(grey_accessibilityID(kTabGroupOverflowMenuButtonIdentifier),
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)tabGroupBackButton {
return grey_allOf(
[ChromeMatchersAppInterface
buttonWithAccessibilityLabel:l10n_util::GetNSString(
IDS_IOS_ICON_ARROW_BACK)],
grey_kindOfClassName(@"UIAccessibilityBackButtonElement"), nil);
}
#pragma mark - Tab Groups Context Menus
+ (id<GREYMatcher>)addTabToNewGroupButton {
return grey_allOf(
[ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabel:
l10n_util::GetPluralNSStringF(
IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP, 1)],
grey_sufficientlyVisible(), nil);
}
+ (id<GREYMatcher>)addTabToGroupSubMenuButton {
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:
IDS_IOS_CONTENT_CONTEXT_ADDTABTONEWTABGROUP_SUBMENU];
}
+ (id<GREYMatcher>)renameGroupButton {
return [ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
IDS_IOS_CONTENT_CONTEXT_RENAMEGROUP];
}
+ (id<GREYMatcher>)ungroupButton {
return [ChromeMatchersAppInterface
contextMenuItemWithAccessibilityLabelID:IDS_IOS_CONTENT_CONTEXT_UNGROUP];
}
+ (id<GREYMatcher>)ungroupConfirmationButton {
return grey_allOf(grey_accessibilityID(
[l10n_util::GetNSString(IDS_IOS_CONTENT_CONTEXT_UNGROUP)
stringByAppendingString:@"AlertAction"]),
grey_interactable(), nil);
}
+ (id<GREYMatcher>)deleteGroupButton {
return [ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
IDS_IOS_CONTENT_CONTEXT_DELETEGROUP];
}
+ (id<GREYMatcher>)deleteGroupConfirmationButton {
return grey_allOf(grey_accessibilityID([l10n_util::GetNSString(
IDS_IOS_CONTENT_CONTEXT_DELETEGROUP)
stringByAppendingString:@"AlertAction"]),
grey_interactable(), nil);
}
+ (id<GREYMatcher>)closeGroupButton {
return [ChromeMatchersAppInterface contextMenuItemWithAccessibilityLabelID:
IDS_IOS_CONTENT_CONTEXT_CLOSEGROUP];
}
@end