// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <EarlGrey/EarlGrey.h>
#import <XCTest/XCTest.h>

#include <memory>

#include "base/bind.h"
#include "base/ios/ios_util.h"
#include "base/strings/sys_string_conversions.h"
#include "base/test/scoped_command_line.h"
#include "components/reading_list/core/reading_list_model.h"
#include "components/search_engines/template_url.h"
#include "components/search_engines/template_url_service.h"
#include "components/strings/grit/components_strings.h"
#include "ios/chrome/browser/application_context.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/chrome_switches.h"
#include "ios/chrome/browser/experimental_flags.h"
#include "ios/chrome/browser/notification_promo.h"
#include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory.h"
#include "ios/chrome/browser/ntp_snippets/ios_chrome_content_suggestions_service_factory_util.h"
#include "ios/chrome/browser/reading_list/reading_list_model_factory.h"
#include "ios/chrome/browser/search_engines/template_url_service_factory.h"
#import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_whats_new_item.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_view_controller.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_constant.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_provider_test_singleton.h"
#import "ios/chrome/browser/ui/content_suggestions/ntp_home_test_utils.h"
#import "ios/chrome/browser/ui/location_bar/location_bar_coordinator.h"
#import "ios/chrome/browser/ui/ntp/new_tab_page_controller.h"
#import "ios/chrome/browser/ui/settings/settings_table_view_controller.h"
#import "ios/chrome/browser/ui/tab_grid/tab_grid_egtest_util.h"
#import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h"
#include "ios/chrome/browser/ui/util/ui_util.h"
#import "ios/chrome/browser/ui/util/uikit_ui_util.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/app/chrome_test_util.h"
#import "ios/chrome/test/app/history_test_util.h"
#import "ios/chrome/test/app/tab_test_util.h"
#include "ios/chrome/test/base/scoped_block_swizzler.h"
#include "ios/chrome/test/earl_grey/accessibility_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"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "ui/base/l10n/l10n_util.h"

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

using namespace content_suggestions;
using namespace ntp_home;
using namespace ntp_snippets;

namespace {
const char kPageLoadedString[] = "Page loaded!";
const char kPageURL[] = "/test-page.html";
const char kPageTitle[] = "Page title!";

// Provides responses for redirect and changed window location URLs.
std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
    const net::test_server::HttpRequest& request) {
  if (request.relative_url != kPageURL) {
    return nullptr;
  }
  std::unique_ptr<net::test_server::BasicHttpResponse> http_response =
      std::make_unique<net::test_server::BasicHttpResponse>();
  http_response->set_code(net::HTTP_OK);
  http_response->set_content("<html><head><title>" + std::string(kPageTitle) +
                             "</title></head><body>" +
                             std::string(kPageLoadedString) + "</body></html>");
  return std::move(http_response);
}
}

// Test case for the NTP home UI. More precisely, this tests the positions of
// the elements after interacting with the device.
@interface NTPHomeTestCase : ChromeTestCase

// Current non-incognito browser state.
@property(nonatomic, assign, readonly) ios::ChromeBrowserState* browserState;
// Mock provider from the singleton.
@property(nonatomic, assign, readonly) MockContentSuggestionsProvider* provider;
// Article category, used by the singleton.
@property(nonatomic, assign, readonly) ntp_snippets::Category category;

@property(nonatomic, assign) base::string16 defaultSearchEngine;

@end

@implementation NTPHomeTestCase

+ (void)setUp {
  [super setUp];

  // Clear the pasteboard in case there is a URL copied, triggering an omnibox
  // suggestion.
  UIPasteboard* pasteboard = [UIPasteboard generalPasteboard];
  [pasteboard setValue:@"" forPasteboardType:UIPasteboardNameGeneral];

  [self closeAllTabs];
  ios::ChromeBrowserState* browserState =
      chrome_test_util::GetOriginalBrowserState();

  // Sets the ContentSuggestionsService associated with this browserState to a
  // service with no provider registered, allowing to register fake providers
  // which do not require internet connection. The previous service is deleted.
  IOSChromeContentSuggestionsServiceFactory::GetInstance()->SetTestingFactory(
      browserState,
      base::BindRepeating(&CreateChromeContentSuggestionsService));

  ContentSuggestionsService* service =
      IOSChromeContentSuggestionsServiceFactory::GetForBrowserState(
          browserState);
  [[ContentSuggestionsTestSingleton sharedInstance]
      registerArticleProvider:service];
}

