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

#import <XCTest/XCTest.h>

#include "base/ios/ios_util.h"
#include "components/strings/grit/components_strings.h"
#include "ios/chrome/test/app/web_view_interaction_test_util.h"
#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
#import "ios/chrome/test/earl_grey/chrome_matchers.h"
#import "ios/chrome/test/earl_grey/chrome_test_case.h"
#import "ios/web/public/test/http_server.h"
#include "ios/web/public/test/http_server_util.h"
#include "ios/web/public/test/response_providers/data_response_provider.h"
#include "ui/base/l10n/l10n_util.h"

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

using chrome_test_util::BackButton;
using chrome_test_util::ForwardButton;
using chrome_test_util::TapWebViewElementWithId;
using chrome_test_util::WebViewContainingText;

namespace {

// URL for the test window.history.go() test file.  The page at this URL
// contains several buttons that trigger window.history commands.  Additionally
// the page contains several divs used to display the state of the page:
// - A div that is populated with |kOnLoadText| when the onload event fires.
// - A div that is populated with |kNoOpText| 1s after a button is tapped.
// - A div that is populated with |kPopStateReceivedText| when a popstate event
//   is received by the page.
// - A div that is populated with the state object (if it's a string) upon the
//   receipt of a popstate event.
// - A div that is populated with |kHashChangeReceivedText| when a hashchange
//   event is received.
// When a button on the page is tapped, all pre-existing div text is cleared,
// so matching against this webview text after a button is tapped ensures that
// the state is set in response to the most recently executed script.
const char kWindowHistoryGoTestURL[] =
    "http://ios/testing/data/http_server_files/history_go.html";

// URL of a sample file-based page.
const char kSampleFileBasedURL[] =
    "http://ios/testing/data/http_server_files/chromium_logo_page.html";

// Strings used by history_go.html.
const char kOnLoadText[] = "OnLoadText";
const char kNoOpText[] = "NoOpText";

// Button ids for history_go.html.
NSString* const kGoNoParameterID = @"go-no-parameter";
NSString* const kGoZeroID = @"go-zero";
NSString* const kGoTwoID = @"go-2";
NSString* const kGoBackTwoID = @"go-back-2";

// URLs and labels for tests that navigate back and forward.
const char kBackHTMLButtonLabel[] = "BackHTMLButton";
const char kForwardHTMLButtonLabel[] = "ForwardHTMLButton";
const char kForwardHTMLSentinel[] = "Forward page loaded";
const char kTestPageSentinel[] = "Test Page";
const char kBackURL[] = "http://back";
const char kForwardURL[] = "http://forward";
const char kTestURL[] = "http://test";

// URLs and labels for scenarioWindowLocation* tests.
const char kHashChangeWithHistoryLabel[] = "hashChangedWithHistory";
const char kHashChangeWithoutHistoryLabel[] = "hashChangedWithoutHistory";
const char kPage1URL[] = "http://page1";
const char kHashChangedWithHistoryURL[] =
    "http://page1/#hashChangedWithHistory";
const char kHashChangedWithoutHistoryURL[] =
    "http://page1/#hashChangedWithoutHistory";
const char kNoHashChangeText[] = "No hash change";
// An HTML page with two links that run JavaScript when they're clicked. The
// first link updates |window.location.hash|, the second link changes
// |window.location|.
const char kHashChangedHTML[] =
    "<html><body>"
    "<a href='javascript:window.location.hash=\"#hashChangedWithHistory\"' "
    "   id=\"hashChangedWithHistory\"'>hashChangedWithHistory</a><br />"
    "<a href='javascript:"
    "           window.location.replace(\"#hashChangedWithoutHistory\")' "
    "   id=\"hashChangedWithoutHistory\">hashChangedWithoutHistory</a>"
    "</body></html>";

void SetupBackAndForwardResponseProvider() {
  std::map<GURL, std::string> responses;
  GURL testURL = web::test::HttpServer::MakeUrl(kTestURL);
  GURL backURL = web::test::HttpServer::MakeUrl(kBackURL);
  GURL forwardURL = web::test::HttpServer::MakeUrl(kForwardURL);
  responses[testURL] = "<html>Test Page</html>";
  responses[backURL] =
      "<html>"
      "<input type=\"button\" value=\"BackHTMLButton\" id=\"BackHTMLButton\""
      "onclick=\"window.history.back()\" />"
      "</html>";
  responses[forwardURL] =
      "<html>"
      "<input type=\"button\" value=\"ForwardHTMLButton\""
      "id=\"ForwardHTMLButton\" onclick=\"window.history.forward()\" /></br>"
      "Forward page loaded</html>";
  web::test::SetUpSimpleHttpServer(responses);
}

// URLs for server redirect tests.
const char kRedirectIndexURL[] = "http://redirect";
const char kRedirect301URL[] = "http://redirect/redirect?code=301";
const char kRedirectWindowURL[] = "http://redirect/redirectWindow.html";
const char kRedirectRefreshURL[] = "http://redirect/redirectRefresh.html";
const char kDestinationURL[] = "http://redirect/destination.html";
const char kLastURL[] = "http://redirect/last.html";

class RedirectResponseProvider : public web::DataResponseProvider {
 public:
  RedirectResponseProvider()
      : index_url_(web::test::HttpServer::MakeUrl(kRedirectIndexURL)),
        redirect_301_url_(web::test::HttpServer::MakeUrl(kRedirect301URL)),
        redirect_refresh_url_(
            web::test::HttpServer::MakeUrl(kRedirectRefreshURL)),
        redirect_window_url_(
            web::test::HttpServer::MakeUrl(kRedirectWindowURL)),
        destination_url_(web::test::HttpServer::MakeUrl(kDestinationURL)) {}

