blob: 8fc9b9f518fb02993b612cd30c01116b9277896a [file] [log] [blame]
// 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 "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_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"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
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()];
}
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];
auto bundledConfig = std::string("OmniboxBundledExperimentV1");
config.additional_args.push_back("--enable-features=" + bundledConfig + "<" +
bundledConfig);
config.additional_args.push_back("--force-fieldtrials=" + bundledConfig +
"/Test");
// Disable AutocompleteProvider types: TYPE_SEARCH and TYPE_ON_DEVICE_HEAD.
config.additional_args.push_back(
"--force-fieldtrial-params=" + bundledConfig +
".Test:" + "DisableProviders" + "/" + "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];
}
// Test inline autocomplete of legacy text field implementation.
// TODO(crbug.com/1445722): Re-enable when fixed.
- (void)DISABLED_testLegacyInlineAutocompleteSuggestion {
// Skip if new text field implementation is enabled.
if (base::FeatureList::IsEnabled(kIOSNewOmniboxImplementation)) {
return;
}
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kPage1];
// Clears the url and replace it with local url host.
[ChromeEarlGreyUI focusOmniboxAndType:base::SysUTF8ToNSString(_URL1.host())];
// We expect to have an autocomplete for URL1.
[[EarlGrey
selectElementWithMatcher:chrome_test_util::OmniboxAutocompleteLabel()]
assertWithMatcher:grey_sufficientlyVisible()];
// We expect to have a suggestion autocomplete.
[[EarlGrey selectElementWithMatcher:PopupRowWithUrl(_URL1)]
assertWithMatcher:grey_sufficientlyVisible()];
}
// 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 focusOmniboxAndType: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 focusOmniboxAndType: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 focusOmniboxAndType:omniboxInput];
// Swipe one of the historical suggestions, to the left.
[[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 focusOmniboxAndType: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 focusOmniboxAndType: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_typeText(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_typeText(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 focusOmniboxAndType: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_typeText(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)];
}
// Test that on iPhones, when the popup is scrolled, the keyboard is dismissed
// but the omnibox is still expanded and the suggestions are visible.
// Test with flag kEnableSuggestionsScrollingOnIPad disabled.
- (void)testScrollingDismissesKeyboardOnPhones {
[[AppLaunchManager sharedManager]
ensureAppLaunchedWithFeaturesEnabled:{}
disabled:{kEnableSuggestionsScrollingOnIPad}
relaunchPolicy:ForceRelaunchByCleanShutdown];
[[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
performAction:grey_tap()];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:chrome_test_util::Omnibox()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_typeText(@"hello")];
// Matcher for a URL-what-you-typed suggestion.
id<GREYMatcher> textMatcher = grey_descendant(
chrome_test_util::StaticTextWithAccessibilityLabel(@"hello"));
id<GREYMatcher> row =
grey_allOf(chrome_test_util::OmniboxPopupRow(), textMatcher, nil);
// Omnibox can reorder itself in multiple animations, so add an extra wait
// here.
[ChromeEarlGrey waitForUIElementToAppearWithMatcher:row];
GREYAssertTrue([EarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// 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_interactable()];
// The keyboard should only be dismissed on phones. Ipads, even in
// multitasking, are considered tall enough to fit all suggestions.
if ([ChromeEarlGrey isIPadIdiom]) {
GREYAssertTrue([EarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
} else {
GREYAssertFalse([EarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should not be Shown");
}
}
// Test when the popup is scrolled, the keyboard is dismissed
// but the omnibox is still expanded and the suggestions are visible.
// Test with flag kEnableSuggestionsScrollingOnIPad enabled.
- (void)testScrollingDismissesKeyboard {
[[AppLaunchManager sharedManager]
ensureAppLaunchedWithFeaturesEnabled:{kEnableSuggestionsScrollingOnIPad}
disabled:{}
relaunchPolicy:ForceRelaunchByCleanShutdown];
[[EarlGrey selectElementWithMatcher:chrome_test_util::FakeOmnibox()]
performAction:grey_tap()];
[ChromeEarlGrey
waitForSufficientlyVisibleElementWithMatcher:chrome_test_util::Omnibox()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
performAction:grey_typeText(@"hello")];
// Matcher for a URL-what-you-typed suggestion.
id<GREYMatcher> textMatcher = grey_descendant(
chrome_test_util::StaticTextWithAccessibilityLabel(@"hello"));
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];
GREYAssertTrue([EarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should be Shown");
// 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.
GREYAssertFalse([EarlGrey isKeyboardShownWithError:nil],
@"Keyboard Should not be Shown");
}
#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 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 focusOmniboxAndType:base::SysUTF8ToNSString("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")];
// 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")];
}
@end