+ (void)tearDown {
  [self closeAllTabs];
  ios::ChromeBrowserState* browserState =
      chrome_test_util::GetOriginalBrowserState();
  ReadingListModelFactory::GetForBrowserState(browserState)->DeleteAllEntries();

  // Resets the Service associated with this browserState to a new service with
  // no providers. The previous service is deleted.
  IOSChromeContentSuggestionsServiceFactory::GetInstance()->SetTestingFactory(
      browserState,
      base::BindRepeating(&CreateChromeContentSuggestionsService));
  [super tearDown];
}

- (void)setUp {
  self.provider->FireCategoryStatusChanged(self.category,
                                           CategoryStatus::AVAILABLE);

  ReadingListModel* readingListModel =
      ReadingListModelFactory::GetForBrowserState(self.browserState);
  readingListModel->DeleteAllEntries();
  [super setUp];

  // Get the default Search Engine.
  ios::ChromeBrowserState* browser_state =
      chrome_test_util::GetOriginalBrowserState();
  TemplateURLService* service =
      ios::TemplateURLServiceFactory::GetForBrowserState(browser_state);
  self.defaultSearchEngine = service->GetDefaultSearchProvider()->short_name();
}

- (void)tearDown {
  self.provider->FireCategoryStatusChanged(
      self.category, CategoryStatus::ALL_SUGGESTIONS_EXPLICITLY_DISABLED);
  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait
                           errorOrNil:nil];

  // Set the search engine back to the default in case the test fails before
  // cleaning it up.
  ios::ChromeBrowserState* browser_state =
      chrome_test_util::GetOriginalBrowserState();
  TemplateURLService* service =
      ios::TemplateURLServiceFactory::GetForBrowserState(browser_state);
  std::vector<TemplateURL*> urls = service->GetTemplateURLs();

  for (auto iter = urls.begin(); iter != urls.end(); ++iter) {
    if (self.defaultSearchEngine == (*iter)->short_name()) {
      service->SetUserSelectedDefaultSearchProvider(*iter);
    }
  }

  [super tearDown];
}

#pragma mark - Properties

- (ios::ChromeBrowserState*)browserState {
  return chrome_test_util::GetOriginalBrowserState();
}

- (MockContentSuggestionsProvider*)provider {
  return [[ContentSuggestionsTestSingleton sharedInstance] provider];
}

- (ntp_snippets::Category)category {
  return ntp_snippets::Category::FromKnownCategory(KnownCategories::ARTICLES);
}

#pragma mark - Tests

// Tests that all items are accessible on the home page.
- (void)testAccessibility {
  chrome_test_util::VerifyAccessibilityForCurrentScreen();
}

// Tests that the collections shortcut are displayed and working.
- (void)testCollectionShortcuts {
  // Check the Bookmarks.
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId(
                                   IDS_IOS_CONTENT_SUGGESTIONS_BOOKMARKS)]
      performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::HeaderWithAccessibilityLabelId(
                                   IDS_IOS_CONTENT_SUGGESTIONS_BOOKMARKS)]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
      performAction:grey_tap()];

  // Check the ReadingList.
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId(
                                   IDS_IOS_CONTENT_SUGGESTIONS_READING_LIST)]
      performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::HeaderWithAccessibilityLabelId(
                                   IDS_IOS_TOOLS_MENU_READING_LIST)]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
      performAction:grey_tap()];

  // Check the RecentTabs.
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId(
                                   IDS_IOS_CONTENT_SUGGESTIONS_RECENT_TABS)]
      performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::HeaderWithAccessibilityLabelId(
                                   IDS_IOS_CONTENT_SUGGESTIONS_RECENT_TABS)]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
      performAction:grey_tap()];

  // Check the History.
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::ButtonWithAccessibilityLabelId(
                                   IDS_IOS_CONTENT_SUGGESTIONS_HISTORY)]
      performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::HeaderWithAccessibilityLabelId(
                                   IDS_HISTORY_TITLE)]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
      performAction:grey_tap()];
}