 private:
  bool CanHandleRequest(const Request& request) override {
    return request.url == index_url_ || request.url == redirect_window_url_ ||
           request.url == redirect_refresh_url_ ||
           request.url == redirect_301_url_ || request.url == destination_url_;
  }
  void GetResponseHeadersAndBody(
      const Request& request,
      scoped_refptr<net::HttpResponseHeaders>* headers,
      std::string* response_body) override {
    *headers = GetDefaultResponseHeaders();
    if (request.url == index_url_) {
      *response_body =
          "<p><a href=\"redirect?code=301\""
          "      id=\"redirect301\">redirect301</a></p>"
          "<p><a href=\"redirectRefresh.html\""
          "      id=\"redirectRefresh\">redirectRefresh</a></p>"
          "<p><a href=\"redirectWindow.html\""
          "      id=\"redirectWindow\">redirectWindow</a></p>";
    } else if (request.url == redirect_301_url_) {
      *headers = GetRedirectResponseHeaders(destination_url_.spec(),
                                            net::HTTP_MOVED_PERMANENTLY);
    } else if (request.url == redirect_refresh_url_) {
      *response_body =
          "<head>"
          "  <meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=destination.html\">"
          "</head>"
          "<body><p>Redirecting</p></body>";
    } else if (request.url == redirect_window_url_) {
      *response_body =
          "<head>"
          "  <meta HTTP-EQUIV=\"REFRESH\" content=\"0; url=destination.html\">"
          "</head>"
          "<body>Redirecting"
          "  <script>window.open(\"destination.html\", \"_self\");</script>"
          "</body>";
    } else if (request.url == destination_url_) {
      *response_body = "<html><body><p>You've arrived</p></body></html>";
    } else if (request.url == last_url_) {
      *response_body = "<html><body><p>Go back from here</p></body></html>";
    } else {
      NOTREACHED();
    }
  }

  // Member variables for test URLs.
  const GURL index_url_;
  const GURL redirect_301_url_;
  const GURL redirect_refresh_url_;
  const GURL redirect_window_url_;
  const GURL destination_url_;
  const GURL last_url_;
};

}  // namespace

// Integration tests for navigating history via JavaScript and the forward and
// back buttons.
@interface NavigationTestCase : ChromeTestCase

// Adds hashchange listener to the page that changes the inner html of the page
// to |content| when a hashchange is detected.
- (void)addHashChangeListenerWithContent:(std::string)content;

// Loads index page for redirect operations, taps the link with |redirectLabel|
// and then perform series of back-forward navigations asserting the proper
// behavior.
- (void)verifyBackAndForwardAfterRedirect:(std::string)redirectLabel;

@end

@implementation NavigationTestCase

#pragma mark window.history.go operations

// Tests reloading the current page via window.history.go() with no parameters.
- (void)testHistoryGoNoParameter {
  web::test::SetUpFileBasedHttpServer();

  // Load the history test page and ensure that its onload text is visible.
  const GURL windowHistoryURL =
      web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL);
  [ChromeEarlGrey loadURL:windowHistoryURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];

  // Tap on the window.history.go() button.  This will clear |kOnLoadText|, so
  // the subsequent check for |kOnLoadText| will only pass if a reload has
  // occurred.
  [ChromeEarlGrey tapWebViewElementWithID:kGoNoParameterID];

  // Verify that the onload text is reset.
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];
}

