Index: ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm |
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3fd2754d90e2f3c5a113564865035cd2e50fcda2 |
--- /dev/null |
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_egtest.mm |
@@ -0,0 +1,309 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import <EarlGrey/EarlGrey.h> |
+#import <XCTest/XCTest.h> |
+ |
+#include "components/strings/grit/components_strings.h" |
+#import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
+#include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
+#import "ios/chrome/browser/ui/ntp/new_tab_page_controller.h" |
+#include "ios/chrome/browser/ui/ui_util.h" |
+#include "ios/chrome/grit/ios_strings.h" |
+#import "ios/chrome/test/app/chrome_test_util.h" |
+#import "ios/chrome/test/app/tab_test_util.h" |
+#import "ios/chrome/test/earl_grey/accessibility_util.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/disabled_test_macros.h" |
+#import "ios/testing/wait_util.h" |
+#include "ui/base/l10n/l10n_util.h" |
+ |
+@implementation NewTabPageController (ExposedForTesting) |
+- (GoogleLandingController*)googleLandingController { |
+ return googleLandingController_; |
+} |
+@end |
+ |
+@interface GoogleLandingController (ExposedForTesting) |
+- (BOOL)scrolledToTop; |
+@end |
+ |
+namespace { |
+ |
+void DismissNewTabPagePanel() { |
+ if (!IsIPadIdiom()) { |
+ id<GREYMatcher> matcher = grey_allOf(grey_accessibilityID(@"Exit"), |
+ grey_sufficientlyVisible(), nil); |
+ [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
+ } |
+} |
+ |
+// Pauses until the history label has disappeared. History should not show on |
+// incognito. |
+void WaitForHistoryToDisappear() { |
+ [[GREYCondition |
+ conditionWithName:@"Wait for history to disappear" |
+ block:^BOOL { |
+ NSError* error = nil; |
+ NSString* history = |
+ l10n_util::GetNSString(IDS_HISTORY_SHOW_HISTORY); |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel( |
+ history)] |
+ assertWithMatcher:grey_notVisible() |
+ error:&error]; |
+ return error == nil; |
+ }] waitWithTimeout:testing::kWaitForUIElementTimeout]; |
+} |
+ |
+// Displays the |panel_type| new tab page. An a phone this will send a command |
+// to display a dialog, on tablet this calls -selectPanel to slide the NTP. |
+void SelectNewTabPagePanel(NewTabPage::PanelIdentifier panel_type) { |
+ NewTabPageController* ntp_controller = |
+ chrome_test_util::GetCurrentNewTabPageController(); |
+ if (IsIPadIdiom()) { |
+ [ntp_controller selectPanel:panel_type]; |
+ } else { |
+ NSUInteger tag = 0; |
+ if (panel_type == NewTabPage::PanelIdentifier::kBookmarksPanel) { |
+ tag = IDC_SHOW_BOOKMARK_MANAGER; |
+ } else if (panel_type == NewTabPage::PanelIdentifier::kOpenTabsPanel) { |
+ tag = IDC_SHOW_OTHER_DEVICES; |
+ } |
+ if (tag) { |
+ base::scoped_nsobject<GenericChromeCommand> command( |
+ [[GenericChromeCommand alloc] initWithTag:tag]); |
+ chrome_test_util::RunCommandWithActiveViewController(command); |
+ } |
+ } |
+ [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
+} |
+ |
+void AssertNTPScrolledToTop(bool scrolledToTop) { |
+ [[GREYUIThreadExecutor sharedInstance] drainUntilIdle]; |
+ NewTabPageController* ntp_controller = |
+ chrome_test_util::GetCurrentNewTabPageController(); |
+ GoogleLandingController* google_landing_controller = |
+ [ntp_controller googleLandingController]; |
+ GREYAssertTrue([google_landing_controller scrolledToTop] == scrolledToTop, |
+ @"scrolledToTop_ does not match expected value"); |
+} |
+ |
+} // namespace |
+ |
+@interface UIWindow (Hidden) |
+- (UIResponder*)firstResponder; |
+@end |
+ |
+@interface NewTabPageTestCase : ChromeTestCase |
+@end |
+ |
+@implementation NewTabPageTestCase |
+ |
+// Tests that all items are accessible on the most visited page. |
+- (void)testAccessibilityOnMostVisited { |
+ SelectNewTabPagePanel(NewTabPage::kMostVisitedPanel); |
+ // TODO(crbug.com/640179): Implement and call |
+ chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
+} |
+ |
+// Tests that all items are accessible on the open tabs page. |
+- (void)testAccessibilityOnOpenTabs { |
+ SelectNewTabPagePanel(NewTabPage::kOpenTabsPanel); |
+ // TODO(crbug.com/640179): Implement and call |
+ chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
+ DismissNewTabPagePanel(); |
+} |
+ |
+// Tests that all items are accessible on the bookmarks page. |
+- (void)testAccessibilityOnBookmarks { |
+ SelectNewTabPagePanel(NewTabPage::kBookmarksPanel); |
+ // TODO(crbug.com/640179): Implement and call |
+ chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
+ DismissNewTabPagePanel(); |
+} |
+ |
+// Tests that all items are accessible on the incognito page. |
+- (void)testAccessibilityOnIncognitoTab { |
+ chrome_test_util::OpenNewIncognitoTab(); |
+ SelectNewTabPagePanel(NewTabPage::kIncognitoPanel); |
+ WaitForHistoryToDisappear(); |
+ // TODO(crbug.com/640179): Implement and call |
+ chrome_test_util::VerifyAccessibilityForCurrentScreen(); |
+ chrome_test_util::CloseAllIncognitoTabs(); |
+} |
+ |
+// Tests rotating the device when the NTP's omnibox is pinned to the top of the |
+// screen. |
+- (void)testRotation { |
+ // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is |
+ // fixed. |
+ if (IsIPadIdiom()) { |
+ EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug."); |
+ } |
+ |
+ NSString* ntpOmniboxLabel = l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT); |
+ NSString* focusedOmniboxLabel = l10n_util::GetNSString(IDS_ACCNAME_LOCATION); |
+ SelectNewTabPagePanel(NewTabPage::kMostVisitedPanel); |
+ AssertNTPScrolledToTop(NO); |
+ |
+ if (IsIPadIdiom()) { |
+ // Tap in omnibox to scroll it to the top of the screen. |
+ id<GREYMatcher> matcher = grey_accessibilityLabel(ntpOmniboxLabel); |
+ [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
+ } else { |
+ // Swipe up the NTP. The omnibox should be pinned at the top of the screen. |
+ id<GREYMatcher> matcher = grey_accessibilityID(@"Google Landing"); |
+ [[EarlGrey selectElementWithMatcher:matcher] |
+ performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; |
+ } |
+ AssertNTPScrolledToTop(YES); |
+ |
+ // Restore the orientation of the device to portrait in Teardown. |
+ [self setTearDownHandler:^{ |
+ if ([UIDevice currentDevice].orientation != UIDeviceOrientationPortrait) { |
+ [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait |
+ errorOrNil:nil]; |
+ } |
+ }]; |
+ |
+ // Rotate to landscape and check that the device and the status bar are |
+ // rotated properly and the omnibox is still scrolled up. |
+ [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft |
+ errorOrNil:nil]; |
+ GREYAssertTrue( |
+ [UIDevice currentDevice].orientation == UIDeviceOrientationLandscapeLeft, |
+ @"Device orientation should now be left landscape"); |
+ GREYAssertTrue([[UIApplication sharedApplication] statusBarOrientation] == |
+ UIInterfaceOrientationLandscapeRight, |
+ @"Status bar orientation should now be right landscape"); |
+ |
+ AssertNTPScrolledToTop(YES); |
+ |
+ // Tap in the omnibox. |
+ NSString* omniboxLabel = |
+ IsIPadIdiom() ? focusedOmniboxLabel : ntpOmniboxLabel; |
+ id<GREYMatcher> matcher = grey_allOf(grey_accessibilityLabel(omniboxLabel), |
+ grey_minimumVisiblePercent(0.2), nil); |
+ [[EarlGrey selectElementWithMatcher:matcher] performAction:grey_tap()]; |
+ |
+ // Rotate to portrait and check that the device and the status bar are rotated |
+ // properly and the omnibox is still scrolled up. |
+ [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait |
+ errorOrNil:nil]; |
+ GREYAssertTrue( |
+ [UIDevice currentDevice].orientation == UIDeviceOrientationPortrait, |
+ @"Device orientation should now be portrait"); |
+ GREYAssertTrue([[UIApplication sharedApplication] statusBarOrientation] == |
+ UIInterfaceOrientationPortrait, |
+ @"Status bar orientation should now be portrait"); |
+ |
+ AssertNTPScrolledToTop(YES); |
+ |
+ // Check that omnibox is still focused. |
+ UIResponder* firstResponder = |
+ [[UIApplication sharedApplication].keyWindow firstResponder]; |
+ BOOL equal = |
+ [[firstResponder accessibilityLabel] isEqualToString:focusedOmniboxLabel]; |
+ GREYAssertTrue( |
+ equal, |
+ @"Expected accessibility label for first responder to be '%@', got '%@'", |
+ focusedOmniboxLabel, [firstResponder accessibilityLabel]); |
+} |
+ |
+// Tests focusing and defocusing the NTP's omnibox. |
+- (void)testOmnibox { |
+ // Empty the pasteboard: if it contains a link the Google Landing will not be |
+ // interactable. |
+ [UIPasteboard generalPasteboard].string = @""; |
+ |
+ NSString* omniboxLabel = l10n_util::GetNSString(IDS_OMNIBOX_EMPTY_HINT); |
+ NSString* cancelLabel = l10n_util::GetNSString(IDS_CANCEL); |
+ if (IsIPadIdiom()) { |
+ SelectNewTabPagePanel(NewTabPage::kMostVisitedPanel); |
+ } |
+ |
+ // Check that the NTP is in its normal state. |
+ id<GREYMatcher> omnibox_matcher = |
+ grey_allOf(grey_accessibilityLabel(omniboxLabel), |
+ grey_minimumVisiblePercent(0.2), nil); |
+ [[EarlGrey selectElementWithMatcher:omnibox_matcher] |
+ assertWithMatcher:grey_notNil()]; |
+ AssertNTPScrolledToTop(NO); |
+ |
+ // Tap in omnibox to scroll it to the top of the screen. |
+ [[EarlGrey selectElementWithMatcher:omnibox_matcher] |
+ performAction:grey_tap()]; |
+ |
+ // Check that the omnibox is scrolled to the top of the screen and its cancel |
+ // button is visible. |
+ AssertNTPScrolledToTop(YES); |
+ |
+ if (!IsIPadIdiom()) { |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(cancelLabel)] |
+ assertWithMatcher:grey_notNil()]; |
+ } |
+ |
+ // Swipe down in the NTP to return to the normal state. |
+ id<GREYMatcher> landing_matcher = grey_accessibilityID(@"Google Landing"); |
+ [[EarlGrey selectElementWithMatcher:landing_matcher] |
+ performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; |
+ AssertNTPScrolledToTop(NO); |
+ if (!IsIPadIdiom()) { |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(cancelLabel)] |
+ assertWithMatcher:grey_notVisible()]; |
+ } |
+ |
+ // Tap in omnibox and check that it's scrolled to the top of the screen and |
+ // its cancel button is visible. |
+ [[EarlGrey selectElementWithMatcher:omnibox_matcher] |
+ performAction:grey_tap()]; |
+ AssertNTPScrolledToTop(YES); |
+ |
+ if (!IsIPadIdiom()) { |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(cancelLabel)] |
+ assertWithMatcher:grey_sufficientlyVisible()]; |
+ } |
+ // Tap below the omnibox to cancel editing and return to the normal state. |
+ [[EarlGrey selectElementWithMatcher:landing_matcher] |
+ performAction:grey_tap()]; |
+ AssertNTPScrolledToTop(NO); |
+ |
+ if (!IsIPadIdiom()) { |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(cancelLabel)] |
+ assertWithMatcher:grey_notVisible()]; |
+ } |
+} |
+ |
+// Tests that the NTP's toolbar is not visible when the NTP is scrolled up. |
+- (void)testScrollToolbar { |
+ if (IsIPadIdiom()) { |
+ EARL_GREY_TEST_SKIPPED(@"Skipped for iPad (no hidden toolbar in tablet)"); |
+ } |
+ |
+ NSString* tabSwitcherLabel = |
+ l10n_util::GetNSString(IDS_IOS_TOOLBAR_SHOW_TABS); |
+ NSString* toolsMenuLabel = l10n_util::GetNSString(IDS_IOS_TOOLBAR_SETTINGS); |
+ |
+ // Check that the toolbar's tab switcher and tools menu buttons are visible. |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(tabSwitcherLabel)] |
+ assertWithMatcher:grey_sufficientlyVisible()]; |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(toolsMenuLabel)] |
+ assertWithMatcher:grey_sufficientlyVisible()]; |
+ AssertNTPScrolledToTop(NO); |
+ |
+ // Swipe up the NTP. The omnibox should be fixed at the top of the screen. |
+ id<GREYMatcher> matcher = grey_accessibilityID(@"Google Landing"); |
+ [[EarlGrey selectElementWithMatcher:matcher] |
+ performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; |
+ AssertNTPScrolledToTop(YES); |
+ |
+ // Check that tab switcher and tools menu buttons are not on screen. |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(tabSwitcherLabel)] |
+ assertWithMatcher:grey_notVisible()]; |
+ [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(toolsMenuLabel)] |
+ assertWithMatcher:grey_notVisible()]; |
+} |
+ |
+@end |