// Tests that the fake omnibox width is correctly updated after a rotation.
- (void)testOmniboxWidthRotation {
  // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is
  // fixed.
  if (IsIPadIdiom()) {
    EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug.");
  }
  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
  UIEdgeInsets safeArea = CollectionView().safeAreaInsets;
  CGFloat collectionWidth =
      CGRectGetWidth(UIEdgeInsetsInsetRect(CollectionView().bounds, safeArea));
  GREYAssertTrue(collectionWidth > 0, @"The collection width is nil.");
  CGFloat fakeOmniboxWidth = searchFieldWidth(collectionWidth);

  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];

  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
                           errorOrNil:nil];
  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];

  safeArea = CollectionView().safeAreaInsets;
  CGFloat collectionWidthAfterRotation =
      CGRectGetWidth(UIEdgeInsetsInsetRect(CollectionView().bounds, safeArea));
  GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation,
                     @"The collection width has not changed.");
  fakeOmniboxWidth = searchFieldWidth(collectionWidthAfterRotation);

  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];
}

// Tests that the fake omnibox width is correctly updated after a rotation done
// while the settings screen is shown.
- (void)testOmniboxWidthRotationBehindSettings {
  // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is
  // fixed.
  if (IsRegularXRegularSizeClass()) {
    EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug.");
  }
  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
  UIEdgeInsets safeArea = CollectionView().safeAreaInsets;
  CGFloat collectionWidth =
      CGRectGetWidth(UIEdgeInsetsInsetRect(CollectionView().bounds, safeArea));
  GREYAssertTrue(collectionWidth > 0, @"The collection width is nil.");
  CGFloat fakeOmniboxWidth = searchFieldWidth(collectionWidth);

  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];

  [ChromeEarlGreyUI openSettingsMenu];

  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
                           errorOrNil:nil];
  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];

  [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()]
      performAction:grey_tap()];

  safeArea = CollectionView().safeAreaInsets;
  CGFloat collectionWidthAfterRotation =
      CGRectGetWidth(UIEdgeInsetsInsetRect(CollectionView().bounds, safeArea));
  GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation,
                     @"The collection width has not changed.");
  fakeOmniboxWidth = searchFieldWidth(collectionWidthAfterRotation);

  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:OmniboxWidth(fakeOmniboxWidth)];
}

// Tests that the fake omnibox width is correctly updated after a rotation done
// while the fake omnibox is pinned to the top.
- (void)testOmniboxPinnedWidthRotation {
  // TODO(crbug.com/652465): Enable the test for iPad when rotation bug is
  // fixed.
  if (IsRegularXRegularSizeClass()) {
    EARL_GREY_TEST_DISABLED(@"Disabled for iPad due to device rotation bug.");
  }

  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_swipeFastInDirection(kGREYDirectionUp)];

  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
  CGFloat collectionWidth = CollectionView().bounds.size.width;
  GREYAssertTrue(collectionWidth > 0, @"The collection width is nil.");

  // The fake omnibox might be slightly bigger than the screen in order to cover
  // it for all screen scale.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:OmniboxWidthBetween(collectionWidth + 1, 2)];

  [EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
                           errorOrNil:nil];

  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
  CGFloat collectionWidthAfterRotation = CollectionView().bounds.size.width;
  GREYAssertNotEqual(collectionWidth, collectionWidthAfterRotation,
                     @"The collection width has not changed.");

  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:grey_not(grey_sufficientlyVisible())];
}

// Tests that the app doesn't crash when opening multiple tabs.
- (void)testOpenMultipleTabs {
  NSInteger numberOfTabs = 10;
  for (NSInteger i = 0; i < numberOfTabs; i++) {
    [ChromeEarlGreyUI openNewTab];
  }
  id<GREYMatcher> matcher;
  if (IsIPadIdiom()) {
    matcher = grey_accessibilityID(@"Enter Tab Switcher");
  } else {
    matcher = grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier),
                         grey_sufficientlyVisible(), nil);
  }
  [[EarlGrey selectElementWithMatcher:matcher]
      assertWithMatcher:grey_accessibilityValue([NSString
                            stringWithFormat:@"%@", @(numberOfTabs + 1)])];
}