// Tests reloading the current page via history.go(0).
- (void)testHistoryGoDeltaZero {
  web::test::SetUpFileBasedHttpServer();

  // Load the history test page and ensure that its onload text is visible.
  const GURL windowHistoryURL =
      web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL);
  [ChromeEarlGrey loadURL:windowHistoryURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];

  // Tap on the window.history.go() button.  This will clear |kOnLoadText|, so
  // the subsequent check for |kOnLoadText| will only pass if a reload has
  // occurred.
  [ChromeEarlGrey tapWebViewElementWithID:kGoZeroID];

  // Verify that the onload text is reset.
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];
}

// Tests that calling window.history.go() with an offset that is out of bounds
// is a no-op.
- (void)testHistoryGoOutOfBounds {
  web::test::SetUpFileBasedHttpServer();

  // Load the history test page and ensure that its onload text is visible.
  const GURL windowHistoryURL =
      web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL);
  [ChromeEarlGrey loadURL:windowHistoryURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];

  // Tap on the window.history.go(2) button.  This will clear all div text, so
  // the subsequent check for |kNoOpText| will only pass if no navigations have
  // occurred.
  [ChromeEarlGrey tapWebViewElementWithID:kGoTwoID];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kNoOpText)]
      assertWithMatcher:grey_notNil()];

  // Tap on the window.history.go(-2) button.  This will clear all div text, so
  // the subsequent check for |kNoOpText| will only pass if no navigations have
  // occurred.
  [ChromeEarlGrey tapWebViewElementWithID:kGoBackTwoID];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kNoOpText)]
      assertWithMatcher:grey_notNil()];
}

// Tests going back and forward via history.go().
- (void)testHistoryGoDelta {
  std::map<GURL, std::string> responses;
  const GURL firstURL = web::test::HttpServer::MakeUrl("http://page1");
  const GURL secondURL = web::test::HttpServer::MakeUrl("http://page2");
  const GURL thirdURL = web::test::HttpServer::MakeUrl("http://page3");
  const GURL fourthURL = web::test::HttpServer::MakeUrl("http://page4");
  responses[firstURL] =
      "page1 <input type='button' value='goForward' id='goForward' "
      "onclick='window.history.go(2)' />";
  responses[secondURL] = "page2";
  responses[thirdURL] = "page3";
  responses[fourthURL] =
      "page4 <input type='button' value='goBack' id='goBack' "
      "onclick='window.history.go(-3)' />";
  web::test::SetUpSimpleHttpServer(responses);

  // Load 4 pages.
  [ChromeEarlGrey loadURL:firstURL];
  [ChromeEarlGrey loadURL:secondURL];
  [ChromeEarlGrey loadURL:thirdURL];
  [ChromeEarlGrey loadURL:fourthURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText("page4")]
      assertWithMatcher:grey_notNil()];

  // Tap button to go back 3 pages.
  TapWebViewElementWithId("goBack");
  [[EarlGrey selectElementWithMatcher:WebViewContainingText("page1")]
      assertWithMatcher:grey_notNil()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          firstURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Tap button to go forward 2 pages.
  TapWebViewElementWithId("goForward");
  [[EarlGrey selectElementWithMatcher:WebViewContainingText("page3")]
      assertWithMatcher:grey_notNil()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          thirdURL.GetContent())]
      assertWithMatcher:grey_notNil()];
}

// Tests that calls to window.history.go() that span multiple documents causes
// a load to occur.
- (void)testHistoryCrossDocumentLoad {
  web::test::SetUpFileBasedHttpServer();

  // Load the history test page and ensure that its onload text is visible.
  const GURL windowHistoryURL =
      web::test::HttpServer::MakeUrl(kWindowHistoryGoTestURL);
  [ChromeEarlGrey loadURL:windowHistoryURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];

  const GURL sampleURL = web::test::HttpServer::MakeUrl(kSampleFileBasedURL);
  [ChromeEarlGrey loadURL:sampleURL];

  [ChromeEarlGrey loadURL:windowHistoryURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];

  // Tap the window.history.go(-2) button.  This will clear the current page's
  // |kOnLoadText|, so the subsequent check will only pass if another load
  // occurs.
  [ChromeEarlGrey tapWebViewElementWithID:kGoBackTwoID];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kOnLoadText)]
      assertWithMatcher:grey_notNil()];
}

