| Index: ios/chrome/browser/ui/stack_view/stack_view_egtest.mm
|
| diff --git a/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm b/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5a7c5c473f92d32a57f0a8389820643f2c42ab31
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/stack_view/stack_view_egtest.mm
|
| @@ -0,0 +1,249 @@
|
| +// 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 <XCTest/XCTest.h>
|
| +
|
| +#include "base/ios/block_types.h"
|
| +#include "base/mac/foundation_util.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#import "base/test/ios/wait_util.h"
|
| +#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
|
| +#include "ios/chrome/browser/pref_names.h"
|
| +#import "ios/chrome/browser/tabs/tab.h"
|
| +#import "ios/chrome/browser/tabs/tab_model.h"
|
| +#import "ios/chrome/browser/ui/browser_view_controller.h"
|
| +#import "ios/chrome/browser/ui/stack_view/card_view.h"
|
| +#import "ios/chrome/browser/ui/stack_view/stack_view_controller.h"
|
| +#import "ios/chrome/browser/ui/stack_view/stack_view_controller_private.h"
|
| +#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
|
| +#import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h"
|
| +#import "ios/chrome/test/app/stack_view_test_util.h"
|
| +#import "ios/chrome/test/app/tab_test_util.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_matchers.h"
|
| +#import "ios/chrome/test/earl_grey/chrome_test_case.h"
|
| +#include "ios/testing/earl_grey/disabled_test_macros.h"
|
| +
|
| +namespace {
|
| +// Returns a GREYMatcher that matches |view|.
|
| +// TODO(crbug.com/642619): Evaluate whether this should be shared code.
|
| +id<GREYMatcher> viewMatchingView(UIView* view) {
|
| + MatchesBlock matches = ^BOOL(UIView* viewToMatch) {
|
| + return viewToMatch == view;
|
| + };
|
| + DescribeToBlock describe = ^void(id<GREYDescription> description) {
|
| + NSString* matcherDescription =
|
| + [NSString stringWithFormat:@"View matching %@", view];
|
| + [description appendText:matcherDescription];
|
| + };
|
| + return [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
|
| + descriptionBlock:describe];
|
| +}
|
| +
|
| +// Returns a matcher for the StackViewController's view.
|
| +id<GREYMatcher> stackView() {
|
| + return viewMatchingView([chrome_test_util::GetStackViewController() view]);
|
| +}
|
| +
|
| +// Waits for the Stack View to be visible/hidden.
|
| +void CheckForStackViewVisibility(bool visible) {
|
| + id<GREYMatcher> visibilityMatcher =
|
| + grey_allOf(visible ? grey_sufficientlyVisible() : grey_notVisible(),
|
| + visible ? grey_notNil() : grey_nil(), nil);
|
| + [[EarlGrey selectElementWithMatcher:stackView()]
|
| + assertWithMatcher:visibilityMatcher];
|
| +}
|
| +
|
| +// Opens the StackViewController.
|
| +void OpenStackView() {
|
| + if (chrome_test_util::IsTabSwitcherActive())
|
| + return;
|
| + // Tap on the toolbar's tab switcher button.
|
| + id<GREYMatcher> stackButtonMatcher =
|
| + grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier),
|
| + grey_sufficientlyVisible(), nil);
|
| + [[EarlGrey selectElementWithMatcher:stackButtonMatcher]
|
| + performAction:grey_tap()];
|
| + // Verify that a StackViewController was presented.
|
| + CheckForStackViewVisibility(true);
|
| +}
|
| +
|
| +// Shows either the normal or incognito deck.
|
| +enum class DeckType : bool { NORMAL, INCOGNITO };
|
| +void ShowDeckWithType(DeckType type) {
|
| + OpenStackView();
|
| + StackViewController* stackViewController =
|
| + chrome_test_util::GetStackViewController();
|
| + UIView* activeDisplayView = stackViewController.activeCardSet.displayView;
|
| + // The inactive deck region is in scroll view coordinates, but the tap
|
| + // recognizer is installed on the active card set's display view.
|
| + CGRect inactiveDeckRegion =
|
| + [activeDisplayView convertRect:[stackViewController inactiveDeckRegion]
|
| + fromView:stackViewController.scrollView];
|
| + bool showIncognito = type == DeckType::INCOGNITO;
|
| + if (showIncognito) {
|
| + GREYAssert(!CGRectIsEmpty(inactiveDeckRegion),
|
| + @"Cannot show Incognito deck if no Incognito tabs are open");
|
| + }
|
| + if (showIncognito != [stackViewController isCurrentSetIncognito]) {
|
| + CGPoint tapPoint = CGPointMake(CGRectGetMidX(inactiveDeckRegion),
|
| + CGRectGetMidY(inactiveDeckRegion));
|
| + [[EarlGrey selectElementWithMatcher:viewMatchingView(activeDisplayView)]
|
| + performAction:grey_tapAtPoint(tapPoint)];
|
| + }
|
| +}
|
| +
|
| +// Opens a new tab using the stack view button.
|
| +void OpenNewTabUsingStackView() {
|
| + // Open the stack view, tap the New Tab button, and wait for the animation to
|
| + // finish.
|
| + ShowDeckWithType(DeckType::NORMAL);
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"New Tab")]
|
| + performAction:grey_tap()];
|
| + CheckForStackViewVisibility(false);
|
| +}
|
| +
|
| +// Opens the tools menu from the stack view.
|
| +void OpenToolsMenu() {
|
| + OpenStackView();
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::toolsMenuButton()]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Opens a new Incognito Tab using the stack view button.
|
| +void OpenNewIncognitoTabUsingStackView() {
|
| + OpenToolsMenu();
|
| + NSString* newIncognitoTabID = kToolsMenuNewIncognitoTabId;
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(newIncognitoTabID)]
|
| + performAction:grey_tap()];
|
| + CheckForStackViewVisibility(false);
|
| +}
|
| +
|
| +// Taps the CardView associated with |tab|.
|
| +void SelectTabUsingStackView(Tab* tab) {
|
| + DCHECK(tab);
|
| + // Present the StackViewController.
|
| + OpenStackView();
|
| + // Get the StackCard associated with |tab|.
|
| + StackViewController* stackViewController =
|
| + chrome_test_util::GetStackViewController();
|
| + StackCard* nextCard = [[stackViewController activeCardSet] cardForTab:tab];
|
| + UIView* card_title_label = static_cast<UIView*>([[nextCard view] titleLabel]);
|
| + [[EarlGrey selectElementWithMatcher:viewMatchingView(card_title_label)]
|
| + performAction:grey_tap()];
|
| + // Wait for the StackViewController to be dismissed.
|
| + CheckForStackViewVisibility(false);
|
| + // Checks that the next Tab has been selected.
|
| + GREYAssertEqual(tab, chrome_test_util::GetCurrentTab(),
|
| + @"The next Tab was not selected");
|
| +}
|
| +}
|
| +
|
| +// Tests for interacting with the StackViewController.
|
| +@interface StackViewTestCase : ChromeTestCase
|
| +@end
|
| +
|
| +@implementation StackViewTestCase
|
| +
|
| +// Switches between three Tabs via the stack view.
|
| +- (void)testSwitchTabs {
|
| + // The StackViewController is only used on iPhones.
|
| + if (IsIPadIdiom())
|
| + EARL_GREY_TEST_SKIPPED(@"Stack view is not used on iPads.");
|
| + // Open two additional Tabs.
|
| + const NSUInteger kAdditionalTabCount = 2;
|
| + for (NSUInteger i = 0; i < kAdditionalTabCount; ++i)
|
| + OpenNewTabUsingStackView();
|
| + // Select each additional Tab using the stack view UI.
|
| + for (NSUInteger i = 0; i < kAdditionalTabCount + 1; ++i)
|
| + SelectTabUsingStackView(chrome_test_util::GetNextTab());
|
| +}
|
| +
|
| +// Tests closing a tab in the stack view.
|
| +- (void)testCloseTab {
|
| + // The StackViewController is only used on iPhones.
|
| + if (IsIPadIdiom())
|
| + EARL_GREY_TEST_SKIPPED(@"Stack view is not used on iPads.");
|
| + // Open the stack view and tap the close button on the current CardView.
|
| + OpenStackView();
|
| + StackViewController* stackViewController =
|
| + chrome_test_util::GetStackViewController();
|
| + Tab* currentTab = chrome_test_util::GetCurrentTab();
|
| + StackCard* card = [[stackViewController activeCardSet] cardForTab:currentTab];
|
| + CardView* cardView = card.view;
|
| + NSString* identifier = card.view.closeButtonId;
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(identifier)]
|
| + performAction:grey_tap()];
|
| + // Verify that the CardView and its associated Tab were removed.
|
| + [[EarlGrey selectElementWithMatcher:viewMatchingView(cardView)]
|
| + assertWithMatcher:grey_notVisible()];
|
| + GREYAssertEqual(chrome_test_util::GetMainTabCount(), 0,
|
| + @"All Tabs should be closed.");
|
| +}
|
| +
|
| +// Tests closing all Tabs in the stack view.
|
| +- (void)testCloseAllTabs {
|
| + // The StackViewController is only used on iPhones.
|
| + if (IsIPadIdiom())
|
| + EARL_GREY_TEST_SKIPPED(@"Stack view is not used on iPads.");
|
| + // Open an incognito Tab.
|
| + OpenNewIncognitoTabUsingStackView();
|
| + GREYAssertEqual(chrome_test_util::GetIncognitoTabCount(), 1,
|
| + @"Incognito Tab was not opened.");
|
| + // Open two additional Tabs.
|
| + const NSUInteger kAdditionalTabCount = 2;
|
| + for (NSUInteger i = 0; i < kAdditionalTabCount; ++i)
|
| + OpenNewTabUsingStackView();
|
| + GREYAssertEqual(chrome_test_util::GetMainTabCount(), kAdditionalTabCount + 1,
|
| + @"Additional Tabs were not opened.");
|
| + // Record all created CardViews.
|
| + OpenStackView();
|
| + StackViewController* stackViewController =
|
| + chrome_test_util::GetStackViewController();
|
| + NSMutableArray* cardViews = [NSMutableArray array];
|
| + for (StackCard* card in [stackViewController activeCardSet].cards) {
|
| + if (card.viewIsLive)
|
| + [cardViews addObject:card.view];
|
| + }
|
| + for (StackCard* card in [stackViewController inactiveCardSet].cards) {
|
| + if (card.viewIsLive)
|
| + [cardViews addObject:card.view];
|
| + }
|
| + // Open the tools menu and select "Close all tabs".
|
| + OpenToolsMenu();
|
| + NSString* closeAllTabsID = kToolsMenuCloseAllTabsId;
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(closeAllTabsID)]
|
| + performAction:grey_tap()];
|
| + // Wait for CardViews to be dismissed.
|
| + for (CardView* cardView in cardViews) {
|
| + [[EarlGrey selectElementWithMatcher:viewMatchingView(cardView)]
|
| + assertWithMatcher:grey_notVisible()];
|
| + }
|
| + // Check that all Tabs were closed.
|
| + GREYAssertEqual(chrome_test_util::GetMainTabCount(), 0,
|
| + @"Tabs were not closed.");
|
| + GREYAssertEqual(chrome_test_util::GetIncognitoTabCount(), 0,
|
| + @"Incognito Tab was not closed.");
|
| +}
|
| +
|
| +// Tests that tapping on the inactive deck region switches modes.
|
| +- (void)testSwitchingModes {
|
| + // The StackViewController is only used on iPhones.
|
| + if (IsIPadIdiom())
|
| + EARL_GREY_TEST_SKIPPED(@"Stack view is not used on iPads.");
|
| + // Open an Incognito Tab then switch decks.
|
| + OpenNewIncognitoTabUsingStackView();
|
| + ShowDeckWithType(DeckType::INCOGNITO);
|
| + // Verify that the current CardSet is the incognito set.
|
| + StackViewController* stackViewController =
|
| + chrome_test_util::GetStackViewController();
|
| + GREYAssert([stackViewController isCurrentSetIncognito],
|
| + @"Incognito deck not selected.");
|
| + // Switch back to the main CardSet and verify that is selected.
|
| + ShowDeckWithType(DeckType::NORMAL);
|
| + GREYAssert(![stackViewController isCurrentSetIncognito],
|
| + @"Normal deck not selected.");
|
| +}
|
| +
|
| +@end
|
|
|