// Tests that the promo is correctly displayed and removed once tapped.
- (void)testPromoTap {
  // Setup the promo.
  NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
  [defaults setInteger:experimental_flags::WHATS_NEW_MOVE_TO_DOCK_TIP
                forKey:@"WhatsNewPromoStatus"];
  PrefService* local_state = GetApplicationContext()->GetLocalState();
  ios::NotificationPromo::MigrateUserPrefs(local_state);

  // Open a new tab to have the promo.
  [ChromeEarlGreyUI openNewTab];

  // Tap the promo.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          [ContentSuggestionsWhatsNewItem
                                              accessibilityIdentifier])]
      performAction:grey_tap()];

  // Promo dismissed.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          [ContentSuggestionsWhatsNewItem
                                              accessibilityIdentifier])]
      assertWithMatcher:grey_not(grey_sufficientlyVisible())];

  // Reset the promo.
  [defaults setInteger:experimental_flags::WHATS_NEW_DEFAULT
                forKey:@"WhatsNewPromoStatus"];
  ios::NotificationPromo::MigrateUserPrefs(local_state);
}

// Tests that the position of the collection view is restored when navigating
// back to the NTP.
- (void)testPositionRestored {
  [self addMostVisitedTile];

  // Add suggestions to be able to scroll on iPad.
  ReadingListModelFactory::GetForBrowserState(self.browserState)
      ->AddEntry(GURL("http://chromium.org/"), "title",
                 reading_list::ADDED_VIA_CURRENT_APP);
  self.provider->FireSuggestionsChanged(self.category, ntp_home::Suggestions());

  // Scroll to have a position to restored.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_scrollInDirection(kGREYDirectionDown, 150)];

  // Save the position before navigating.
  UIView* omnibox = ntp_home::FakeOmnibox();
  CGPoint previousPosition = omnibox.bounds.origin;

  // Navigate and come back.
  [[EarlGrey selectElementWithMatcher:
                 chrome_test_util::StaticTextWithAccessibilityLabel(
                     base::SysUTF8ToNSString(kPageTitle))]
      performAction:grey_tap()];
  [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString];
  [ChromeEarlGrey goBack];

  // Check that the new position is the same.
  omnibox = ntp_home::FakeOmnibox();
  GREYAssertEqual(previousPosition.y, omnibox.bounds.origin.y,
                  @"Omnibox not at the same position");
}

// Tests that when navigating back to the NTP while having the omnibox focused
// and moved up, the scroll position restored is the position before the omnibox
// is selected.
- (void)testPositionRestoredWithOmniboxFocused {
  [self addMostVisitedTile];

  // Add suggestions to be able to scroll on iPad.
  ReadingListModelFactory::GetForBrowserState(self.browserState)
      ->AddEntry(GURL("http://chromium.org/"), "title",
                 reading_list::ADDED_VIA_CURRENT_APP);
  self.provider->FireSuggestionsChanged(self.category, ntp_home::Suggestions());

  // Scroll to have a position to restored.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_scrollInDirection(kGREYDirectionDown, 150)];

  // Save the position before navigating.
  UIView* omnibox = ntp_home::FakeOmnibox();
  CGPoint previousPosition = omnibox.bounds.origin;

  // Tap the omnibox to focus it.
  [self focusFakebox];

  // Navigate and come back.
  [[EarlGrey selectElementWithMatcher:
                 chrome_test_util::StaticTextWithAccessibilityLabel(
                     base::SysUTF8ToNSString(kPageTitle))]
      performAction:grey_tap()];
  [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString];
  [ChromeEarlGrey goBack];

  // Check that the new position is the same.
  omnibox = ntp_home::FakeOmnibox();
  GREYAssertEqual(previousPosition.y, omnibox.bounds.origin.y,
                  @"Omnibox not at the same position");
}

// Tests that tapping the fake omnibox focuses the real omnibox.
- (void)testTapFakeOmnibox {
  // TODO(crbug.com/753098): Re-enable this test on iPad once grey_typeText
  // works.
  if (IsRegularXRegularSizeClass()) {
    EARL_GREY_TEST_DISABLED(@"Test disabled on iPad.");
  }
  // Setup the server.
  self.testServer->RegisterRequestHandler(base::Bind(&StandardResponse));
  GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
  const GURL pageURL = self.testServer->GetURL(kPageURL);

  NSString* URL = base::SysUTF8ToNSString(pageURL.spec());
  // Tap the fake omnibox, type the URL in the real omnibox and navigate to the
  // page.
  [self focusFakebox];

  [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
      performAction:grey_typeText([URL stringByAppendingString:@"\n"])];

  // Check that the page is loaded.
  [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString];
}