#pragma mark window.history.[back/forward] operations

// Tests going back via history.back() then forward via forward button.
- (void)testHistoryBackNavigation {
  SetupBackAndForwardResponseProvider();

  // Navigate to a URL.
  const GURL firstURL = web::test::HttpServer::MakeUrl(kTestURL);
  [ChromeEarlGrey loadURL:firstURL];

  // Navigate to an HTML page with a back button.
  const GURL secondURL = web::test::HttpServer::MakeUrl(kBackURL);
  [ChromeEarlGrey loadURL:secondURL];

  // Tap the back button in the HTML and verify the first URL is loaded.
  TapWebViewElementWithId(kBackHTMLButtonLabel);
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          firstURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Tap the forward button in the toolbar and verify the second URL is loaded.
  [[EarlGrey selectElementWithMatcher:ForwardButton()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          secondURL.GetContent())]
      assertWithMatcher:grey_notNil()];
}

// Tests going back via back button then forward via history.forward().
- (void)testHistoryForwardNavigation {
  SetupBackAndForwardResponseProvider();

  // Navigate to an HTML page with a forward button.
  const GURL firstURL = web::test::HttpServer::MakeUrl(kForwardURL);
  [ChromeEarlGrey loadURL:firstURL];

  // Navigate to some other page.
  const GURL secondURL = web::test::HttpServer::MakeUrl(kTestURL);
  [ChromeEarlGrey loadURL:secondURL];

  // Tap the back button in the toolbar and verify the page with forward button
  // is loaded.
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:WebViewContainingText(kForwardHTMLSentinel)]
      assertWithMatcher:grey_notNil()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          firstURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Tap the forward button in the HTML and verify the second URL is loaded.
  TapWebViewElementWithId(kForwardHTMLButtonLabel);
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(kTestPageSentinel)]
      assertWithMatcher:grey_notNil()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          secondURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Verify that the forward button is not enabled.
  // TODO(crbug.com/638674): Evaluate if size class determination can move to
  // shared code.
  if (UIApplication.sharedApplication.keyWindow.traitCollection
          .horizontalSizeClass == UIUserInterfaceSizeClassCompact) {
    // In horizontally compact environments, the forward button is not visible.
    [[EarlGrey selectElementWithMatcher:ForwardButton()]
        assertWithMatcher:grey_nil()];
  } else {
    // In horizontally regular environments, the forward button is visible and
    // disabled.
    id<GREYMatcher> disabledForwardButton = grey_allOf(
        ForwardButton(),
        grey_accessibilityTrait(UIAccessibilityTraitNotEnabled), nil);
    [[EarlGrey selectElementWithMatcher:disabledForwardButton]
        assertWithMatcher:grey_notNil()];
  }
}

// Tests navigating forward via window.history.forward() to an error page.
- (void)testHistoryForwardToErrorPage {
// TODO(crbug.com/694662): This test relies on external URL because of the bug.
// Re-enable this test on device once the bug is fixed.
#if !TARGET_IPHONE_SIMULATOR
  EARL_GREY_TEST_DISABLED(@"Test disabled on device.");
#endif

  SetupBackAndForwardResponseProvider();

  // Go to page 1 with a button which calls window.history.forward().
  const GURL forwardURL = web::test::HttpServer::MakeUrl(kForwardURL);
  [ChromeEarlGrey loadURL:forwardURL];

  // Go to page 2: 'www.badurljkljkljklfloofy.com'. This page should display a
  // page not available error.
  const GURL badURL("http://www.badurljkljkljklfloofy.com");
  [ChromeEarlGrey loadURL:badURL];
  [ChromeEarlGrey waitForErrorPage];

  // Go back to page 1 by clicking back button.
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          forwardURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Go forward to page 2 by calling window.history.forward() and assert that
  // the error page is shown.
  TapWebViewElementWithId(kForwardHTMLButtonLabel);
  [ChromeEarlGrey waitForErrorPage];
}

#pragma mark window.location.hash operations

