| Index: ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
|
| diff --git a/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..33a33661a58740db68dbfb1399d92ce19c6b53f5
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/bookmarks/bookmarks_egtest.mm
|
| @@ -0,0 +1,1559 @@
|
| +// 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.
|
| +
|
| +#include <vector>
|
| +
|
| +#import <EarlGrey/EarlGrey.h>
|
| +#import <UIKit/UIKit.h>
|
| +#import <XCTest/XCTest.h>
|
| +
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#include "components/bookmarks/browser/bookmark_model.h"
|
| +#include "components/bookmarks/browser/titled_url_match.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "components/strings/grit/components_strings.h"
|
| +#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
|
| +#include "ios/chrome/browser/bookmarks/bookmarks_utils.h"
|
| +#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
|
| +#include "ios/chrome/browser/experimental_flags.h"
|
| +#include "ios/chrome/browser/pref_names.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/toolbar/toolbar_controller.h"
|
| +#import "ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.h"
|
| +#import "ios/chrome/browser/ui/uikit_ui_util.h"
|
| +#include "ios/chrome/grit/ios_strings.h"
|
| +#import "ios/chrome/test/app/bookmarks_test_util.h"
|
| +#import "ios/chrome/test/app/chrome_test_util.h"
|
| +#include "ios/chrome/test/app/navigation_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_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/public/provider/chrome/browser/signin/fake_chrome_identity.h"
|
| +#import "ios/public/provider/chrome/browser/signin/fake_chrome_identity_service.h"
|
| +#import "ios/testing/wait_util.h"
|
| +#import "ios/web/public/test/http_server.h"
|
| +#include "ios/web/public/test/http_server_util.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/models/tree_node_iterator.h"
|
| +#include "url/gurl.h"
|
| +
|
| +using chrome_test_util::buttonWithAccessibilityLabel;
|
| +using chrome_test_util::buttonWithAccessibilityLabelId;
|
| +
|
| +namespace {
|
| +// TODO(crbug.com/616929): Move common matchers that are useful across tests
|
| +// into a shared location.
|
| +
|
| +// Matcher for bookmarks tool tip star.
|
| +id<GREYMatcher> starButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_TOOLTIP_STAR);
|
| +}
|
| +
|
| +// Matcher for the button to add bookmark.
|
| +id<GREYMatcher> addBookmarkButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_BOOKMARK_ADD_EDITOR_TITLE);
|
| +}
|
| +
|
| +// Matcher for the lit star buttom on iPhone that will open the edit button
|
| +// screen.
|
| +id<GREYMatcher> litStarButtoniPhone() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_TOOLS_MENU_EDIT_BOOKMARK);
|
| +}
|
| +
|
| +// Matcher for the button to edit bookmark.
|
| +id<GREYMatcher> editBookmarkButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_BOOKMARK_ACTION_EDIT);
|
| +}
|
| +
|
| +// Matcher for the button to close the tools menu.
|
| +id<GREYMatcher> closeToolsMenuButton() {
|
| + NSString* closeMenuButtonText =
|
| + l10n_util::GetNSString(IDS_IOS_TOOLBAR_CLOSE_MENU);
|
| + return grey_allOf(grey_accessibilityID(kToolbarToolsMenuButtonIdentifier),
|
| + grey_accessibilityLabel(closeMenuButtonText), nil);
|
| +}
|
| +
|
| +// Matcher for the Done button on the bookmarks UI.
|
| +id<GREYMatcher> bookmarksDoneButton() {
|
| + return grey_allOf(
|
| + buttonWithAccessibilityLabelId(IDS_IOS_BOOKMARK_DONE_BUTTON),
|
| + grey_not(grey_accessibilityTrait(UIAccessibilityTraitKeyboardKey)), nil);
|
| +}
|
| +
|
| +// Types of actions possible in the contextual action sheet.
|
| +typedef NS_ENUM(NSUInteger, Action) {
|
| + ActionSelect,
|
| + ActionEdit,
|
| + ActionMove,
|
| + ActionDelete,
|
| +};
|
| +
|
| +// Matcher for the action sheet's buttons.
|
| +id<GREYMatcher> actionSheet(Action action) {
|
| + int accessibilityLabelMessageID;
|
| + switch (action) {
|
| + case ActionSelect:
|
| + accessibilityLabelMessageID = IDS_IOS_BOOKMARK_ACTION_SELECT;
|
| + break;
|
| + case ActionEdit:
|
| + accessibilityLabelMessageID = IDS_IOS_BOOKMARK_ACTION_EDIT;
|
| + break;
|
| + case ActionMove:
|
| + accessibilityLabelMessageID = IDS_IOS_BOOKMARK_ACTION_MOVE;
|
| + break;
|
| + case ActionDelete:
|
| + accessibilityLabelMessageID = IDS_IOS_BOOKMARK_ACTION_DELETE;
|
| + break;
|
| + }
|
| +
|
| + return grey_allOf(grey_accessibilityLabel(
|
| + l10n_util::GetNSString(accessibilityLabelMessageID)),
|
| + grey_accessibilityTrait(UIAccessibilityTraitButton),
|
| + grey_not(grey_accessibilityID(@"Edit_editing_bar")), nil);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// Bookmark integration tests for Chrome.
|
| +@interface BookmarksTestCase : ChromeTestCase
|
| +@end
|
| +
|
| +@implementation BookmarksTestCase
|
| +
|
| +- (void)setUp {
|
| + [super setUp];
|
| + // Wait for bookmark model to be loaded.
|
| + GREYAssert(testing::WaitUntilConditionOrTimeout(
|
| + testing::kWaitForUIElementTimeout,
|
| + ^{
|
| + return chrome_test_util::BookmarksLoaded();
|
| + }),
|
| + @"Bookmark model did not load");
|
| + GREYAssert(chrome_test_util::ClearBookmarks(),
|
| + @"Not all bookmarks were removed.");
|
| +}
|
| +
|
| +// Tear down called once per test.
|
| +- (void)tearDown {
|
| + [super tearDown];
|
| + GREYAssert(chrome_test_util::ClearBookmarks(),
|
| + @"Not all bookmarks were removed.");
|
| +}
|
| +
|
| +#pragma mark Tests
|
| +
|
| +// Verifies that adding a bookmark and removing a bookmark via the UI properly
|
| +// updates the BookmarkModel.
|
| +- (void)testAddRemoveBookmark {
|
| + const GURL bookmarkedURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/pony.html");
|
| + std::string expectedURLContent = bookmarkedURL.GetContent();
|
| + NSString* bookmarkTitle = @"my bookmark";
|
| +
|
| + [ChromeEarlGrey loadURL:bookmarkedURL];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
|
| + expectedURLContent)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Add the bookmark from the UI.
|
| + [[self class] bookmarkCurrentTabWithTitle:bookmarkTitle];
|
| +
|
| + // Verify the bookmark is set.
|
| + [[self class] assertBookmarksWithTitle:bookmarkTitle expectedCount:1];
|
| +
|
| + NSString* const kStarLitLabel =
|
| + !IsCompact() ? l10n_util::GetNSString(IDS_TOOLTIP_STAR)
|
| + : l10n_util::GetNSString(IDS_IOS_BOOKMARK_EDIT_SCREEN_TITLE);
|
| + // Verify the star is lit.
|
| + if (IsCompact()) {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + }
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(kStarLitLabel)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Clear the bookmark via the UI.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(kStarLitLabel)]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionDelete)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify the bookmark is not in the BookmarkModel.
|
| + [[self class] assertBookmarksWithTitle:bookmarkTitle expectedCount:0];
|
| +
|
| + NSString* const kStarUnlitLabel =
|
| + !IsCompact() ? l10n_util::GetNSString(IDS_TOOLTIP_STAR)
|
| + : l10n_util::GetNSString(IDS_BOOKMARK_ADD_EDITOR_TITLE);
|
| +
|
| + // Verify the star is not lit.
|
| + if (IsCompact()) {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + }
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(kStarUnlitLabel)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // TODO(crbug.com/617652): This code should be removed when a common helper
|
| + // is added to close any menus, which should be run as test setup.
|
| + if (IsCompact()) {
|
| + [[EarlGrey selectElementWithMatcher:closeToolsMenuButton()]
|
| + performAction:grey_tap()];
|
| + }
|
| +
|
| + // Close the opened tab.
|
| + base::scoped_nsobject<GenericChromeCommand> command(
|
| + [[GenericChromeCommand alloc] initWithTag:IDC_CLOSE_TAB]);
|
| + chrome_test_util::RunCommandWithActiveViewController(command);
|
| +}
|
| +
|
| +// Tests that tapping a bookmark on the NTP navigates to the proper URL.
|
| +- (void)testTapBookmark {
|
| + const GURL bookmarkURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/destination.html");
|
| + NSString* kBookmarkTitle = @"smokeTapBookmark";
|
| +
|
| + // Load a bookmark into the bookmark model.
|
| + [[self class] addBookmark:bookmarkURL withTitle:kBookmarkTitle];
|
| +
|
| + // Open the UI for Bookmarks.
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Wait for the bookmark to appear.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:buttonWithAccessibilityLabel(kBookmarkTitle)]
|
| + assertWithMatcher:grey_sufficientlyVisible()
|
| + error:nil];
|
| +
|
| + // Tap on the bookmark and verify the URL that appears in the omnibox.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:buttonWithAccessibilityLabel(kBookmarkTitle)]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
|
| + bookmarkURL.GetContent())]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Test to set bookmarks in multiple tabs.
|
| +- (void)testBookmarkMultipleTabs {
|
| + const GURL firstURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/pony.html");
|
| + const GURL secondURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/destination.html");
|
| + [ChromeEarlGrey loadURL:firstURL];
|
| + chrome_test_util::OpenNewTab();
|
| + [ChromeEarlGrey loadURL:secondURL];
|
| +
|
| + [[self class] bookmarkCurrentTabWithTitle:@"my bookmark"];
|
| + [[self class] assertBookmarksWithTitle:@"my bookmark" expectedCount:1];
|
| +}
|
| +
|
| +// Try navigating to the bookmark screen, and selecting a bookmark.
|
| +- (void)testSelectBookmark {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Tap on one of the standard bookmark. Verify that it loads.
|
| + [[EarlGrey selectElementWithMatcher:grey_text(@"Second URL")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait for the page to load.
|
| + [ChromeEarlGrey waitForPageToFinishLoading];
|
| +
|
| + // Check the URL is correct.
|
| + const GURL secondURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/destination.html");
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::omnibox()]
|
| + assertWithMatcher:chrome_test_util::omniboxText(secondURL.GetContent())];
|
| +}
|
| +
|
| +// Try deleting a bookmark, then undoing that delete.
|
| +- (void)testUndoDeleteBookmark {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Load the menu for a bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Delete it.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionDelete)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait until it's gone.
|
| + [[self class] waitForDeletionOfBookmarkWithTitle:@"Second URL"];
|
| +
|
| + // Press undo
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Undo")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify it's back.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL")]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Try deleting a bookmark from the edit screen, then undoing that delete.
|
| +- (void)testUndoDeleteBookmarkFromEditScreen {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Load the menu for a bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Delete it.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionDelete)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait until it's gone.
|
| + ConditionBlock condition = ^{
|
| + NSError* error = nil;
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL")]
|
| + assertWithMatcher:grey_notVisible()
|
| + error:&error];
|
| + return error == nil;
|
| + };
|
| + GREYAssert(testing::WaitUntilConditionOrTimeout(10, condition),
|
| + @"Waiting for bookmark to go away");
|
| +
|
| + // Press undo
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Undo")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify it's back.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL")]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Try moving bookmarks, then undoing that move.
|
| +- (void)testUndoMoveBookmark {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Verify that folder 2 only has 1 child.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"Folder 2"];
|
| +
|
| + // Load the menu for a bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Select a first bookmark.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionSelect)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Select a second bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Choose the move action.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Move")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Pick the destination.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder 2")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait for undo to show up (there is a 300ms delay for the user to see the
|
| + // change).
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Undo")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Verify that folder 2 has 3 children now, and that they are no longer
|
| + // visible.
|
| + [[self class] assertChildCount:3 ofFolderWithName:@"Folder 2"];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Press undo.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Undo")]
|
| + performAction:grey_tap()];
|
| +
|
| + [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
|
| +
|
| + // Verify it's back.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Second URL")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Verify that folder 2 is back to one child.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"Folder 2"];
|
| +}
|
| +
|
| +- (void)testLabelUpdatedUponMove {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Load the menu for a bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap on the Edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the Folder button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Change Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Create a new folder with default name.
|
| + [[self class] addFolderWithName:nil];
|
| +
|
| + // Verify that the editor is present.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Check the new folder label.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_accessibilityID(@"Change Folder"),
|
| + grey_accessibilityLabel(@"New Folder"), nil)]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Test the creation of a bookmark and new folder.
|
| +- (void)testAddBookmarkInNewFolder {
|
| + const GURL bookmarkedURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/pony.html");
|
| + std::string expectedURLContent = bookmarkedURL.GetContent();
|
| +
|
| + [ChromeEarlGrey loadURL:bookmarkedURL];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
|
| + expectedURLContent)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + [[self class] starCurrentTab];
|
| +
|
| + // Verify the snackbar title.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Bookmarked")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Tap on the snackbar.
|
| + NSString* snackbarLabel =
|
| + l10n_util::GetNSString(IDS_IOS_NAVIGATION_BAR_EDIT_BUTTON);
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(snackbarLabel)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify that the newly-created bookmark is in the BookmarkModel.
|
| + [[self class]
|
| + assertBookmarksWithTitle:base::SysUTF8ToNSString(expectedURLContent)
|
| + expectedCount:1];
|
| +
|
| + // Verify that the editor is present.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + [[self class] assertFolderName:@"Mobile Bookmarks"];
|
| +
|
| + // Tap the Folder button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Change Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Create a new folder with default name.
|
| + [[self class] addFolderWithName:nil];
|
| +
|
| + // Verify that the editor is present.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + [[self class] assertFolderExists:@"New Folder"];
|
| +}
|
| +
|
| +// Tests that changing a folder's title in edit mode works as expected.
|
| +- (void)testChangeFolderTitle {
|
| + NSString* existingFolderTitle = @"Folder 1";
|
| + NSString* newFolderTitle = @"New Folder Title";
|
| +
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| + [[self class] openEditBookmarkFolderWithFolderTitle:existingFolderTitle];
|
| + [[self class] renameBookmarkFolderWithFolderTitle:newFolderTitle];
|
| + [[self class] closeEditBookmarkFolder];
|
| +
|
| + if (IsCompact()) {
|
| + // Exit from bookmarks modal. IPad shows bookmarks in tab.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| + }
|
| +
|
| + // Verify that the change has been made.
|
| + [[self class] openMobileBookmarks];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(existingFolderTitle)]
|
| + assertWithMatcher:grey_nil()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(newFolderTitle)]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Tests that the default folder bookmarks are saved in is updated to the last
|
| +// used folder.
|
| +- (void)testStickyDefaultFolder {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Tap on the top-right button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the Folder button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Change Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Create a new folder.
|
| + [[self class] addFolderWithName:@"Sticky Folder"];
|
| +
|
| + // Verify that the editor is present.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Tap the Done button.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + if (IsCompact()) {
|
| + // Dismiss the bookmarks screen.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Exit")]
|
| + performAction:grey_tap()];
|
| + }
|
| +
|
| + // Second, bookmark a page.
|
| +
|
| + // Verify that the bookmark that is going to be added is not in the
|
| + // BookmarkModel.
|
| + const GURL bookmarkedURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/fullscreen.html");
|
| + NSString* const bookmarkedURLString =
|
| + base::SysUTF8ToNSString(bookmarkedURL.spec());
|
| + [[self class] assertBookmarksWithTitle:bookmarkedURLString expectedCount:0];
|
| + // Open the page.
|
| + std::string expectedURLContent = bookmarkedURL.GetContent();
|
| + [ChromeEarlGrey loadURL:bookmarkedURL];
|
| + [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText(
|
| + expectedURLContent)]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Verify that the folder has only one element.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"Sticky Folder"];
|
| +
|
| + // Bookmark the page.
|
| + [[self class] starCurrentTab];
|
| +
|
| + // Verify the snackbar title.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(
|
| + @"Bookmarked to Sticky Folder")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Verify that the newly-created bookmark is in the BookmarkModel.
|
| + [[self class] assertBookmarksWithTitle:bookmarkedURLString expectedCount:1];
|
| +
|
| + // Verify that the folder has now two elements.
|
| + [[self class] assertChildCount:2 ofFolderWithName:@"Sticky Folder"];
|
| +}
|
| +
|
| +// Tests that changes to the parent folder from the Single Bookmark Controller
|
| +// are saved to the bookmark only when saving the results.
|
| +- (void)testMoveDoesSaveOnSave {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openTopLevelBookmarksFolder];
|
| +
|
| + // Tap on the top-right button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the Folder button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Change Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Create a new folder.
|
| + [[self class] addFolderWithName:nil];
|
| +
|
| + // Verify that the editor is present.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Check that the new folder doesn't contain the bookmark.
|
| + [[self class] assertChildCount:0 ofFolderWithName:@"New Folder"];
|
| +
|
| + // Tap the Done button.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Check that the new folder contains the bookmark.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"New Folder"];
|
| +
|
| + // Dismiss the bookmarks screen.
|
| + if (IsCompact()) {
|
| + // Dismiss the bookmarks screen.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Exit")]
|
| + performAction:grey_tap()];
|
| + }
|
| +
|
| + // Check that the new folder still contains the bookmark.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"New Folder"];
|
| +}
|
| +
|
| +// Test thats editing a single bookmark correctly persists data.
|
| +- (void)testSingleBookmarkEdit {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openTopLevelBookmarksFolder];
|
| +
|
| + // Load the menu for a bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Replace the title field with new text.
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Title Field_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Title Field_textField")]
|
| + performAction:grey_typeText(@"n5")];
|
| +
|
| + // Replace the url field with new text.
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"URL Field_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"URL Field_textField")]
|
| + performAction:grey_typeText(@"www.a.fr")];
|
| +
|
| + // Dismiss editor.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Verify that the bookmark was updated.
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabel(@"n5")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| + [[self class] assertExistenceOfBookmarkWithURL:@"http://www.a.fr" name:@"n5"];
|
| +}
|
| +
|
| +// Tests that cancelling editing a single bookmark correctly doesn't persist
|
| +// data.
|
| +- (void)testSingleBookmarkCancelEdit {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openTopLevelBookmarksFolder];
|
| +
|
| + // Load the menu for a bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Replace the title field with new text.
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Title Field_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Title Field_textField")]
|
| + performAction:grey_typeText(@"n5")];
|
| +
|
| + // Replace the url field with new text.
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"URL Field_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"URL Field_textField")]
|
| + performAction:grey_typeText(@"www.a.fr")];
|
| +
|
| + // Dismiss editor with Cancel button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Cancel")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Single Bookmark Editor")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Verify that the bookmark was not updated.
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabel(@"n5")]
|
| + assertWithMatcher:grey_notVisible()];
|
| + [[self class] assertAbsenceOfBookmarkWithURL:@"http://www.a.fr"];
|
| +}
|
| +
|
| +// Tests that long pressing a bookmark selects it and gives access to editing,
|
| +// as does the Info menu.
|
| +- (void)testLongPressBookmark {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openTopLevelBookmarksFolder];
|
| +
|
| + // Long press the top-right button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_longPress()];
|
| +
|
| + // Tap the edit button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Edit_editing_bar")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Dismiss the editor screen.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap on the top-right button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the edit action.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionEdit)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Dismiss the editor screen.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Tests the editing of a folder.
|
| +- (void)testEditFolder {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openBookmarkFolder:@"Folder 1"];
|
| +
|
| + // Tap the Edit button in the navigation bar.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Edit_navigation_bar")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Change the title.
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Title_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Title_textField")]
|
| + performAction:grey_typeText(@"Renamed Folder")];
|
| +
|
| + // Cancel without saving.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Cancel")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Check that Folder 1 still exists at this name, and Renamed Folder doesn't.
|
| + [[self class] assertFolderExistsWithTitle:@"Folder 1"];
|
| + [[self class] assertFolderDoesntExistWithTitle:@"Renamed Folder"];
|
| +
|
| + // Tap the Edit button in the navigation bar.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Edit_navigation_bar")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Change the title.
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Title_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Title_textField")]
|
| + performAction:grey_typeText(@"Renamed Folder")];
|
| +
|
| + // Save.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Save")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Check that Folder 1 doesn't exist and Renamed Folder does.
|
| + [[self class] assertFolderDoesntExistWithTitle:@"Folder 1"];
|
| + [[self class] assertFolderExistsWithTitle:@"Renamed Folder"];
|
| +}
|
| +
|
| +// Tests the deletion of a folder.
|
| +- (void)testDeleteFolder {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openBookmarkFolder:@"Folder 1"];
|
| +
|
| + // Delete the folder.
|
| + [[self class] deleteSelectedFolder];
|
| +
|
| + // Check that the folder doesn't exist anymore.
|
| + [[self class] assertFolderDoesntExistWithTitle:@"Folder 1"];
|
| +}
|
| +
|
| +// Navigates to a deeply nested folder, deletes it and makes sure the UI is
|
| +// consistent.
|
| +- (void)testDeleteCurrentSubfolder {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openBookmarkFolder:@"Folder 1"];
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabel(@"Folder 2")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabel(@"Folder 3")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Delete the folder.
|
| + [[self class] deleteSelectedFolder];
|
| +
|
| + // Folder 3 is now deleted, UI should have moved to Folder 2, and Folder 2
|
| + // should be empty.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Folder 2")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| + [[self class] assertChildCount:0 ofFolderWithName:@"Folder 2"];
|
| + [[self class] assertFolderDoesntExistWithTitle:@"Folder 3"];
|
| + [[self class] waitForDeletionOfBookmarkWithTitle:@"Folder 3"];
|
| +}
|
| +
|
| +// Navigates to a deeply nested folder, delete its parent programatically.
|
| +// Verifies that the UI is as expected.
|
| +- (void)testDeleteParentFolder {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openBookmarkFolder:@"Folder 1"];
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabel(@"Folder 2")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:buttonWithAccessibilityLabel(@"Folder 3")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Remove the parent programmatically.
|
| + [[self class] removeBookmarkWithTitle:@"Folder 2"];
|
| +
|
| + // Folder 2 and 3 are now deleted, UI should have moved to Folder1, and
|
| + // Folder 1 should be empty.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_kindOfClass(NSClassFromString(
|
| + @"BookmarkNavigationBar")),
|
| + grey_descendant(grey_text(@"Folder 1")),
|
| + nil)]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| + [[self class] assertChildCount:0 ofFolderWithName:@"Folder 1"];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Folder 2")]
|
| + assertWithMatcher:grey_notVisible()];
|
| + [[self class] assertFolderDoesntExistWithTitle:@"Folder 2"];
|
| + [[self class] assertFolderDoesntExistWithTitle:@"Folder 3"];
|
| +
|
| + // Check that the selected folder in the menu is Folder 1.
|
| + if (IsCompact()) {
|
| + // Opens the bookmark manager sidebar on handsets.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Menu")]
|
| + performAction:grey_tap()];
|
| + }
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_kindOfClass(
|
| + NSClassFromString(@"BookmarkMenuCell")),
|
| + grey_descendant(grey_text(@"Folder 1")),
|
| + nil)]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +}
|
| +
|
| +// Tests that the menu button changes to a back button as expected when browsing
|
| +// nested folders.
|
| +- (void)testBrowseNestedFolders {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Navigate down the nested folders.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder 1")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder 2")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder 3")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify the back button is visible to be able to go back to parent.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Parent")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + if (IsCompact()) {
|
| + // Verify menu button becomes back button in phone only.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Menu")]
|
| + assertWithMatcher:grey_notVisible()];
|
| + }
|
| +
|
| + // Go back two levels to Folder 1.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Parent")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Parent")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify back button is hidden again.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Parent")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + if (IsCompact()) {
|
| + // Verify menu button reappears.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Menu")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| + }
|
| +}
|
| +
|
| +// Tests moving a bookmark into a new folder created in the moving process.
|
| +- (void)testCreateNewFolderWhileMovingBookmark {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Tap the info disclosure indicator for the bookmark we want to move.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"First URL Info")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Choose to move the bookmark in the context menu.
|
| + [[EarlGrey selectElementWithMatcher:actionSheet(ActionMove)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Choose to move the bookmark into a new folder.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Create New Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Enter custom new folder name.
|
| + [[self class] renameBookmarkFolderWithFolderTitle:@"Title For New Folder"];
|
| +
|
| + // Verify current parent folder (Change Folder) is Bookmarks folder.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_accessibilityID(@"Change Folder"),
|
| + grey_accessibilityLabel(@"Mobile Bookmarks"),
|
| + nil)]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Choose new parent folder (Change Folder).
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Change Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify folder picker UI is displayed.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Picker")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Verify Folder 2 only has one item.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"Folder 2"];
|
| +
|
| + // Select Folder 2 as new Change Folder.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder 2")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify folder picker is dismissed and folder creator is now visible.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Creator")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Picker")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Verify picked parent folder (Change Folder) is Folder 2.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_accessibilityID(@"Change Folder"),
|
| + grey_accessibilityLabel(@"Folder 2"), nil)]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Tap Done (accessibilityID is 'Save') to close bookmark move flow.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Save")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify all folder flow UI is now closed.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Creator")]
|
| + assertWithMatcher:grey_notVisible()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Picker")]
|
| + assertWithMatcher:grey_notVisible()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Editor")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Verify new folder has been created under Folder 2.
|
| + [[self class] assertChildCount:2 ofFolderWithName:@"Folder 2"];
|
| +
|
| + // Verify new folder has one bookmark.
|
| + [[self class] assertChildCount:1 ofFolderWithName:@"Title For New Folder"];
|
| +}
|
| +
|
| +// Navigates to a deeply nested folder, deletes its root ancestor and checks
|
| +// that the UI is on the top level folder.
|
| +- (void)testDeleteRootFolder {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openBookmarkFolder:@"Folder 1"];
|
| + [[EarlGrey selectElementWithMatcher:grey_text(@"Folder 2")]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:grey_text(@"Folder 3")]
|
| + performAction:grey_tap()];
|
| +
|
| + [[self class] removeBookmarkWithTitle:@"Folder 1"];
|
| +
|
| + NSString* rootFolderTitle = nil;
|
| + if (experimental_flags::IsAllBookmarksEnabled()) {
|
| + rootFolderTitle = @"Bookmarks";
|
| + } else {
|
| + rootFolderTitle = @"Mobile Bookmarks";
|
| + }
|
| +
|
| + // Folder 2 and 3 are now deleted, UI should have moved to top level folder.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_kindOfClass(NSClassFromString(
|
| + @"BookmarkNavigationBar")),
|
| + grey_descendant(grey_text(rootFolderTitle)),
|
| + nil)] assertWithMatcher:grey_notNil()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Folder 1")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + if (IsCompact()) {
|
| + // Opens the bookmark manager sidebar on handsets.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Menu")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Test that the root folder is selected in the menu. This is only the case
|
| + // on iPhone.
|
| + if (experimental_flags::IsAllBookmarksEnabled()) {
|
| + rootFolderTitle = @"All Bookmarks";
|
| + }
|
| +
|
| + GREYElementMatcherBlock* selectedMatcher =
|
| + [GREYElementMatcherBlock matcherWithMatchesBlock:^BOOL(id element) {
|
| + UITableViewCell* cell = (UITableViewCell*)element;
|
| + return [cell isSelected];
|
| + }
|
| + descriptionBlock:^void(id<GREYDescription> description) {
|
| + [description appendText:@"Selected UI element."];
|
| + }];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(grey_kindOfClass(NSClassFromString(
|
| + @"BookmarkMenuCell")),
|
| + grey_descendant(
|
| + grey_text(rootFolderTitle)),
|
| + nil)]
|
| + assertWithMatcher:selectedMatcher];
|
| + }
|
| +
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Folder 1")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +}
|
| +
|
| +// Tests that keyboard commands are registered when a bookmark is added with the
|
| +// new bookmark UI as it shows only a snackbar.
|
| +- (void)testKeyboardCommandsRegistered_AddBookmark {
|
| + // Add the bookmark.
|
| + [[self class] starCurrentTab];
|
| + GREYAssertTrue(chrome_test_util::GetRegisteredKeyCommandsCount() > 0,
|
| + @"Some keyboard commands are registered.");
|
| +}
|
| +
|
| +// Tests that keyboard commands are not registered when a bookmark is edited, as
|
| +// the edit screen is presented modally.
|
| +- (void)testKeyboardCommandsNotRegistered_EditBookmark {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openMobileBookmarks];
|
| +
|
| + // Go to a bookmarked page. Tap on one of the standard bookmark.
|
| + [[EarlGrey selectElementWithMatcher:grey_text(@"Second URL")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Edit the bookmark.
|
| + if (!IsCompact()) {
|
| + [[EarlGrey selectElementWithMatcher:starButton()] performAction:grey_tap()];
|
| + } else {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:litStarButtoniPhone()]
|
| + performAction:grey_tap()];
|
| + }
|
| + GREYAssertTrue(chrome_test_util::GetRegisteredKeyCommandsCount() == 0,
|
| + @"No keyboard commands are registered.");
|
| +}
|
| +
|
| +// Tests that tapping No thanks on the promo make it disappear.
|
| +- (void)testPromoNoThanksMakeItDisappear {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openTopLevelBookmarksFolder];
|
| +
|
| + // We are going to set the PromoAlreadySeen preference. Set a teardown handler
|
| + // to reset it.
|
| + [self setTearDownHandler:^{
|
| + [[self class] setPromoAlreadySeen:NO];
|
| + }];
|
| + // Check that promo is visible.
|
| + [[self class] verifyPromoAlreadySeen:NO];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"promo_view")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Tap the dismiss button.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"promo_no_thanks_button")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait until promo is gone.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"promo_view")]
|
| + assertWithMatcher:grey_notVisible()];
|
| +
|
| + // Check that the promo already seen state is updated.
|
| + [[self class] verifyPromoAlreadySeen:YES];
|
| +}
|
| +
|
| +// Tests that tapping Sign in on the promo make the Sign in sheet appear and
|
| +// the promo still appears after dismissing the Sign in sheet.
|
| +- (void)testUIPromoSignIn {
|
| + [[self class] setupStandardBookmarks];
|
| + [[self class] openTopLevelBookmarksFolder];
|
| + // Set up a fake identity.
|
| + ChromeIdentity* identity =
|
| + [FakeChromeIdentity identityWithEmail:@"fakefoo@egmail.com"
|
| + gaiaID:@"fakefoopassword"
|
| + name:@"Fake Foo"];
|
| + ios::FakeChromeIdentityService::GetInstanceFromChromeProvider()->AddIdentity(
|
| + identity);
|
| +
|
| + // Check that promo is visible.
|
| + [[self class] verifyPromoAlreadySeen:NO];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"promo_view")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + // Tap the Sign in button.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"promo_sign_in_button")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Tap the CANCEL button.
|
| + [[EarlGrey selectElementWithMatcher:
|
| + grey_buttonTitle([l10n_util::GetNSString(
|
| + IDS_IOS_ACCOUNT_CONSISTENCY_SETUP_SKIP_BUTTON)
|
| + uppercaseString])] performAction:grey_tap()];
|
| +
|
| + // Check that the bookmarks UI reappeared and the cell is still here.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"promo_view")]
|
| + assertWithMatcher:grey_notNil()];
|
| +
|
| + [[self class] verifyPromoAlreadySeen:NO];
|
| +}
|
| +
|
| +#pragma mark Helper Methods
|
| +
|
| +// Navigates to the bookmark manager UI.
|
| ++ (void)openBookmarks {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| +
|
| + // Opens the bookmark manager.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(kToolsMenuBookmarksId)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Wait for it to load, and the menu to go away.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(kToolsMenuBookmarksId)]
|
| + assertWithMatcher:grey_nil()];
|
| +}
|
| +
|
| +// Navigates to the bookmark manager UI, and selects |bookmarkFolder|.
|
| ++ (void)openBookmarkFolder:(NSString*)bookmarkFolder {
|
| + [BookmarksTestCase openBookmarks];
|
| + if (IsCompact()) {
|
| + // Opens the bookmark manager sidebar on handsets.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Menu")]
|
| + performAction:grey_tap()];
|
| + }
|
| +
|
| + // Selects the folder with label |bookmarkFolder|.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_kindOfClass(
|
| + NSClassFromString(@"BookmarkMenuCell")),
|
| + grey_descendant(grey_text(bookmarkFolder)),
|
| + nil)] performAction:grey_tap()];
|
| +}
|
| +
|
| +// Navigates to the bookmark manager UI, and selects the top level folder.
|
| ++ (void)openTopLevelBookmarksFolder {
|
| + if (experimental_flags::IsAllBookmarksEnabled()) {
|
| + [BookmarksTestCase openBookmarkFolder:@"All Bookmarks"];
|
| + } else {
|
| + [BookmarksTestCase openMobileBookmarks];
|
| + }
|
| +}
|
| +
|
| +// Navigates to the bookmark manager UI, and selects MobileBookmarks.
|
| ++ (void)openMobileBookmarks {
|
| + [BookmarksTestCase openBookmarkFolder:@"Mobile Bookmarks"];
|
| +}
|
| +
|
| +// Navigates to the edit folder UI for |folderTitle|.
|
| ++ (void)openEditBookmarkFolderWithFolderTitle:(NSString*)folderTitle {
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(folderTitle)]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:editBookmarkButton()]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Dismisses the edit folder UI.
|
| ++ (void)closeEditBookmarkFolder {
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Rename folder title to |folderTitle|. Must be in edit folder UI.
|
| ++ (void)renameBookmarkFolderWithFolderTitle:(NSString*)folderTitle {
|
| + NSString* titleIdentifier = @"Title_textField";
|
| + NSString* clearTextFieldIdentifier = @"Clear text";
|
| +
|
| + // Edit the title field.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(titleIdentifier)]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(
|
| + clearTextFieldIdentifier)]
|
| + performAction:grey_tap()];
|
| +
|
| + // Type in the new title and use '\n' to dismiss the keyboard.
|
| + NSString* folderTitleWithNewLine =
|
| + [NSString stringWithFormat:@"%@\n", folderTitle];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(titleIdentifier)]
|
| + performAction:grey_typeText(folderTitleWithNewLine)];
|
| +}
|
| +
|
| +// Tap on the star to bookmark a page, then edit the bookmark to change the
|
| +// title to |title|.
|
| ++ (void)bookmarkCurrentTabWithTitle:(NSString*)title {
|
| + [[self class] waitForBookmarkModelLoaded:YES];
|
| + // Add the bookmark from the UI.
|
| + [[self class] starCurrentTab];
|
| +
|
| + // Set the bookmark name.
|
| + [[EarlGrey selectElementWithMatcher:editBookmarkButton()]
|
| + performAction:grey_tap()];
|
| + NSString* titleIdentifier = @"Title Field_textField";
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(titleIdentifier)]
|
| + performAction:grey_tap()];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Clear text")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Use '\n' to tap Done and dismiss the keyboard.
|
| + NSString* bookmarkTitle = [NSString stringWithFormat:@"%@\n", title];
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(titleIdentifier)]
|
| + performAction:grey_typeText(bookmarkTitle)];
|
| +
|
| + // Dismiss the window.
|
| + [[EarlGrey selectElementWithMatcher:bookmarksDoneButton()]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Waits for the bookmark model to be loaded in memory.
|
| ++ (void)waitForBookmarkModelLoaded:(BOOL)loaded {
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| + GREYAssert(testing::WaitUntilConditionOrTimeout(
|
| + testing::kWaitForUIElementTimeout,
|
| + ^{
|
| + return bookmarkModel->loaded() == loaded;
|
| + }),
|
| + @"Bookmark model was not loaded");
|
| +}
|
| +
|
| +// Asserts that a folder called |title| exists.
|
| ++ (void)assertFolderExists:(NSString*)title {
|
| + base::string16 folderTitle16(base::SysNSStringToUTF16(title));
|
| + bookmarks::BookmarkModel* bookmark_model =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| +
|
| + ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
|
| + bookmark_model->root_node());
|
| + BOOL folderExists = NO;
|
| +
|
| + while (iterator.has_next()) {
|
| + const bookmarks::BookmarkNode* bookmark = iterator.Next();
|
| + if (bookmark->is_url())
|
| + continue;
|
| + // This is a folder.
|
| + if (bookmark->GetTitle() == folderTitle16) {
|
| + folderExists = YES;
|
| + break;
|
| + }
|
| + }
|
| +
|
| + NSString* assertMessage =
|
| + [NSString stringWithFormat:@"Folder %@ doesn't exist", title];
|
| + GREYAssert(folderExists, assertMessage);
|
| +}
|
| +
|
| +// Asserts that |expectedCount| bookmarks exist with the corresponding |title|
|
| +// using the BookmarkModel.
|
| ++ (void)assertBookmarksWithTitle:(NSString*)title
|
| + expectedCount:(NSUInteger)expectedCount {
|
| + // Get BookmarkModel and wait for it to be loaded.
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| +
|
| + // Verify the correct number of bookmarks exist.
|
| + base::string16 matchString = base::SysNSStringToUTF16(title);
|
| + std::vector<bookmarks::TitledUrlMatch> matches;
|
| + bookmarkModel->GetBookmarksMatching(matchString, 50, &matches);
|
| + const size_t count = matches.size();
|
| + GREYAssertEqual(expectedCount, count, @"Unexpected number of bookmarks");
|
| +}
|
| +
|
| +// Check that the currently edited bookmark is in |folderName| folder.
|
| ++ (void)assertFolderName:(NSString*)folderName {
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_allOf(
|
| + grey_accessibilityID(@"Change Folder"),
|
| + grey_accessibilityLabel(folderName), nil)]
|
| + assertWithMatcher:grey_notNil()];
|
| +}
|
| +
|
| +// Verifies that there is |count| children on the bookmark folder with |name|.
|
| ++ (void)assertChildCount:(int)count ofFolderWithName:(NSString*)name {
|
| + base::string16 name16(base::SysNSStringToUTF16(name));
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| +
|
| + ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
|
| + bookmarkModel->root_node());
|
| +
|
| + const bookmarks::BookmarkNode* folder = NULL;
|
| + while (iterator.has_next()) {
|
| + const bookmarks::BookmarkNode* bookmark = iterator.Next();
|
| + if (bookmark->is_folder() && bookmark->GetTitle() == name16) {
|
| + folder = bookmark;
|
| + break;
|
| + }
|
| + }
|
| + GREYAssert(folder, @"No folder named %@", name);
|
| + GREYAssertEqual(
|
| + folder->child_count(), count,
|
| + @"Unexpected number of children in folder '%@': %d instead of %d", name,
|
| + folder->child_count(), count);
|
| +}
|
| +
|
| +// Adds a bookmark with the given |url| and |title| into the Mobile Bookmarks
|
| +// folder.
|
| ++ (void)addBookmark:(const GURL)url withTitle:(NSString*)title {
|
| + [[self class] waitForBookmarkModelLoaded:YES];
|
| + bookmarks::BookmarkModel* bookmark_model =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| + bookmark_model->AddURL(bookmark_model->mobile_node(), 0,
|
| + base::SysNSStringToUTF16(title), url);
|
| +}
|
| +
|
| +// Creates a new folder starting from the folder picker.
|
| +// Passing a |name| of 0 length will use the default value.
|
| ++ (void)addFolderWithName:(NSString*)name {
|
| + // Wait for folder picker to appear.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Picker")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Tap on Create new folder.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Create New Folder")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Verify the folder creator is displayed.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Folder Creator")]
|
| + assertWithMatcher:grey_sufficientlyVisible()];
|
| +
|
| + // Change the name of the folder.
|
| + if (name.length > 0) {
|
| + // TODO(crbug.com/644730): Use grey_replaceText instead of
|
| + // grey_clearText/grey_typeText when EarlGrey's issue is fixed:
|
| + // https://github.com/google/EarlGrey/issues/253
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Title_textField")]
|
| + performAction:grey_clearText()];
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Title_textField")]
|
| + performAction:grey_typeText(name)];
|
| + }
|
| +
|
| + // Tap the Save button.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Save")]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Loads a set of default bookmarks in the model for the tests to use.
|
| ++ (void)setupStandardBookmarks {
|
| + [[self class] waitForBookmarkModelLoaded:YES];
|
| +
|
| + bookmarks::BookmarkModel* bookmark_model =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| +
|
| + const GURL firstURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/pony.html");
|
| + NSString* firstTitle = @"First URL";
|
| + bookmark_model->AddURL(bookmark_model->mobile_node(), 0,
|
| + base::SysNSStringToUTF16(firstTitle), firstURL);
|
| +
|
| + const GURL secondURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/destination.html");
|
| + NSString* secondTitle = @"Second URL";
|
| + bookmark_model->AddURL(bookmark_model->mobile_node(), 0,
|
| + base::SysNSStringToUTF16(secondTitle), secondURL);
|
| +
|
| + NSString* folderTitle = @"Folder 1";
|
| + const bookmarks::BookmarkNode* folder1 = bookmark_model->AddFolder(
|
| + bookmark_model->mobile_node(), 0, base::SysNSStringToUTF16(folderTitle));
|
| +
|
| + folderTitle = @"Folder 2";
|
| + const bookmarks::BookmarkNode* folder2 = bookmark_model->AddFolder(
|
| + folder1, 0, base::SysNSStringToUTF16(folderTitle));
|
| +
|
| + folderTitle = @"Folder 3";
|
| + const bookmarks::BookmarkNode* folder3 = bookmark_model->AddFolder(
|
| + folder2, 0, base::SysNSStringToUTF16(folderTitle));
|
| +
|
| + const GURL thirdURL = web::test::HttpServer::MakeUrl(
|
| + "http://ios/testing/data/http_server_files/chromium_logo_page.html");
|
| + NSString* thirdTitle = @"Third URL";
|
| + bookmark_model->AddURL(folder3, 0, base::SysNSStringToUTF16(thirdTitle),
|
| + thirdURL);
|
| +}
|
| +
|
| +// Checks that the promo has already been seen or not.
|
| ++ (void)verifyPromoAlreadySeen:(BOOL)seen {
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + PrefService* prefs = browserState->GetPrefs();
|
| + if (prefs->GetBoolean(prefs::kIosBookmarkPromoAlreadySeen) == seen) {
|
| + return;
|
| + }
|
| + NSString* errorDesc = (seen)
|
| + ? @"Expected promo already seen, but it wasn't."
|
| + : @"Expected promo not already seen, but it was.";
|
| + GREYFail(errorDesc);
|
| +}
|
| +
|
| +// Checks that the promo has already been seen or not.
|
| ++ (void)setPromoAlreadySeen:(BOOL)seen {
|
| + ios::ChromeBrowserState* browserState =
|
| + chrome_test_util::GetOriginalBrowserState();
|
| + PrefService* prefs = browserState->GetPrefs();
|
| + prefs->SetBoolean(prefs::kIosBookmarkPromoAlreadySeen, seen);
|
| +}
|
| +
|
| ++ (void)assertExistenceOfBookmarkWithURL:(NSString*)URL name:(NSString*)name {
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| + const bookmarks::BookmarkNode* bookmark =
|
| + bookmarkModel->GetMostRecentlyAddedUserNodeForURL(
|
| + GURL(base::SysNSStringToUTF16(URL)));
|
| + GREYAssert(bookmark->GetTitle() == base::SysNSStringToUTF16(name),
|
| + @"Could not find bookmark named %@ for %@", name, URL);
|
| +}
|
| +
|
| ++ (void)assertAbsenceOfBookmarkWithURL:(NSString*)URL {
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| + const bookmarks::BookmarkNode* bookmark =
|
| + bookmarkModel->GetMostRecentlyAddedUserNodeForURL(
|
| + GURL(base::SysNSStringToUTF16(URL)));
|
| + GREYAssert(!bookmark, @"There is a bookmark for %@", URL);
|
| +}
|
| +
|
| +// Whether there is a bookmark folder with the given title.
|
| ++ (BOOL)folderExistsWithTitle:(NSString*)folderTitle {
|
| + base::string16 folderTitle16(base::SysNSStringToUTF16(folderTitle));
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| +
|
| + ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
|
| + bookmarkModel->root_node());
|
| +
|
| + while (iterator.has_next()) {
|
| + const bookmarks::BookmarkNode* bookmark = iterator.Next();
|
| + if (bookmark->is_url())
|
| + continue;
|
| + // This is a folder.
|
| + if (bookmark->GetTitle() == folderTitle16)
|
| + return YES;
|
| + }
|
| + return NO;
|
| +}
|
| +
|
| +// Asserts that there is a bookmark folder with the given title.
|
| ++ (void)assertFolderExistsWithTitle:(NSString*)folderTitle {
|
| + GREYAssert([[self class] folderExistsWithTitle:folderTitle],
|
| + @"There is no folder named %@", folderTitle);
|
| +}
|
| +
|
| +// Asserts that there is no bookmark folder with the given title.
|
| ++ (void)assertFolderDoesntExistWithTitle:(NSString*)folderTitle {
|
| + GREYAssert(![[self class] folderExistsWithTitle:folderTitle],
|
| + @"There is a folder named %@", folderTitle);
|
| +}
|
| +
|
| +// Deletes via the UI the currently focused folder. This must be called once
|
| +// already in a non permanent folder (i.e. not Mobile Bookmarks, etc.).
|
| ++ (void)deleteSelectedFolder {
|
| + // Enter edit mode.
|
| + [[EarlGrey
|
| + selectElementWithMatcher:grey_accessibilityID(@"Edit_navigation_bar")]
|
| + performAction:grey_tap()];
|
| +
|
| + // Delete the folder.
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Delete Folder")]
|
| + performAction:grey_tap()];
|
| +}
|
| +
|
| +// Removes programmatically the first bookmark with the given title.
|
| ++ (void)removeBookmarkWithTitle:(NSString*)title {
|
| + base::string16 name16(base::SysNSStringToUTF16(title));
|
| + bookmarks::BookmarkModel* bookmarkModel =
|
| + ios::BookmarkModelFactory::GetForBrowserState(
|
| + chrome_test_util::GetOriginalBrowserState());
|
| + ui::TreeNodeIterator<const bookmarks::BookmarkNode> iterator(
|
| + bookmarkModel->root_node());
|
| + while (iterator.has_next()) {
|
| + const bookmarks::BookmarkNode* bookmark = iterator.Next();
|
| + if (bookmark->GetTitle() == name16) {
|
| + bookmarkModel->Remove(bookmark);
|
| + return;
|
| + }
|
| + }
|
| + GREYFail(@"Could not remove bookmark with name %@", title);
|
| +}
|
| +
|
| +// Waits for the disparition of the given |title| in the UI.
|
| ++ (void)waitForDeletionOfBookmarkWithTitle:(NSString*)title {
|
| + // Wait until it's gone.
|
| + ConditionBlock condition = ^{
|
| + NSError* error = nil;
|
| + [[EarlGrey selectElementWithMatcher:grey_accessibilityID(title)]
|
| + assertWithMatcher:grey_notVisible()
|
| + error:&error];
|
| + return error == nil;
|
| + };
|
| + GREYAssert(testing::WaitUntilConditionOrTimeout(10, condition),
|
| + @"Waiting for bookmark to go away");
|
| +}
|
| +
|
| +// Adds a bookmark for the current tab. Must be called when on a tab.
|
| ++ (void)starCurrentTab {
|
| + if (!IsCompact()) {
|
| + [[EarlGrey selectElementWithMatcher:starButton()] performAction:grey_tap()];
|
| + } else {
|
| + [ChromeEarlGreyUI openToolsMenu];
|
| + [[EarlGrey selectElementWithMatcher:addBookmarkButton()]
|
| + performAction:grey_tap()];
|
| + }
|
| +}
|
| +
|
| +@end
|
|
|