// Tests that tapping the omnibox search button logs correctly.
// It is important for ranking algorithm of omnibox that requests from the
// search button and real omnibox are marked appropriately.
- (void)testTapOmniboxSearchButtonLogsCorrectly {
  if (IsRegularXRegularSizeClass()) {
    // This logging only happens on iPhone, since on iPad there's no secondary
    // toolbar.
    return;
  }

  // Swizzle the method that needs to be called for correct logging.
  __block BOOL tapped = NO;
  ScopedBlockSwizzler swizzler([LocationBarCoordinator class],
                               @selector(focusOmniboxFromSearchButton), ^{
                                 tapped = YES;
                               });

  // Tap the search button.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          kToolbarOmniboxButtonIdentifier)]
      performAction:grey_tap()];

  // Check that the page is loaded.
  GREYAssertTrue(tapped,
                 @"The tap on the search button was not correctly logged.");
}

// Tests that tapping the fake omnibox moves the collection.
- (void)testTapFakeOmniboxScroll {
  // Get the collection and its layout.
  UIView* collection = ntp_home::CollectionView();
  GREYAssertTrue([collection isKindOfClass:[UICollectionView class]],
                 @"The collection has not been correctly selected.");
  UICollectionView* collectionView = (UICollectionView*)collection;
  GREYAssertTrue(
      [collectionView.delegate
          conformsToProtocol:@protocol(UICollectionViewDelegateFlowLayout)],
      @"The collection has not the expected delegate.");
  id<UICollectionViewDelegateFlowLayout> delegate =
      (id<UICollectionViewDelegateFlowLayout>)(collectionView.delegate);
  CGFloat headerHeight =
      [delegate collectionView:collectionView
                                   layout:collectionView.collectionViewLayout
          referenceSizeForHeaderInSection:0]
          .height;

  // Offset before the tap.
  CGPoint origin = collectionView.contentOffset;

  // Tap the omnibox to focus it.
  [self focusFakebox];

  // Offset after the fake omnibox has been tapped.
  CGPoint offsetAfterTap = collectionView.contentOffset;

  // Make sure the fake omnibox has been hidden and the collection has moved.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:grey_not(grey_sufficientlyVisible())];

  CGFloat top = ntp_home::CollectionView().safeAreaInsets.top;
  GREYAssertTrue(offsetAfterTap.y >= origin.y + headerHeight - (60 + top),
                 @"The collection has not moved.");

  // Unfocus the omnibox.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_tapAtPoint(CGPointMake(0, offsetAfterTap.y + 100))];

  // Check the fake omnibox is displayed again at the same position.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:grey_sufficientlyVisible()];

  GREYAssertEqual(
      origin.y, collectionView.contentOffset.y,
      @"The collection is not scrolled back to its previous position");
}

// Tests that tapping the fake omnibox then unfocusing it moves the collection
// back to where it was.
- (void)testTapFakeOmniboxScrollScrolled {
  // Get the collection and its layout.
  UIView* collection = ntp_home::CollectionView();
  GREYAssertTrue([collection isKindOfClass:[UICollectionView class]],
                 @"The collection has not been correctly selected.");
  UICollectionView* collectionView = (UICollectionView*)collection;

  // Scroll to have a position different from the default.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_scrollInDirection(kGREYDirectionDown, 50)];

  // Offset before the tap.
  CGPoint origin = collectionView.contentOffset;

  // Tap the omnibox to focus it.
  [self focusFakebox];

  // Unfocus the omnibox.
  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_tapAtPoint(
                        CGPointMake(0, collectionView.contentOffset.y + 100))];

  // Check the fake omnibox is displayed again at the same position.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:grey_sufficientlyVisible()];

  // The collection might be slightly moved on iPhone.
  GREYAssertTrue(
      collectionView.contentOffset.y >= origin.y &&
          collectionView.contentOffset.y <= origin.y + 6,
      @"The collection is not scrolled back to its previous position");
}

// Tests tapping the search button when the fake omnibox is scrolled.
- (void)testTapSearchButtonFakeOmniboxScrolled {
  if (IsRegularXRegularSizeClass()) {
    // This only happens on iPhone, since on iPad there's no secondary toolbar.
    return;
  }

  [[EarlGrey selectElementWithMatcher:chrome_test_util::
                                          ContentSuggestionCollectionView()]
      performAction:grey_swipeFastInDirection(kGREYDirectionUp)];
  // Tap the search button.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          kToolbarOmniboxButtonIdentifier)]
      performAction:grey_tap()];
  [ChromeEarlGrey
      waitForElementWithMatcherSufficientlyVisible:chrome_test_util::Omnibox()];
}