// Loads a URL and modifies window.location.hash, then goes back and forward
// and verifies the URLs and that hashchange event is fired.
- (void)testWindowLocationChangeHash {
  std::map<GURL, std::string> responses;
  const GURL page1URL = web::test::HttpServer::MakeUrl(kPage1URL);
  const GURL hashChangedWithHistoryURL =
      web::test::HttpServer::MakeUrl(kHashChangedWithHistoryURL);
  responses[page1URL] = kHashChangedHTML;
  responses[hashChangedWithHistoryURL] = kHashChangedHTML;
  web::test::SetUpSimpleHttpServer(responses);
  [ChromeEarlGrey loadURL:page1URL];

  // Click link to update location.hash and go to new URL (same page).
  chrome_test_util::TapWebViewElementWithId(kHashChangeWithHistoryLabel);

  // Navigate back to original URL. This should fire a hashchange event.
  std::string backHashChangeContent = "backHashChange";
  [self addHashChangeListenerWithContent:backHashChangeContent];
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          page1URL.GetContent())]
      assertWithMatcher:grey_notNil()];
  [[EarlGrey
      selectElementWithMatcher:WebViewContainingText(backHashChangeContent)]
      assertWithMatcher:grey_notNil()];

  // Navigate forward to the new URL. This should fire a hashchange event.
  std::string forwardHashChangeContent = "forwardHashChange";
  [self addHashChangeListenerWithContent:forwardHashChangeContent];
  [[EarlGrey selectElementWithMatcher:ForwardButton()]
      performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::OmniboxText(
                                   hashChangedWithHistoryURL.GetContent())]
      assertWithMatcher:grey_notNil()];
  [[EarlGrey
      selectElementWithMatcher:WebViewContainingText(forwardHashChangeContent)]
      assertWithMatcher:grey_notNil()];

  // Load a hash URL directly. This shouldn't fire a hashchange event.
  std::string hashChangeContent = "FAIL_loadUrlHashChange";
  [self addHashChangeListenerWithContent:hashChangeContent];
  [ChromeEarlGrey loadURL:hashChangedWithHistoryURL];
  [[EarlGrey selectElementWithMatcher:WebViewContainingText(hashChangeContent)]
      assertWithMatcher:grey_nil()];
}

// Loads a URL and replaces its location, then updates its location.hash
// and verifies that going back returns to the replaced entry.
- (void)testWindowLocationReplaceAndChangeHash {
  std::map<GURL, std::string> responses;
  const GURL page1URL = web::test::HttpServer::MakeUrl(kPage1URL);
  const GURL hashChangedWithoutHistoryURL =
      web::test::HttpServer::MakeUrl(kHashChangedWithoutHistoryURL);
  const GURL hashChangedWithHistoryURL =
      web::test::HttpServer::MakeUrl(kHashChangedWithHistoryURL);
  responses[page1URL] = kHashChangedHTML;
  web::test::SetUpSimpleHttpServer(responses);
  [ChromeEarlGrey loadURL:page1URL];

  // Tap link to replace the location value.
  TapWebViewElementWithId(kHashChangeWithoutHistoryLabel);
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::OmniboxText(
                                   hashChangedWithoutHistoryURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Tap link to update the location.hash with a new value.
  TapWebViewElementWithId(kHashChangeWithHistoryLabel);
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::OmniboxText(
                                   hashChangedWithHistoryURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigate back and verify that the URL that replaced window.location
  // has been reached.
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::OmniboxText(
                                   hashChangedWithoutHistoryURL.GetContent())]
      assertWithMatcher:grey_notNil()];
}

