// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import <XCTest/XCTest.h>
#import "base/functional/bind.h"
#import "base/ios/ios_util.h"
#import "base/strings/sys_string_conversions.h"
#import "base/test/ios/wait_util.h"
#import "components/omnibox/common/omnibox_features.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_app_interface.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_constants.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_earl_grey.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_test_util.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/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/app_launch_manager.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "net/test/embedded_test_server/embedded_test_server.h"
#import "net/test/embedded_test_server/http_request.h"
#import "net/test/embedded_test_server/http_response.h"
#import "ui/base/l10n/l10n_util_mac.h"
namespace {
/// Returns the popup row containing the `url` as suggestion.
id<GREYMatcher> PopupRowWithUrl(GURL url) {
NSString* urlString = base::SysUTF8ToNSString(url.GetContent());
id<GREYMatcher> URLMatcher = grey_allOf(
grey_descendant(
chrome_test_util::StaticTextWithAccessibilityLabel(urlString)),
grey_sufficientlyVisible(), nil);
return grey_allOf(chrome_test_util::OmniboxPopupRow(), URLMatcher, nil);
}
/// Returns the switch to open tab element for the `url`.
id<GREYMatcher> SwitchTabElementForUrl(const GURL& url) {
return grey_allOf(
grey_ancestor(PopupRowWithUrl(url)),
grey_accessibilityID(kOmniboxPopupRowSwitchTabAccessibilityIdentifier),
grey_interactable(), nil);
}
void TapSwitchToTabButton(const GURL& url) {
[[EarlGrey selectElementWithMatcher:grey_allOf(SwitchTabElementForUrl(url),
grey_interactable(), nil)]
performAction:grey_tap()];
}
id<GREYMatcher> OmniboxWithLeadingImageElement(
NSString* const leadingImageIdentifier) {
return grey_allOf(
grey_ancestor(grey_kindOfClassName(@"OmniboxContainerView")),
grey_accessibilityID(leadingImageIdentifier), grey_interactable(), nil);
}
void ScrollToSwitchToTabElement(const GURL& url) {
[[[EarlGrey selectElementWithMatcher:grey_allOf(SwitchTabElementForUrl(url),
grey_interactable(), nil)]
usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 200)
onElementWithMatcher:chrome_test_util::OmniboxPopupList()]
assertWithMatcher:grey_interactable()];
}
// Web page 1.
const char kPage1[] = "This is the first page";
const char kPage1Title[] = "Title 1";
const char kPage1URL[] = "/page1.html";
// Web page 2.
const char kPage2[] = "This is the second page";
const char kPage2Title[] = "Title 2";
const char kPage2URL[] = "/page2.html";
// Web page 2.
const char kPage3[] = "This is the third page";
const char kPage3Title[] = "Title 3";
const char kPage3URL[] = "/page3.html";
/// Provides responses for the different pages.
std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
const net::test_server::HttpRequest& request) {
std::unique_ptr<net::test_server::BasicHttpResponse> http_response =
std::make_unique<net::test_server::BasicHttpResponse>();
http_response->set_code(net::HTTP_OK);
if (request.relative_url == kPage1URL) {
http_response->set_content(
"<html><head><title>" + std::string(kPage1Title) +
"</title></head><body>" + std::string(kPage1) + "</body></html>");
return std::move(http_response);
}
if (request.relative_url == kPage2URL) {
http_response->set_content(
"<html><head><title>" + std::string(kPage2Title) +
"</title></head><body>" + std::string(kPage2) + "</body></html>");
return std::move(http_response);
}
if (request.relative_url == kPage3URL) {
http_response->set_content(
"<html><head><title>" + std::string(kPage3Title) +
"</title></head><body>" + std::string(kPage3) + "</body></html>");
return std::move(http_response);
}
return nil;
}
} // namespace
@interface OmniboxPopupTestCase : ChromeTestCase
@end
@implementation OmniboxPopupTestCase {
GURL _URL1;
GURL _URL2;
GURL _URL3;
}
- (AppLaunchConfiguration)appConfigurationForTestCase {
AppLaunchConfiguration config = [super appConfigurationForTestCase];
// Disable AutocompleteProvider types: TYPE_SEARCH and TYPE_ON_DEVICE_HEAD.
omnibox::DisableAutocompleteProviders(config, 1056);
return config;
}
- (void)setUp {
[super setUp];
// Start a server to be able to navigate to a web page.
self.testServer->RegisterRequestHandler(
base::BindRepeating(&StandardResponse));
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
_URL1 = self.testServer->GetURL(kPage1URL);
_URL2 = self.testServer->GetURL(kPage2URL);
_URL3 = self.testServer->GetURL(kPage3URL);
[ChromeEarlGrey clearBrowsingHistory];
}
// Tests that tapping the switch to open tab button, switch to the open tab,
// doesn't close the tab.
- (void)testSwitchToOpenTab {
// Open the first page.
GURL firstPageURL = self.testServer->GetURL(kPage1URL);
[ChromeEarlGrey loadURL:firstPageURL];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Open the second page in another tab.
[ChromeEarlGreyUI openNewTab];
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPage2URL)];
[ChromeEarlGrey waitForWebStateContainingText:kPage2];
// Type the URL of the first page in the omnibox to trigger it as suggestion.
[ChromeEarlGreyUI
focusOmniboxAndReplaceText:base::SysUTF8ToNSString(kPage1URL)];
// Switch to the first tab, scrolling the popup if necessary.
ScrollToSwitchToTabElement(firstPageURL);
TapSwitchToTabButton(firstPageURL);
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Check that both tabs are opened (and that we switched tab and not just
// navigated.
[ChromeEarlGreyUI openTabGrid];
[[EarlGrey
selectElementWithMatcher:
grey_allOf(chrome_test_util::StaticTextWithAccessibilityLabel(
base::SysUTF8ToNSString(kPage2Title)),
grey_ancestor(chrome_test_util::TabGridCellAtIndex(1)),
nil)] assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that the switch to open tab button isn't displayed for the current tab.
- (void)testNotSwitchButtonOnCurrentTab {
// Open the first page.
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPage1URL)];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Open the second page in another tab.
[ChromeEarlGreyUI openNewTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kPage2];
// Type the URL of the first page in the omnibox to trigger it as suggestion.
[ChromeEarlGreyUI
focusOmniboxAndReplaceText:base::SysUTF8ToNSString(kPage2URL)];
// Check that we have the suggestion for the second page, but not the switch
// as it is the current page.
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL2)]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:SwitchTabElementForUrl(_URL2)]
assertWithMatcher:grey_not(grey_interactable())];
}
// Test that swiping left on a historical suggestion and tapping
// the delete button , removes the suggestions.
- (void)testDeleteHistoricalSuggestion {
[self populateHistory];
NSString* omniboxInput = [NSString
stringWithFormat:@"%@:%@", base::SysUTF8ToNSString(_URL3.host()),
base::SysUTF8ToNSString(_URL3.port())];
[ChromeEarlGreyUI focusOmniboxAndReplaceText:omniboxInput];
// Swipe one of the historical suggestions, to the left.
if ([ChromeEarlGrey isIPadIdiom]) {
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)]
performAction:GREYSwipeSlowInDirectionWithStartPoint(kGREYDirectionLeft,
0.09, 0.5)];
} else {
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)]
performAction:grey_swipeSlowInDirection(kGREYDirectionLeft)];
}
// Delete button is displayed.
[[EarlGrey selectElementWithMatcher:grey_kindOfClassName(
@"UISwipeActionStandardButton")]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap on the delete button.
[[EarlGrey selectElementWithMatcher:grey_kindOfClassName(
@"UISwipeActionStandardButton")]
performAction:grey_tap()];
// Historical suggestion with URL1 is now deleted.
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)]
assertWithMatcher:grey_nil()];
}
// Tests that the incognito tabs aren't displayed as "opened" tab in the
// non-incognito suggestions and vice-versa.
- (void)testIncognitoSeparation {
[self populateHistory];
[[self class] closeAllTabs];
// Load page 1 in non-incognito and page 2 in incognito.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kPage2];
// Open page 3 in non-incognito.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL3];
[ChromeEarlGrey waitForWebStateContainingText:kPage3];
NSString* omniboxInput = [NSString
stringWithFormat:@"%@:%@", base::SysUTF8ToNSString(_URL3.host()),
base::SysUTF8ToNSString(_URL3.port())];
[ChromeEarlGreyUI focusOmniboxAndReplaceText:omniboxInput];
// Check that we have the switch button for the first page.
[[EarlGrey
selectElementWithMatcher:
grey_allOf(grey_ancestor(PopupRowWithUrl(_URL1)),
grey_accessibilityID(
kOmniboxPopupRowSwitchTabAccessibilityIdentifier),
nil)] assertWithMatcher:grey_sufficientlyVisible()];
// Check that we have the suggestion for the second page, but not the switch.
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL2)]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:SwitchTabElementForUrl(_URL2)]
assertWithMatcher:grey_nil()];
// Open page 3 in incognito.
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL3];
[ChromeEarlGrey waitForWebStateContainingText:kPage3];
[ChromeEarlGreyUI
focusOmniboxAndReplaceText:base::SysUTF8ToNSString(_URL3.host())];
// Check that we have the switch button for the second page.
[[EarlGrey
selectElementWithMatcher:
grey_allOf(grey_ancestor(PopupRowWithUrl(_URL2)),
grey_accessibilityID(
kOmniboxPopupRowSwitchTabAccessibilityIdentifier),
nil)] assertWithMatcher:grey_sufficientlyVisible()];
// Check that we have the suggestion for the first page, but not the switch.
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:SwitchTabElementForUrl(_URL1)]
assertWithMatcher:grey_nil()];
}
- (void)testCloseNTPWhenSwitching {
// Open the first page.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Open a new tab and switch to the first tab.
[ChromeEarlGrey openNewTab];
NSString* omniboxInput = [NSString
stringWithFormat:@"%@:%@", base::SysUTF8ToNSString(_URL1.host()),
base::SysUTF8ToNSString(_URL1.port())];
[[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
performAction:grey_tap()];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:chrome_test_util::Omnibox()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_replaceText(omniboxInput)];
TapSwitchToTabButton(_URL1);
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Check that the other tab is closed.
[ChromeEarlGrey waitForMainTabCount:1];
}
- (void)testDontCloseNTPWhenSwitchingWithForwardHistory {
// Open the first page.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Open a new tab, navigate to a page and go back to have forward history.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
[ChromeEarlGrey goBack];
// Navigate to the other tab.
[[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
performAction:grey_tap()];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:chrome_test_util::Omnibox()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_replaceText(base::SysUTF8ToNSString(_URL1.host()))];
// Omnibox can reorder itself in multiple animations, so add an extra wait
// here.
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:SwitchTabElementForUrl(
_URL1)];
[[EarlGrey selectElementWithMatcher:SwitchTabElementForUrl(_URL1)]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Check that the other tab is not closed.
[ChromeEarlGrey waitForMainTabCount:2];
}
// Tests that switching to closed tab opens the tab in foreground, except if it
// is from NTP without history.
- (void)testSwitchToClosedTab {
// Open the first page.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Open a new tab and load another URL.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:self.testServer->GetURL(kPage2URL)];
[ChromeEarlGrey waitForWebStateContainingText:kPage2];
// Start typing url of the first page.
[ChromeEarlGreyUI
focusOmniboxAndReplaceText:base::SysUTF8ToNSString(kPage1URL)];
// Make sure that the "Switch to Open Tab" element is visible, scrolling the
// popup if necessary.
ScrollToSwitchToTabElement(_URL1);
// Close the first page.
[ChromeEarlGrey closeTabAtIndex:0];
[ChromeEarlGrey waitForMainTabCount:1];
// Try to switch to the first tab.
TapSwitchToTabButton(_URL1);
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
[ChromeEarlGreyUI waitForAppToIdle];
// Check that the URL has been opened in a new foreground tab.
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
[ChromeEarlGrey waitForMainTabCount:2];
}
// Tests that having multiple suggestions with corresponding opened tabs display
// multiple buttons.
- (void)testMultiplePageOpened {
// Open the first page.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Open the second page in a new tab.
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kPage2];
// Start typing url of the two opened pages in a new tab.
[ChromeEarlGrey openNewTab];
NSString* omniboxInput = [NSString
stringWithFormat:@"%@:%@", base::SysUTF8ToNSString(_URL1.host()),
base::SysUTF8ToNSString(_URL1.port())];
[[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
performAction:grey_tap()];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:chrome_test_util::Omnibox()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_replaceText(omniboxInput)];
// Check that both elements are displayed.
// Omnibox can reorder itself in multiple animations, so add an extra wait
// here.
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:SwitchTabElementForUrl(
_URL1)];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:SwitchTabElementForUrl(
_URL2)];
}
// Tests that selecting a suggestion in the omnibox and successfully navigating
// to it adds an entry in the shortcuts database.
- (void)testShortcutsDatabasePopulation {
[ChromeEarlGrey clearBrowsingHistory];
// Ensure the database is initialized and empty.
[OmniboxEarlGrey waitForShortcutsBackendInitialization];
[OmniboxEarlGrey waitForNumberOfShortcutsInDatabase:0];
[self populateHistory];
NSString* omniboxInput = [NSString
stringWithFormat:@"%@:%@", base::SysUTF8ToNSString(_URL3.host()),
base::SysUTF8ToNSString(_URL3.port())];
[ChromeEarlGreyUI focusOmniboxAndReplaceText:omniboxInput];
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Verify that the shortcut database has been populated.
[OmniboxEarlGrey waitForNumberOfShortcutsInDatabase:1];
}
#pragma mark - Helpers
// Populate history by visiting the 3 different pages.
- (void)populateHistory {
// Add all the pages to the history.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kPage2];
[ChromeEarlGrey loadURL:_URL3];
[ChromeEarlGrey waitForWebStateContainingText:kPage3];
}
@end
@interface OmniboxPopupWithFakeSuggestionTestCase : ChromeTestCase
@end
@implementation OmniboxPopupWithFakeSuggestionTestCase
- (void)setUp {
[super setUp];
[ChromeEarlGrey clearBrowsingHistory];
[OmniboxAppInterface
setUpFakeSuggestionsService:@"fake_suggestions_pedal.json"];
}
- (void)tearDown {
[OmniboxAppInterface tearDownFakeSuggestionsService];
[super tearDown];
}
- (void)testTapAppendArrowButton {
[ChromeEarlGrey loadURL:GURL("about:blank")];
// Clears the url and replace it with local url host.
[ChromeEarlGreyUI focusOmniboxAndReplaceText:@"abc"];
// Wait for the suggestions to show.
[ChromeEarlGrey waitForUIElementToAppearWithMatcher:
chrome_test_util::OmniboxPopupRowWithString(@"abcdef")];
id<GREYMatcher> appendArrowButtonMatcher = grey_allOf(
grey_ancestor(chrome_test_util::OmniboxPopupRowWithString(@"abcdef")),
grey_accessibilityID(kOmniboxPopupRowAppendAccessibilityIdentifier), nil);
// Wait for the append button to show.
[ChromeEarlGrey waitForUIElementToAppearWithMatcher:appendArrowButtonMatcher];
// Tap on the append arrow button.
[[EarlGrey selectElementWithMatcher:grey_allOf(appendArrowButtonMatcher,
grey_interactable(), nil)]
performAction:grey_tap()];
// Omnibox should now contain the suggestion row string 'abcdef '.
[ChromeEarlGrey waitForUIElementToAppearWithMatcher:
chrome_test_util::OmniboxContainingText("abcdef ")];
// Wait for the new suggestions to show.
[ChromeEarlGrey
waitForUIElementToAppearWithMatcher:
chrome_test_util::OmniboxPopupRowWithString(@"abcdefghi")];
}
// Test when the popup is scrolled, the keyboard is dismissed
// but the omnibox is still expanded and the suggestions are visible.
- (void)testScrollingDismissesKeyboard {
[[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
performAction:grey_tap()];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:chrome_test_util::Omnibox()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_replaceText(@"abc")];
// Matcher for a URL-what-you-typed suggestion.
id<GREYMatcher> textMatcher = grey_descendant(
chrome_test_util::StaticTextWithAccessibilityLabel(@"abc"));
id<GREYMatcher> row =
grey_allOf(chrome_test_util::OmniboxPopupRow(), textMatcher,
grey_sufficientlyVisible(), nil);
// Omnibox can reorder itself in multiple animations, so add an extra wait
// here.
[ChromeEarlGrey waitForSufficientlyVisibleElementWithMatcher:row];
[ChromeEarlGrey waitForKeyboardToAppear];
// Scroll the popup. This swipes from the point located at 50% of the width of
// the frame horizontally and most importantly 10% of the height of the frame
// vertically. This is necessary if the center of the list's accessibility
// frame is not visible, as it is the default start point.
[[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxPopupList()]
performAction:grey_swipeFastInDirectionWithStartPoint(kGREYDirectionDown,
0.5, 0.1)];
[[EarlGrey selectElementWithMatcher:row]
assertWithMatcher:grey_sufficientlyVisible()];
// The keyboard should be dismissed.
[ChromeEarlGrey waitForKeyboardToDisappear];
}
@end
@interface HardwareKeyboardInteractionTestCase : ChromeTestCase
@end
@implementation HardwareKeyboardInteractionTestCase
- (void)setUp {
[super setUp];
[ChromeEarlGrey clearBrowsingHistory];
[OmniboxAppInterface
setUpFakeSuggestionsService:@"fake_suggestions_pedal.json"];
}
- (void)tearDown {
[OmniboxAppInterface tearDownFakeSuggestionsService];
[super tearDown];
// HW keyboard simulation does mess up the SW keyboard simulator state.
// Relaunching resets the state.
AppLaunchConfiguration config = [super appConfigurationForTestCase];
config.relaunch_policy = ForceRelaunchByCleanShutdown;
[[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config];
}
// Tests up down interaction in omnibox popup using a hardware keyboard.
- (void)testUpDownArrowAutocomplete {
// Focus omnibox from Web.
[ChromeEarlGrey loadURL:GURL("about:blank")];
[ChromeEarlGreyUI focusOmniboxAndReplaceText:@"testupdown"];
// Matcher for the first autocomplete suggestions.
id<GREYMatcher> testupDownAutocomplete1 =
chrome_test_util::OmniboxPopupRowWithString(@"testupdownautocomplete1");
// Wait for the suggestions to show.
[ChromeEarlGrey waitForUIElementToAppearWithMatcher:testupDownAutocomplete1];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
assertWithMatcher:chrome_test_util::OmniboxContainingText("testupdown")];
// The omnibox popup may update multiple times. Don't downArrow until this
// is done.
base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(1));
// Go down to testautocomplete1 popup row.
[ChromeEarlGrey simulatePhysicalKeyboardEvent:@"downArrow" flags:0];
[ChromeEarlGrey simulatePhysicalKeyboardEvent:@"downArrow" flags:0];
[ChromeEarlGrey
waitForUIElementToAppearWithMatcher:
chrome_test_util::OmniboxContainingText("testupdownautocomplete1")];
[ChromeEarlGrey simulatePhysicalKeyboardEvent:@"upArrow" flags:0];
[ChromeEarlGrey waitForUIElementToAppearWithMatcher:
chrome_test_util::OmniboxContainingText("testupdown")];
}
// Tests that leading image in omnibox changes based on the suggestion
// highlighted.
// TODO(crbug.com/40917341): Test is flaky on both device and simulator.
- (void)DISABLED_testOmniboxLeadingImage {
// Start a server to be able to navigate to a web page.
self.testServer->RegisterRequestHandler(
base::BindRepeating(&StandardResponse));
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
GURL _URL1 = self.testServer->GetURL(kPage1URL);
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Focus omnibox from Web.
[ChromeEarlGreyUI focusOmnibox];
// Typing the title of page1.
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_replaceText(base::SysUTF8ToNSString(kPage1Title))];
// Wait for suggestions to show.
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:PopupRowWithUrl(_URL1)];
// The omnibox popup may update multiple times. Don't downArrow until this
// is done.
base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(1));
[ChromeEarlGrey simulatePhysicalKeyboardEvent:@"downArrow" flags:0];
// We expect to have the default leading image.
[ChromeEarlGrey
waitForUIElementToAppearWithMatcher:
grey_allOf(OmniboxWithLeadingImageElement(
kOmniboxLeadingImageDefaultAccessibilityIdentifier),
nil)];
[ChromeEarlGrey simulatePhysicalKeyboardEvent:@"downArrow" flags:0];
// The popup row is a url suggestion so we expect to have the leading
// suggestion image .
[ChromeEarlGrey
waitForUIElementToAppearWithMatcher:
grey_allOf(
OmniboxWithLeadingImageElement(
kOmniboxLeadingImageSuggestionImageAccessibilityIdentifier),
nil)];
}
@end