- (void)testOpeningNewTab {
  // TODO(crbug.com/933953): Re-enable this test when grey_tap() issue is fixed.
  EARL_GREY_TEST_DISABLED(@"Disabled due to full-configs and slimnav failures");

  [ChromeEarlGreyUI openNewTab];

  // Check that the fake omnibox is here.
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:grey_sufficientlyVisible()];
  id<GREYMatcher> tabGridMatcher = nil;
  if (IsIPadIdiom()) {
    tabGridMatcher = grey_accessibilityID(@"Enter Tab Switcher");
  } else {
    tabGridMatcher =
        grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier),
                   grey_sufficientlyVisible(), nil);
  }
  [[EarlGrey selectElementWithMatcher:tabGridMatcher]
      assertWithMatcher:grey_accessibilityValue(
                            [NSString stringWithFormat:@"%i", 2])];

  // Test the same thing after opening a tab from the tab grid.
  [[EarlGrey selectElementWithMatcher:tabGridMatcher] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::TabGridNewTabButton()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      assertWithMatcher:grey_sufficientlyVisible()];
  [[EarlGrey selectElementWithMatcher:tabGridMatcher]
      assertWithMatcher:grey_accessibilityValue(
                            [NSString stringWithFormat:@"%i", 3])];
}

- (void)testFavicons {
  for (NSInteger index = 0; index < 8; index++) {
    [[EarlGrey
        selectElementWithMatcher:
            grey_accessibilityID([NSString
                stringWithFormat:
                    @"%@%li",
                    kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix,
                    index])] assertWithMatcher:grey_sufficientlyVisible()];
  }

  // Change the Search Engine to Yahoo!.
  [ChromeEarlGreyUI openSettingsMenu];
  [ChromeEarlGreyUI
      tapSettingsMenuButton:grey_accessibilityID(kSettingsSearchEngineCellId)];
  [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Yahoo!")]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()]
      performAction:grey_tap()];

  // Check again the favicons.
  for (NSInteger index = 0; index < 8; index++) {
    [[EarlGrey
        selectElementWithMatcher:
            grey_accessibilityID([NSString
                stringWithFormat:
                    @"%@%li",
                    kContentSuggestionsMostVisitedAccessibilityIdentifierPrefix,
                    index])] assertWithMatcher:grey_sufficientlyVisible()];
  }

  // Change the Search Engine to Google.
  [ChromeEarlGreyUI openSettingsMenu];
  [ChromeEarlGreyUI
      tapSettingsMenuButton:grey_accessibilityID(kSettingsSearchEngineCellId)];
  [[EarlGrey selectElementWithMatcher:grey_accessibilityLabel(@"Google")]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::SettingsDoneButton()]
      performAction:grey_tap()];
}

#pragma mark - Helpers

- (void)addMostVisitedTile {
  self.testServer->RegisterRequestHandler(base::Bind(&StandardResponse));
  GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
  const GURL pageURL = self.testServer->GetURL(kPageURL);

  // Clear history to ensure the tile will be shown.
  GREYAssertTrue(chrome_test_util::ClearBrowsingHistory(),
                 @"Clearing Browsing History timed out");
  [[GREYUIThreadExecutor sharedInstance] drainUntilIdle];
  [ChromeEarlGrey loadURL:pageURL];
  [ChromeEarlGrey waitForWebViewContainingText:kPageLoadedString];

  // After loading URL, need to do another action before opening a new tab
  // with the icon present.
  [ChromeEarlGrey goBack];
  [[self class] closeAllTabs];
  [ChromeEarlGrey openNewTab];
}

// Taps the fake omnibox and waits for the real omnibox to be visible.
- (void)focusFakebox {
  [[EarlGrey selectElementWithMatcher:grey_accessibilityID(
                                          FakeOmniboxAccessibilityID())]
      performAction:grey_tap()];
  [ChromeEarlGrey
      waitForElementWithMatcherSufficientlyVisible:chrome_test_util::Omnibox()];
}

@end