// Loads a URL and modifies window.location.hash twice, verifying that there is
// only one entry in the history by navigating back.
- (void)testWindowLocationChangeToSameHash {
  std::map<GURL, std::string> responses;
  const GURL page1URL = web::test::HttpServer::MakeUrl(kPage1URL);
  const GURL hashChangedWithHistoryURL =
      web::test::HttpServer::MakeUrl(kHashChangedWithHistoryURL);
  responses[page1URL] = kHashChangedHTML;
  web::test::SetUpSimpleHttpServer(responses);
  [ChromeEarlGrey loadURL:page1URL];

  // Tap link to update location.hash with a new value.
  TapWebViewElementWithId(kHashChangeWithHistoryLabel);
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::OmniboxText(
                                   hashChangedWithHistoryURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Tap link to update location.hash with the same value.
  TapWebViewElementWithId(kHashChangeWithHistoryLabel);

  // Tap back once to return to original URL.
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          page1URL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigate forward and verify the URL.
  [[EarlGrey selectElementWithMatcher:ForwardButton()]
      performAction:grey_tap()];
  [[EarlGrey
      selectElementWithMatcher:chrome_test_util::OmniboxText(
                                   hashChangedWithHistoryURL.GetContent())]
      assertWithMatcher:grey_notNil()];
}

#pragma mark Redirect operations

// Navigates to a page that immediately redirects to another page via JavaScript
// then verifies the browsing history.
- (void)testJavaScriptRedirect {
  std::map<GURL, std::string> responses;
  // A starting page.
  const GURL initialURL = web::test::HttpServer::MakeUrl("http://initialURL");
  // A page that redirects immediately via the window.open JavaScript method.
  const GURL originURL = web::test::HttpServer::MakeUrl(
      "http://scenarioJavaScriptRedirect_origin");
  const GURL destinationURL =
      web::test::HttpServer::MakeUrl("http://destination");
  responses[initialURL] = "<html><body>Initial page</body></html>";
  responses[originURL] =
      "<script>window.open('" + destinationURL.spec() + "', '_self');</script>";
  responses[destinationURL] = "scenarioJavaScriptRedirect destination";

  web::test::SetUpSimpleHttpServer(responses);
  [ChromeEarlGrey loadURL:initialURL];
  [ChromeEarlGrey loadURL:originURL];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          destinationURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigating back takes the user to the new tab page.
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          initialURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigating forward take the user to destination page.
  [[EarlGrey selectElementWithMatcher:ForwardButton()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          destinationURL.GetContent())]
      assertWithMatcher:grey_notNil()];
}

// Test to load a page that contains a redirect window, then does multiple back
// and forth navigations.
- (void)testRedirectWindow {
  std::unique_ptr<web::DataResponseProvider> provider(
      new RedirectResponseProvider());
  web::test::SetUpHttpServer(std::move(provider));
  [self verifyBackAndForwardAfterRedirect:"redirectWindow"];
}

// Test to load a page that contains a redirect refresh, then does multiple back
// and forth navigations.
- (void)testRedirectRefresh {
  std::unique_ptr<web::DataResponseProvider> provider(
      new RedirectResponseProvider());
  web::test::SetUpHttpServer(std::move(provider));
  [self verifyBackAndForwardAfterRedirect:"redirectRefresh"];
}

// Test to load a page that performs a 301 redirect, then does multiple back and
// forth navigations.
- (void)test301Redirect {
  std::unique_ptr<web::DataResponseProvider> provider(
      new RedirectResponseProvider());
  web::test::SetUpHttpServer(std::move(provider));
  [self verifyBackAndForwardAfterRedirect:"redirect301"];
}

#pragma mark Utility methods

- (void)addHashChangeListenerWithContent:(std::string)content {
  NSString* const script =
      [NSString stringWithFormat:
                    @"document.body.innerHTML = '%s';"
                     "window.addEventListener('hashchange', function(event) {"
                     "   document.body.innerHTML = '%s';"
                     "});",
                    kNoHashChangeText, content.c_str()];

  __unsafe_unretained NSError* error = nil;
  chrome_test_util::ExecuteJavaScript(script, &error);
}

- (void)verifyBackAndForwardAfterRedirect:(std::string)redirectLabel {
  const GURL indexURL(web::test::HttpServer::MakeUrl(kRedirectIndexURL));
  const GURL destinationURL(web::test::HttpServer::MakeUrl(kDestinationURL));
  const GURL lastURL(web::test::HttpServer::MakeUrl(kLastURL));

  // Load index, tap on redirect link, and assert that the page is redirected
  // to the proper destination.
  [ChromeEarlGrey loadURL:indexURL];
  TapWebViewElementWithId(redirectLabel);
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          destinationURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigate to a new URL, navigate back and assert that the resulting page is
  // the proper destination.
  [ChromeEarlGrey loadURL:lastURL];
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          destinationURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigate back and assert that the resulting page is the initial index.
  [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          indexURL.GetContent())]
      assertWithMatcher:grey_notNil()];

  // Navigate forward and assert the the resulting page is the proper
  // destination.
  [[EarlGrey selectElementWithMatcher:ForwardButton()]
      performAction:grey_tap()];
  [[EarlGrey selectElementWithMatcher:chrome_test_util::OmniboxText(
                                          destinationURL.GetContent())]
      assertWithMatcher:grey_notNil()];
}

@end
