blob: 865b90b23f00d100ea5b439681c6d8e6a5ebd19e [file] [log] [blame] [edit]
// Copyright 2018 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.
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/features.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_constants.h"
#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h"
#import "ios/chrome/browser/ui/util/ui_util.h"
#include "ios/chrome/grit/ios_strings.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_xcui_actions.h"
#import "ios/chrome/test/earl_grey/web_http_server_chrome_test_case.h"
#import "ios/testing/earl_grey/earl_grey_test.h"
#import "ios/web/public/test/http_server/http_server.h"
#import "ios/web/public/test/http_server/http_server_util.h"
#include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using chrome_test_util::TabGridOtherDevicesPanelButton;
using chrome_test_util::LongPressCellAndDragToEdge;
using chrome_test_util::LongPressCellAndDragToOffsetOf;
using chrome_test_util::TapAtOffsetOf;
using chrome_test_util::WindowWithNumber;
namespace {
char kURL1[] = "http://firstURL";
char kURL2[] = "http://secondURL";
char kURL3[] = "http://thirdURL";
char kURL4[] = "http://fourthURL";
char kTitle1[] = "Page 1";
char kTitle2[] = "Page 2";
char kTitle4[] = "Page 4";
char kResponse1[] = "Test Page 1 content";
char kResponse2[] = "Test Page 2 content";
char kResponse3[] = "Test Page 3 content";
char kResponse4[] = "Test Page 4 content";
// Matcher for the 'Close All' confirmation button.
id<GREYMatcher> CloseAllTabsConfirmationWithNumberOfTabs(
NSInteger numberOfTabs) {
NSString* closeTabs =
base::SysUTF16ToNSString(l10n_util::GetPluralStringFUTF16(
IDS_IOS_TAB_GRID_CLOSE_ALL_TABS_CONFIRMATION, numberOfTabs));
return grey_allOf(grey_accessibilityLabel(closeTabs),
grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
}
// Identifer for cell at given |index| in the tab grid.
NSString* IdentifierForCellAtIndex(unsigned int index) {
return [NSString stringWithFormat:@"%@%u", kGridCellIdentifierPrefix, index];
}
} // namespace
@interface TabGridTestCase : WebHttpServerChromeTestCase {
GURL _URL1;
GURL _URL2;
GURL _URL3;
GURL _URL4;
}
@end
@implementation TabGridTestCase
- (void)setUp {
[super setUp];
_URL1 = web::test::HttpServer::MakeUrl(kURL1);
_URL2 = web::test::HttpServer::MakeUrl(kURL2);
_URL3 = web::test::HttpServer::MakeUrl(kURL3);
_URL4 = web::test::HttpServer::MakeUrl(kURL4);
std::map<GURL, std::string> responses;
const char kPageFormat[] = "<head><title>%s</title></head><body>%s</body>";
responses[_URL1] = base::StringPrintf(kPageFormat, kTitle1, kResponse1);
responses[_URL2] = base::StringPrintf(kPageFormat, kTitle2, kResponse2);
// Page 3 does not have <title> tag, so URL will be its title.
responses[_URL3] = kResponse3;
responses[_URL4] = base::StringPrintf(kPageFormat, kTitle4, kResponse4);
web::test::SetUpSimpleHttpServer(responses);
}
// Tests entering and leaving the tab grid.
- (void)testEnteringAndLeavingTabGrid {
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests that tapping on the first cell shows that tab.
- (void)testTappingOnFirstCell {
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that closing the cell shows no tabs, and displays the empty state.
- (void)testClosingFirstCell {
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
TabGridCloseButtonForCellAtIndex(0)]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)]
assertWithMatcher:grey_nil()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
TabGridRegularTabsEmptyStateView()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that tapping Close All shows no tabs, shows Undo button, and displays
// the empty state. Then tests tapping Undo shows Close All button again.
- (void)testCloseAllAndUndoCloseAll {
if ([ChromeEarlGrey isCloseAllTabsConfirmationEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Close All Tabs Confirmation feature flag is on.");
}
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)]
assertWithMatcher:grey_nil()];
[[EarlGrey
selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
assertWithMatcher:grey_nil()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
TabGridRegularTabsEmptyStateView()]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey
selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that the Undo button is no longer available after tapping Close All,
// then creating a new tab, then coming back to the tab grid.
- (void)testUndoCloseAllNotAvailableAfterNewTabCreation {
if ([ChromeEarlGrey isCloseAllTabsConfirmationEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Close All Tabs Confirmation feature flag is on.");
}
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
performAction:grey_tap()];
[[EarlGrey
selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()]
assertWithMatcher:grey_sufficientlyVisible()];
// Create a new tab then come back to tab grid.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridNewTabButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
// Undo is no longer available.
[[EarlGrey
selectElementWithMatcher:chrome_test_util::TabGridUndoCloseAllButton()]
assertWithMatcher:grey_nil()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that Clear Browsing Data can be successfully done from tab grid.
- (void)DISABLED_testClearBrowsingData {
// Load history
[self loadTestURLs];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
// Switch over to Recent Tabs.
[[EarlGrey selectElementWithMatcher:TabGridOtherDevicesPanelButton()]
performAction:grey_tap()];
// Tap on "Show History"
// Undo is available after close all action.
[[EarlGrey
selectElementWithMatcher:chrome_test_util::TabGridSelectShowHistoryCell()]
performAction:grey_tap()];
[ChromeEarlGreyUI openAndClearBrowsingDataFromHistory];
[ChromeEarlGreyUI assertHistoryHasNoEntries];
}
// Tests the Copy Link action on a recent tab's context menu.
- (void)testRecentTabsContextMenuCopyLink {
if (![ChromeEarlGrey isNativeContextMenusEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Native Context Menus feature flag is off.");
}
[self prepareRecentTabWithURL:_URL1 response:kResponse1];
[self longPressRecentTabWithTitle:[NSString stringWithUTF8String:kTitle1]];
[ChromeEarlGrey
verifyCopyLinkActionWithText:[NSString stringWithUTF8String:_URL1.spec()
.c_str()]
useNewString:YES];
}
// Tests the Open in New Tab action on a recent tab's context menu.
- (void)testRecentTabsContextMenuOpenInNewTab {
if (![ChromeEarlGrey isNativeContextMenusEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Native Context Menus feature flag is off.");
}
[self prepareRecentTabWithURL:_URL1 response:kResponse1];
[self longPressRecentTabWithTitle:[NSString stringWithUTF8String:kTitle1]];
[ChromeEarlGrey verifyOpenInNewTabActionWithURL:_URL1.GetContent()];
// Verify that the Tab Grid is closed.
[[EarlGrey selectElementWithMatcher:TabGridOtherDevicesPanelButton()]
assertWithMatcher:grey_notVisible()];
}
// Tests the Open in New Window action on a recent tab's context menu.
- (void)testRecentTabsContextMenuOpenInNewWindow {
if (![ChromeEarlGrey areMultipleWindowsSupported]) {
EARL_GREY_TEST_DISABLED(@"Multiple windows can't be opened.");
}
if (![ChromeEarlGrey isNativeContextMenusEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Native Context Menus feature flag is off.");
}
[self prepareRecentTabWithURL:_URL1 response:kResponse1];
[self longPressRecentTabWithTitle:[NSString stringWithUTF8String:kTitle1]];
[ChromeEarlGrey verifyOpenInNewWindowActionWithContent:kResponse1];
}
// Tests the Share action on a recent tab's context menu.
- (void)testRecentTabsContextMenuShare {
if (![ChromeEarlGrey isNativeContextMenusEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Native Context Menus feature flag is off.");
}
[self prepareRecentTabWithURL:_URL1 response:kResponse1];
[self longPressRecentTabWithTitle:[NSString stringWithUTF8String:kTitle1]];
[ChromeEarlGrey
verifyShareActionWithPageTitle:[NSString stringWithUTF8String:kTitle1]];
}
// Tests that tapping on "Close All" shows a confirmation dialog.
// It also tests that tapping on "Close x Tab(s)" on the confirmation dialog
// displays an empty grid and tapping on "Cancel" doesn't modify the grid.
- (void)testCloseAllTabsConfirmation {
if (![ChromeEarlGrey isCloseAllTabsConfirmationEnabled]) {
EARL_GREY_TEST_SKIPPED(
@"Test disabled when Close All Tabs Confirmation feature flag is off.");
}
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
// Taps on "Close All" and Confirm.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:CloseAllTabsConfirmationWithNumberOfTabs(
1)] performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)]
assertWithMatcher:grey_nil()];
// Checks that "Close All" is grayed out.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
assertWithMatcher:grey_not(grey_enabled())];
// Creates a new tab then come back to tab grid.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridNewTabButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
// Taps on "Close All" and Cancel.
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
performAction:grey_tap()];
if (IsIPadIdiom()) {
[[EarlGrey
selectElementWithMatcher:chrome_test_util::TabGridCloseAllButton()]
performAction:grey_tap()];
} else {
[[EarlGrey selectElementWithMatcher:chrome_test_util::CancelButton()]
performAction:grey_tap()];
}
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(0)]
assertWithMatcher:grey_sufficientlyVisible()];
}
#pragma mark - Drag and drop in Multiwindow
// Tests that dragging a tab grid item to the edge opens a new window and that
// the tab is properly transferred, incuding navigation stack.
- (void)testDragAndDropAtEdgeToCreateNewWindow {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
// TODO(crbug.com/1184267): Test is flaky on iPad devices.
#if !TARGET_IPHONE_SIMULATOR
if ([ChromeEarlGrey isIPadIdiom]) {
EARL_GREY_TEST_DISABLED(@"This test is flaky on iPad devices.");
}
#endif
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey loadURL:_URL3];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3];
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2];
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
GREYAssert(LongPressCellAndDragToEdge(IdentifierForCellAtIndex(0),
kGREYContentEdgeRight, 0),
@"Failed to DND cell");
GREYWaitForAppToIdle(@"App failed to idle");
// Assert two windows and the expected tabs in each.
[ChromeEarlGrey waitForForegroundWindowCount:2];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2
inWindowWithNumber:0];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
// Navigate back on second window to check the navigation stack is intact.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1
inWindowWithNumber:1];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests that dragging a tab grid incognito item to the edge opens a new window
// and that the tab is properly transferred, incuding navigation stack.
// TODO(crbug.com/1176180): re-enable this test when it is fixed.
- (void)DISABLED_testIncognitoDragAndDropAtEdgeToCreateNewWindow {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
[ChromeEarlGrey closeAllNormalTabs];
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey loadURL:_URL3];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3];
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2];
[ChromeEarlGrey waitForIncognitoTabCount:2 inWindowWithNumber:0];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
GREYAssert(LongPressCellAndDragToEdge(IdentifierForCellAtIndex(0),
kGREYContentEdgeRight, 0),
@"Failed to DND cell");
GREYWaitForAppToIdle(@"App failed to idle");
// Assert two windows and the expected tabs in each.
[ChromeEarlGrey waitForForegroundWindowCount:2];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2
inWindowWithNumber:0];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
// Navigate back on second window to check the navigation stack is intact.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1
inWindowWithNumber:1];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests dragging tab grid item between windows.
- (void)testDragAndDropBetweenWindows {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
// TODO(crbug.com/1184267): Test is flaky on iPad devices.
#if !TARGET_IPHONE_SIMULATOR
if ([ChromeEarlGrey isIPadIdiom]) {
EARL_GREY_TEST_DISABLED(@"This test is flaky on iPad devices.");
}
#endif
// Setup first window with tabs 1 and 2.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2];
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0];
// Open second window.
[ChromeEarlGrey openNewWindow];
[ChromeEarlGrey waitForForegroundWindowCount:2];
// Setup second window with tabs 3 and 4.
[ChromeEarlGrey loadURL:_URL3 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
[ChromeEarlGrey openNewTabInWindowWithNumber:1];
[ChromeEarlGrey loadURL:_URL4 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse4
inWindowWithNumber:1];
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:1];
// Open tab grid in both window.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
// DnD first tab of left window to left edge of first tab in second window.
// Note: move to left half of the destination tile, to avoid unwanted
// scrolling that would happen closer to the left edge.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(0), 0,
IdentifierForCellAtIndex(0), 1,
CGVectorMake(0.4, 0.5)),
@"Failed to DND cell on cell");
GREYWaitForAppToIdle(@"App failed to idle");
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:3 inWindowWithNumber:1];
// Move third cell of second window as second cell in first window.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(2), 1,
IdentifierForCellAtIndex(0), 0,
CGVectorMake(1.0, 0.5)),
@"Failed to DND cell on cell");
GREYWaitForAppToIdle(@"App failed to idle");
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:1];
// Check content and order of tabs.
[self fromGridCheckTabAtIndex:0 inWindowNumber:0 containsText:kResponse2];
[self fromGridCheckTabAtIndex:1 inWindowNumber:0 containsText:kResponse4];
[self fromGridCheckTabAtIndex:0 inWindowNumber:1 containsText:kResponse1];
[self fromGridCheckTabAtIndex:1 inWindowNumber:1 containsText:kResponse3];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests dragging tab grid item between windows.
// TODO(crbug.com/1176669): re-enable this test when it is fixed.
- (void)DISABLED_testDragAndDropIncognitoBetweenWindows {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
// Setup first window with one incognito tab.
[ChromeEarlGrey closeAllNormalTabs];
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
// Open second window with main ntp.
[ChromeEarlGrey openNewWindow];
[ChromeEarlGrey waitForForegroundWindowCount:2];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Open tab grid in both window.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
// Try DnDing first incognito tab of left window to main tab panel on right
// window.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(0), 0,
IdentifierForCellAtIndex(0), 1,
CGVectorMake(1.0, 0.5)),
@"Failed to DND cell on cell");
GREYWaitForAppToIdle(@"App failed to idle");
// It should fail and both windows should still have only one tab.
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Move second window to incognito tab panel.
// Note: until reported bug is fixed in EarlGrey, grey_tap() doesn't always
// work in second window, because it fails the visibility check.
GREYAssert(TapAtOffsetOf(kTabGridIncognitoTabsPageButtonIdentifier, 1,
CGVectorMake(0.5, 0.5)),
@"Failed to tap incognito panel button");
// Try again to move tabs.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(0), 0, nil,
1, CGVectorMake(0.5, 0.5)),
@"Failed to DND cell on window");
GREYWaitForAppToIdle(@"App failed to idle");
// Check that it worked and there are 2 incgnito tabs in second window.
[ChromeEarlGrey waitForIncognitoTabCount:0 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:1];
// Cleanup.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests dragging tab grid item as URL between windows.
- (void)testDragAndDropURLBetweenWindows {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
// Setup first window with tabs 1 and 2.
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey openNewTab];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2];
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0];
// Open second window.
[ChromeEarlGrey openNewWindow];
[ChromeEarlGrey waitForForegroundWindowCount:2];
// Setup second window with tab 3.
[ChromeEarlGrey loadURL:_URL3 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Open tab grid in first window.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
// DnD first tab of left window to second window.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(0), 0, nil,
1, CGVectorMake(0.5, 0.5)),
@"Failed to DND cell on window");
GREYWaitForAppToIdle(@"App failed to idle");
// Tabs should not have changed.
[ChromeEarlGrey waitForMainTabCount:2 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Second window should show URL1
[ChromeEarlGrey waitForWebStateContainingText:kResponse1
inWindowWithNumber:1];
// Navigate back to check the navigation stack is intact.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests dragging tab grid incognito item as URL to a main windows.
- (void)testDragAndDropIncognitoURLInMainWindow {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
// Setup first window with one incognito tab 1.
[ChromeEarlGrey closeAllNormalTabs];
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
// Open second window.
[ChromeEarlGrey openNewWindow];
[ChromeEarlGrey waitForForegroundWindowCount:2];
// Setup second window with tab 3.
[ChromeEarlGrey loadURL:_URL3 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Open incognito tab grid in first window.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
TabGridIncognitoTabsPanelButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
// DnD first tab of left window to second window.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(0), 0, nil,
1, CGVectorMake(0.5, 0.5)),
@"Failed to DND cell on window");
GREYWaitForAppToIdle(@"App failed to idle");
// Tabs should not have changed.
[ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Second window should show URL1
[ChromeEarlGrey waitForWebStateContainingText:kResponse1
inWindowWithNumber:1];
// Navigate back to check the navigation stack is intact.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
// Tests dragging tab grid main item as URL to an incognito windows.
- (void)testDragAndDropMainURLInIncognitoWindow {
if (![ChromeEarlGrey areMultipleWindowsSupported])
EARL_GREY_TEST_SKIPPED(@"Multiple windows can't be opened.");
// TODO(crbug.com/1184267): Test is flaky on iPad devices.
#if !TARGET_IPHONE_SIMULATOR
if ([ChromeEarlGrey isIPadIdiom]) {
EARL_GREY_TEST_DISABLED(@"This test is flaky on iPad devices.");
}
#endif
// Setup first window with one incognito tab 1.
[ChromeEarlGrey closeAllNormalTabs];
[ChromeEarlGrey openNewIncognitoTab];
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
// Open second window.
[ChromeEarlGrey openNewWindow];
[ChromeEarlGrey waitForForegroundWindowCount:2];
// Setup second window with tab 3.
[ChromeEarlGrey loadURL:_URL3 inWindowWithNumber:1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:1];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// Open incognito tab grid in first window.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
GREYWaitForAppToIdle(@"App failed to idle");
// DnD first tab of second window to first window.
GREYAssert(LongPressCellAndDragToOffsetOf(IdentifierForCellAtIndex(0), 1, nil,
0, CGVectorMake(0.5, 0.5)),
@"Failed to DND cell on window");
GREYWaitForAppToIdle(@"App failed to idle");
// Tabs should not have changed.
[ChromeEarlGrey waitForMainTabCount:0 inWindowWithNumber:0];
[ChromeEarlGrey waitForIncognitoTabCount:1 inWindowWithNumber:0];
[ChromeEarlGrey waitForMainTabCount:1 inWindowWithNumber:1];
// First window should show URL3
[ChromeEarlGrey waitForWebStateContainingText:kResponse3
inWindowWithNumber:0];
// Navigate back to check the navigation stack is intact.
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(0)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1
inWindowWithNumber:0];
[EarlGrey setRootMatcherForSubsequentInteractions:WindowWithNumber(1)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridDoneButton()]
performAction:grey_tap()];
}
#pragma mark - Helper Methods
- (void)loadTestURLs {
[ChromeEarlGrey loadURL:_URL1];
[ChromeEarlGrey waitForWebStateContainingText:kResponse1];
[ChromeEarlGrey loadURL:_URL2];
[ChromeEarlGrey waitForWebStateContainingText:kResponse2];
[ChromeEarlGrey loadURL:_URL3];
[ChromeEarlGrey waitForWebStateContainingText:kResponse3];
}
// Loads a URL in a new tab and deletes it to populate Recent Tabs. Then,
// navigates to the Recent tabs via tab grid.
- (void)prepareRecentTabWithURL:(const GURL&)URL
response:(const char*)response {
[ChromeEarlGrey loadURL:URL];
[ChromeEarlGrey waitForWebStateContainingText:response];
// Close the tab, making it appear in Recent Tabs.
[ChromeEarlGrey closeCurrentTab];
// Switch over to Recent Tabs.
[[EarlGrey selectElementWithMatcher:TabGridOtherDevicesPanelButton()]
performAction:grey_tap()];
}
- (void)longPressRecentTabWithTitle:(NSString*)title {
// The test page may be there multiple times.
[[[EarlGrey
selectElementWithMatcher:grey_allOf(grey_accessibilityLabel(title),
grey_sufficientlyVisible(), nil)]
atIndex:0] performAction:grey_longPress()];
}
// Checks if the content of the given tab in the given window matches given
// text. This method exits the tab grid and re-enters it afterward.
- (void)fromGridCheckTabAtIndex:(int)tabIndex
inWindowNumber:(int)windowNumber
containsText:(const char*)text {
[EarlGrey
setRootMatcherForSubsequentInteractions:WindowWithNumber(windowNumber)];
[[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridCellAtIndex(
tabIndex)] performAction:grey_tap()];
[ChromeEarlGrey waitForWebStateContainingText:text
inWindowWithNumber:windowNumber];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ShowTabsButton()]
performAction:grey_tap()];
}
@end