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

#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_timeouts.h"
#include "build/build_config.h"
#include "content/browser/renderer_host/frame_tree_node.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/back_forward_cache_util.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/hit_test_region_observer.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/controllable_http_response.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "third_party/blink/public/common/switches.h"
#include "url/gurl.h"

// RunUntilInputProcessed will force a Blink lifecycle which is needed
// because did_scroll is set in an onscroll handler which may be delayed from
// the scroll by a frame.
#define EXPECT_DID_SCROLL(scrolled)                        \
  RunUntilInputProcessed(GetWidgetHost());                 \
  EXPECT_EQ(scrolled, EvalJs(main_contents, "did_scroll;", \
                             EXECUTE_SCRIPT_NO_USER_GESTURE));

#define ASSERT_DID_SCROLL(scrolled)                        \
  RunUntilInputProcessed(GetWidgetHost());                 \
  ASSERT_EQ(scrolled, EvalJs(main_contents, "did_scroll;", \
                             EXECUTE_SCRIPT_NO_USER_GESTURE));

namespace content {

class TextFragmentAnchorBrowserTest : public ContentBrowserTest {
 public:
  TextFragmentAnchorBrowserTest() {
    feature_list_.InitAndEnableFeature(features::kDocumentPolicy);
  }

 protected:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    ContentBrowserTest::SetUpCommandLine(command_line);
    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
                                    "TextFragmentIdentifiers");
    // Slow bots are flaky due to slower loading interacting with
    // deferred commits.
    command_line->AppendSwitch(blink::switches::kAllowPreCommitInput);
  }

  // Simulates a click on the middle of the DOM element with the given |id|.
  void ClickElementWithId(WebContents* web_contents, const std::string& id) {
    // Get the center coordinates of the DOM element.
    const int x = EvalJs(web_contents,
                         JsReplace("const bounds = "
                                   "document.getElementById($1)."
                                   "getBoundingClientRect();"
                                   "Math.floor(bounds.left + bounds.width / 2)",
                                   id))
                      .ExtractInt();
    const int y = EvalJs(web_contents,
                         JsReplace("const bounds = "
                                   "document.getElementById($1)."
                                   "getBoundingClientRect();"
                                   "Math.floor(bounds.top + bounds.height / 2)",
                                   id))
                      .ExtractInt();

    SimulateMouseClickAt(web_contents, 0, blink::WebMouseEvent::Button::kLeft,
                         gfx::Point(x, y));
    RunUntilInputProcessed(GetWidgetHost());
  }

  void WaitForPageLoad(WebContents* contents) {
    EXPECT_TRUE(WaitForLoadStop(contents));
    EXPECT_TRUE(WaitForRenderFrameReady(contents->GetPrimaryMainFrame()));
  }

  RenderWidgetHostImpl* GetWidgetHost() {
    return RenderWidgetHostImpl::From(shell()
                                          ->web_contents()
                                          ->GetPrimaryMainFrame()
                                          ->GetRenderViewHost()
                                          ->GetWidget());
  }

  base::test::ScopedFeatureList feature_list_;
};

IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, EnabledOnUserNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/target_text_link.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContents* main_contents = shell()->web_contents();
  TestNavigationObserver observer(main_contents);

  // We need to wait until hit test data is available.
  HitTestRegionObserver hittest_observer(GetWidgetHost()->GetFrameSinkId());
  hittest_observer.WaitForHitTestData();

  ClickElementWithId(main_contents, "link");
  observer.Wait();
  EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());

  // Observe the frame after page is loaded. Note that we need to initialize
  // this after navigation because the main RenderFrameHost might have changed
  // from before the navigation started.
  RenderFrameSubmissionObserver frame_observer(main_contents);
  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);

  EXPECT_DID_SCROLL(true);
}

IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       EnabledOnBrowserNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));
  WebContents* main_contents = shell()->web_contents();
  RenderFrameSubmissionObserver frame_observer(main_contents);

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);
}

IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       EnabledOnUserGestureScriptNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/empty.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContents* main_contents = shell()->web_contents();
  TestNavigationObserver observer(main_contents);

  EXPECT_TRUE(
      ExecJs(main_contents, "location = '" + target_text_url.spec() + "';"));
  observer.Wait();
  EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());
  // Observe the frame after page is loaded. Note that we need to initialize
  // this after navigation because the main RenderFrameHost might have changed
  // from before the navigation started.
  RenderFrameSubmissionObserver frame_observer(main_contents);

  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);
}

// Ensures that a simulated redirect service works correctly. That is, only the
// initial NavigateToURL has a user gesture but this should be propagated
// through the window.location navigation which doesn't have a user gesture.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       UserGesturePassedThroughRedirect) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/empty.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));

  // This navigtion is simulated as if it came from the omnibox, hence it is
  // considered to be user initiated.
  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContents* main_contents = shell()->web_contents();
  TestNavigationObserver observer(main_contents);

  // This navigation occurs without a user gesture, simulating a client
  // redirect. However, because the above navigation didn't activate a text
  // fragment, permission should be propagated to this navigation.
  EXPECT_TRUE(ExecJs(main_contents,
                     "location = '" + target_text_url.spec() + "';",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  observer.Wait();
  EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());

  WaitForPageLoad(main_contents);
  RenderFrameSubmissionObserver frame_observer(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);
}

// Ensures that a text fragment activation consumes a user gesture so that
// future navigations cannot activate a text fragment without a new user
// gesture.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, UserGestureConsumed) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL empty_page_url(embedded_test_server()->GetURL("/empty.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));

  WebContents* main_contents = shell()->web_contents();

  // This navigtion is simulated as if it came from the omnibox, hence it is
  // considered to be user initiated.
  {
    TestNavigationObserver observer(main_contents);
    ASSERT_TRUE(NavigateToURL(shell(), target_text_url));
    observer.Wait();
    ASSERT_EQ(target_text_url, main_contents->GetLastCommittedURL());

    // Ensure the page did scroll to the text fragment. Note, we can't use
    // WaitForPageLoad since the WaitForRenderFrameReady executes javascript
    // with a user gesture.
    WaitForLoadStop(main_contents);
    RenderFrameSubmissionObserver frame_observer(main_contents);
    frame_observer.WaitForScrollOffsetAtTop(
        /*expected_scroll_offset_at_top=*/false);
    ASSERT_DID_SCROLL(true);
  }

  // We now want to try a second text fragment navigation. Same document
  // navigations are blocked so we'll navigate away first.
  {
    TestNavigationObserver observer(main_contents);
    ASSERT_TRUE(ExecJs(main_contents,
                       "location = '" + empty_page_url.spec() + "';",
                       EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    ASSERT_EQ(empty_page_url, main_contents->GetLastCommittedURL());
    WaitForLoadStop(main_contents);
  }

  // Now try another text fragment navigation. Since we haven't had a user
  // gesture since the last one, it should be blocked.
  {
    TestNavigationObserver observer(main_contents);
    ASSERT_TRUE(ExecJs(main_contents,
                       "location = '" + target_text_url.spec() + "';",
                       EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    ASSERT_EQ(target_text_url, main_contents->GetLastCommittedURL());
    WaitForLoadStop(main_contents);

    // Wait a short amount of time to ensure the page does not scroll.
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
    EXPECT_DID_SCROLL(false);
  }
}

IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       DisabledOnScriptHistoryNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL target_text_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));
  GURL url(embedded_test_server()->GetURL("/empty.html"));

  EXPECT_TRUE(NavigateToURL(shell(), target_text_url));

  WebContents* main_contents = shell()->web_contents();
  // The test assumes the previous page gets deleted after navigation and will
  // be recreated with did_scroll == false. Disable back/forward cache to ensure
  // that it doesn't get preserved in the cache.
  DisableBackForwardCacheForTesting(
      main_contents, BackForwardCacheImpl::TEST_REQUIRES_NO_CACHING);

  {
    // The RenderFrameSubmissionObserver destructor expects the RenderFrameHost
    // stays the same until it gets destructed, so we need to scope this to make
    // sure it gets destructed before the next navigation.
    RenderFrameSubmissionObserver frame_observer(main_contents);
    frame_observer.WaitForScrollOffsetAtTop(false);

    // Scroll the page back to top so scroll restoration does not scroll the
    // target back into view.
    EXPECT_TRUE(ExecJs(main_contents, "window.scrollTo(0, 0)"));
    frame_observer.WaitForScrollOffsetAtTop(true);
  }

  EXPECT_TRUE(NavigateToURL(shell(), url));

  TestNavigationObserver observer(main_contents);
  EXPECT_TRUE(
      ExecJs(main_contents, "history.back()", EXECUTE_SCRIPT_NO_USER_GESTURE));
  observer.Wait();
  EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());

  WaitForPageLoad(main_contents);

  // Wait a short amount of time to ensure the page does not scroll.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
  run_loop.Run();

  // Note: we use a scroll handler in the page to check whether any scrolls
  // happened at all, rather than checking the current scroll offset. This is
  // to ensure that if the offset is reset back to the top for other reasons
  // (e.g. history restoration) we still fail this test. See
  // https://crbug.com/1042986 for why this matters.
  EXPECT_DID_SCROLL(false);
}

// Ensure a same-document navigation from browser UI scrolls to the text
// fragment.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       SameDocumentBrowserNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));
  WebContents* main_contents = shell()->web_contents();
  RenderFrameSubmissionObserver frame_observer(main_contents);

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(false);

  // Scroll the page back to top. Make sure we reset the |did_scroll| variable
  // we'll use below to ensure the same-document navigation invokes the text
  // fragment.
  EXPECT_TRUE(ExecJs(main_contents, "window.scrollTo(0, 0)"));
  frame_observer.WaitForScrollOffsetAtTop(true);
  RunUntilInputProcessed(GetWidgetHost());
  EXPECT_TRUE(ExecJs(main_contents, "did_scroll = false;"));

  // Perform a same-document browser initiated navigation
  GURL same_doc_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=some"));
  EXPECT_TRUE(NavigateToURL(shell(), same_doc_url));

  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);
}

IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       SameDocumentBrowserNavigationOnScriptNavigatedDocument) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContents* main_contents = shell()->web_contents();
  RenderFrameSubmissionObserver frame_observer(main_contents);
  // The test assumes the RenderWidgetHost stays the same after navigation,
  // which won't happen if same-site back/forward-cache is enabled. Disable it
  // so that we will keep RenderWidgetHost even after navigation.
  DisableBackForwardCacheForTesting(
      main_contents, BackForwardCacheImpl::TEST_ASSUMES_NO_RENDER_FRAME_CHANGE);

  // Load an initial page
  {
    GURL initial_url(embedded_test_server()->GetURL("/empty.html"));
    EXPECT_TRUE(NavigateToURL(shell(), initial_url));
    WaitForPageLoad(main_contents);
  }

  // Now navigate to the target document without a user gesture. We provide a
  // text-fragment here and expect it to be invoked because the initial load
  // was browser-initiated so its transferred to this load via the text fragment
  // token. This navigation ensures the token is consumed.
  {
    GURL target_url(embedded_test_server()->GetURL(
        "/scrollable_page_with_content.html#:~:text=text"));
    TestNavigationObserver observer(main_contents);
    EXPECT_TRUE(ExecJs(main_contents, "location = '" + target_url.spec() + "';",
                       EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    EXPECT_EQ(target_url, main_contents->GetLastCommittedURL());
    frame_observer.WaitForScrollOffsetAtTop(false);
    EXPECT_DID_SCROLL(true);
  }

  // Scroll the page back to top. Make sure we reset the |did_scroll| variable
  // we'll use below to ensure the same-document navigation invokes the text
  // fragment.
  {
    EXPECT_TRUE(ExecJs(main_contents, "window.scrollTo(0, 0)"));
    frame_observer.WaitForScrollOffsetAtTop(true);
    RunUntilInputProcessed(GetWidgetHost());
    EXPECT_TRUE(ExecJs(main_contents, "did_scroll = false;"));
  }

  // Perform a same-document browser initiated navigation. This should cause a
  // scroll because the navigation is browser-initiated, despite the fact that
  // the document was loaded without a user gesture.
  {
    GURL same_doc_url(embedded_test_server()->GetURL(
        "/scrollable_page_with_content.html#:~:text=some"));
    EXPECT_TRUE(NavigateToURL(shell(), same_doc_url));

    WaitForPageLoad(main_contents);

    frame_observer.WaitForScrollOffsetAtTop(
        /*expected_scroll_offset_at_top=*/false);
    EXPECT_DID_SCROLL(true);
  }
}

// Ensure a text fragment token isn't generated via history.back() navigation.
// This is a tricky case because all history navigations (including script
// initiated) appear to the renderer as "browser-initiated".
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       HistoryDoesntGenerateToken) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContents* main_contents = shell()->web_contents();
  GURL url(embedded_test_server()->GetURL(
      "a.com", "/scrollable_page_with_content.html#:~:text=text"));

  {
    // RenderFrameSubmissionObserver must not outlive the RenderWidgetHostImpl
    // so ensure it's destructed before we navigate to a new page.
    RenderFrameSubmissionObserver frame_observer(main_contents);

    // Load a page with a text-fragment
    EXPECT_TRUE(NavigateToURL(shell(), url));
    WaitForPageLoad(main_contents);
    frame_observer.WaitForScrollOffsetAtTop(false);

    // Scroll the page back to top. Make sure we reset the |did_scroll| variable
    // we'll use below to ensure the same-document navigation invokes the text
    // fragment.
    EXPECT_TRUE(ExecJs(main_contents, "window.scrollTo(0, 0)",
                       EXECUTE_SCRIPT_NO_USER_GESTURE));
    frame_observer.WaitForScrollOffsetAtTop(true);
    EXPECT_TRUE(ExecJs(main_contents, "did_scroll = false;",
                       EXECUTE_SCRIPT_NO_USER_GESTURE));

    // Perform a scripted same-document navigation to a non-existent fragment to
    // generate a history entry.
    {
      GURL temp_url(embedded_test_server()->GetURL(
          "a.com", "/scrollable_page_with_content.html#doesntexist"));
      TestNavigationObserver observer(main_contents);
      EXPECT_TRUE(ExecJs(main_contents, JsReplace("location = $1;", temp_url),
                         EXECUTE_SCRIPT_NO_USER_GESTURE));
      observer.Wait();
      EXPECT_EQ(temp_url, main_contents->GetLastCommittedURL());
    }

    // Navigate back using history.back().
    {
      TestNavigationObserver observer(main_contents);
      EXPECT_TRUE(ExecJs(main_contents, "history.back();",
                         EXECUTE_SCRIPT_NO_USER_GESTURE));
      observer.Wait();
      EXPECT_EQ(url, main_contents->GetLastCommittedURL());

      // The page should be restored to where we left off at the top.
      RunUntilInputProcessed(GetWidgetHost());
      ASSERT_EQ(EvalJs(main_contents, "window.scrollY;",
                       EXECUTE_SCRIPT_NO_USER_GESTURE)
                    .ExtractInt(),
                0);
      ASSERT_DID_SCROLL(false);
    }
  }

  // Now try to navigate to a new page with a text-fragment. This should be
  // blocked because the token was consumed in the initial load at the top and
  // a new one must not have been generated by the same document navigations
  // above.
  {
    GURL new_url(embedded_test_server()->GetURL(
        "b.com", "/scrollable_page_with_content.html#:~:text=Some"));
    TestNavigationObserver observer(main_contents);
    EXPECT_TRUE(ExecJs(main_contents, "location = '" + new_url.spec() + "';",
                       EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    EXPECT_EQ(new_url, main_contents->GetLastCommittedURL());
    base::RunLoop run_loop;
    base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
        FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
    run_loop.Run();
    EXPECT_DID_SCROLL(false);
  }
}

// Ensure same-document navigation to a text-fragment works when initiated from
// the document itself.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       SameDocumentScriptNavigation) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(
      embedded_test_server()->GetURL("/scrollable_page_with_content.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=some"));

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContents* main_contents = shell()->web_contents();
  TestNavigationObserver observer(main_contents);
  // User gesture not required since the script is running in the same origin
  // as the page.
  EXPECT_TRUE(ExecJs(main_contents,
                     "location = '" + target_text_url.spec() + "';",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  observer.Wait();
  EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());

  WaitForPageLoad(main_contents);
  RenderFrameSubmissionObserver frame_observer(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);
}

// Ensure same-document navigation to a text-fragment works when initiated from
// the same origin.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       SameDocumentScriptNavigationSameOrigin) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL(
      "a.com", "/scrollable_page_with_content.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "a.com", "/scrollable_page_with_content.html#:~:text=some"));
  GURL cross_origin_inner_url(
      embedded_test_server()->GetURL("a.com", "/hello.html"));

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContentsImpl* main_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  FrameTreeNode* root = main_contents->GetPrimaryFrameTree().root();

  // Insert a same-origin iframe from which we'll execute script.
  {
    const auto script = JsReplace(
        R"JS(
            let f = document.createElement("iframe");
            f.src=$1;
            document.body.appendChild(f);
          )JS",
        cross_origin_inner_url);

    TestNavigationObserver observer(main_contents);
    EXPECT_TRUE(ExecJs(main_contents, script, EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    ASSERT_EQ(1u, root->child_count());
  }

  // Try navigating the top frame to a same-document text fragment from inside
  // the iframe. This should be allowed, even without user-gesture, since it's
  // same-origin; script is able to see all its content anyway.
  {
    TestNavigationObserver observer(main_contents);
    RenderFrameHostImpl* child_rfh = root->child_at(0)->current_frame_host();
    EXPECT_TRUE(ExecJs(child_rfh,
                       JsReplace("window.top.location = $1;", target_text_url),
                       EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());

    RenderFrameSubmissionObserver frame_observer(main_contents);
    WaitForPageLoad(main_contents);
    frame_observer.WaitForScrollOffsetAtTop(
        /*expected_scroll_offset_at_top=*/false);
    EXPECT_DID_SCROLL(true);
  }
}

// Ensure same-document navigation to a text-fragment is blocked when initiated
// from a different origin.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       SameDocumentScriptNavigationCrossOrigin) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL(
      "a.com", "/scrollable_page_with_content.html"));
  GURL target_text_url(embedded_test_server()->GetURL(
      "a.com", "/scrollable_page_with_content.html#:~:text=some"));
  GURL cross_origin_inner_url(
      embedded_test_server()->GetURL("b.com", "/hello.html"));

  EXPECT_TRUE(NavigateToURL(shell(), url));

  WebContentsImpl* main_contents =
      static_cast<WebContentsImpl*>(shell()->web_contents());
  FrameTreeNode* root = main_contents->GetPrimaryFrameTree().root();

  // Insert a cross-origin iframe from which we'll execute script.
  {
    const auto script = JsReplace(
        R"JS(
            let f = document.createElement("iframe");
            f.src=$1;
            document.body.appendChild(f);
          )JS",
        cross_origin_inner_url);

    TestNavigationObserver observer(main_contents);
    EXPECT_TRUE(ExecJs(main_contents, script, EXECUTE_SCRIPT_NO_USER_GESTURE));
    observer.Wait();
    ASSERT_EQ(1u, root->child_count());
  }

  // Try navigating the top frame to a same-document text fragment from inside
  // the iframe. This should be blocked as its cross-origin. Note, the script
  // executes with a user gesture but this is still blocked. Same-document
  // navigations are allowed only when initiated from same-origin or
  // browser-UI.
  {
    TestNavigationObserver observer(main_contents);
    RenderFrameHostImpl* child_rfh = root->child_at(0)->current_frame_host();
    EXPECT_TRUE(ExecJs(
        child_rfh, JsReplace("window.top.location = $1;", target_text_url)));
    observer.Wait();
    EXPECT_EQ(target_text_url, main_contents->GetLastCommittedURL());

    WaitForPageLoad(main_contents);
    EXPECT_DID_SCROLL(false);
  }
}

// Test that when ForceLoadAtTop document policy is explicitly turned off,
// scrolling to a text fragment is allowed.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, EnabledByDocumentPolicy) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/target.html");

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/target.html#:~:text=text"));
  WebContents* main_contents = shell()->web_contents();
  RenderFrameSubmissionObserver frame_observer(main_contents);

  // Load the target document
  TestNavigationManager navigation_manager(main_contents, url);
  shell()->LoadURL(url);

  // Start navigation
  EXPECT_TRUE(navigation_manager.WaitForRequestStart());
  navigation_manager.ResumeNavigation();

  // Send Document-Policy header
  response.WaitForRequest();
  response.Send(
      "HTTP/1.1 200 OK\r\n"
      "Content-Type: text/html; charset=utf-8\r\n"
      "Document-Policy: force-load-at-top=?0\r\n"
      "\r\n"
      "<script>"
      "  let did_scroll = false;"
      "  window.addEventListener('scroll', () => {"
      "    did_scroll = true;"
      "  });"
      "</script>"
      "<p style='position: absolute; top: 10000px;'>Some text</p>");
  response.Done();

  EXPECT_TRUE(navigation_manager.WaitForResponse());
  navigation_manager.ResumeNavigation();
  navigation_manager.WaitForNavigationFinished();

  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);
}

// Test that the ForceLoadAtTop document policy disables scrolling to a text
// fragment.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       DisabledByDocumentPolicy) {
  net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                      "/target.html");

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(embedded_test_server()->GetURL("/target.html#:~:text=text"));
  WebContents* main_contents = shell()->web_contents();

  // Load the target document
  TestNavigationManager navigation_manager(main_contents, url);
  shell()->LoadURL(url);

  // Start navigation
  EXPECT_TRUE(navigation_manager.WaitForRequestStart());
  navigation_manager.ResumeNavigation();

  // Send Document-Policy header
  response.WaitForRequest();
  response.Send(
      "HTTP/1.1 200 OK\r\n"
      "Content-Type: text/html; charset=utf-8\r\n"
      "Document-Policy: force-load-at-top\r\n"
      "\r\n"
      "<script>"
      "  let did_scroll = false;"
      "  window.addEventListener('scroll', () => {"
      "    did_scroll = true;"
      "  });"
      "</script>"
      "<p style='position: absolute; top: 10000px;'>Some text</p>");
  response.Done();

  EXPECT_TRUE(navigation_manager.WaitForResponse());
  navigation_manager.ResumeNavigation();
  navigation_manager.WaitForNavigationFinished();

  WaitForPageLoad(main_contents);
  // Wait a short amount of time to ensure the page does not scroll.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
  run_loop.Run();
  EXPECT_DID_SCROLL(false);
}

// Test that Tab key press puts focus from the start of the text directive that
// was scrolled into view.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest, TabFocus) {
  ASSERT_TRUE(embedded_test_server()->Start());
  GURL url(
      embedded_test_server()->GetURL("/scrollable_page_with_anchor.html#:~:"
                                     "text=nonexistent&text=text&text=more"));
  WebContents* main_contents = shell()->web_contents();
  RenderFrameSubmissionObserver frame_observer(main_contents);
  EXPECT_TRUE(NavigateToURL(shell(), url));
  WaitForPageLoad(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);

  DOMMessageQueue msg_queue(main_contents);
  SimulateKeyPress(main_contents, ui::DomKey::TAB, ui::DomCode::TAB,
                   ui::VKEY_TAB, false, false, false, false);

  // Wait for focus to happen.
  std::string message;
  EXPECT_TRUE(msg_queue.WaitForMessage(&message));
  EXPECT_EQ("\"FocusDone2\"", message);
}

class ForceLoadAtTopBrowserTest : public TextFragmentAnchorBrowserTest {
 protected:
  // Loads the given path as predetermined HTML response with a
  // |Document-Policy: force-load-at-top| header and waits for the navigation
  // to finish.
  void LoadScrollablePageWithContent(const std::string& path) {
    std::size_t hash_pos = path.find("#");
    std::string path_without_fragment = path;
    if (hash_pos != std::string::npos) {
      path_without_fragment = path.substr(0, hash_pos);
    }
    net::test_server::ControllableHttpResponse response(embedded_test_server(),
                                                        path_without_fragment);

    ASSERT_TRUE(embedded_test_server()->Start());
    GURL url(embedded_test_server()->GetURL(path));
    RenderFrameSubmissionObserver frame_observer(shell()->web_contents());

    // Load the target document.
    TestNavigationManager navigation_manager(shell()->web_contents(), url);
    shell()->LoadURL(url);

    // Start navigation
    ASSERT_TRUE(navigation_manager.WaitForRequestStart());
    navigation_manager.ResumeNavigation();

    // Send Document-Policy header
    response.WaitForRequest();
    std::string response_string =
        "HTTP/1.1 200 OK\r\n"
        "Content-Type: text/html; charset=utf-8\r\n"
        "Document-Policy: force-load-at-top\r\n"
        "\r\n"
        R"HTML(
          <html>
            <head>
              <meta name="viewport" content="width=device-width">
              <script>
                let did_scroll = false;
                window.addEventListener('scroll', () => {
                  did_scroll = true;
                });
              </script>
              <style>
                p {
                  position: absolute;
                  top: 10000px;
                }
              </style>
            </head>
            <body>
              <a id="link" href="#text">Go Down</a>
              <p id="text">Some text</p>
            </body>
          </html>
        )HTML";
    response.Send(response_string);
    response.Done();

    ASSERT_TRUE(navigation_manager.WaitForResponse());
    navigation_manager.ResumeNavigation();
    navigation_manager.WaitForNavigationFinished();

    WaitForPageLoad(shell()->web_contents());
  }
};

// Test that scroll restoration is disabled with ForceLoadAtTop
IN_PROC_BROWSER_TEST_F(ForceLoadAtTopBrowserTest, ScrollRestorationDisabled) {
  ASSERT_NO_FATAL_FAILURE(LoadScrollablePageWithContent("/index.html"));

  WebContents* main_contents = shell()->web_contents();
  // This test expects the document is freshly loaded on the back navigation
  // so that the document policy to force-load-at-top will run. This will not
  // happen if the document is back-forward cached, so we need to disable it.
  DisableBackForwardCacheForTesting(main_contents,
                                    BackForwardCache::TEST_REQUIRES_NO_CACHING);

  // Scroll down the page a bit
  EXPECT_TRUE(ExecJs(main_contents, "window.scrollTo(0, 1000)"));

  // Navigate away
  EXPECT_TRUE(ExecJs(main_contents, "window.location = 'about:blank'"));
  EXPECT_TRUE(WaitForLoadStop(main_contents));

  // Navigate back
  EXPECT_TRUE(ExecJs(main_contents, "history.back()"));
  EXPECT_TRUE(WaitForLoadStop(main_contents));

  // Wait a short amount of time to ensure the page does not scroll.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
  run_loop.Run();
  RunUntilInputProcessed(GetWidgetHost());
  EXPECT_EQ(EvalJs(main_contents, "window.scrollY;").ExtractInt(), 0);
}

// Test that element fragment anchor scrolling is disabled with ForceLoadAtTop
IN_PROC_BROWSER_TEST_F(ForceLoadAtTopBrowserTest, FragmentAnchorDisabled) {
  ASSERT_NO_FATAL_FAILURE(LoadScrollablePageWithContent("/index.html#text"));
  WebContents* main_contents = shell()->web_contents();

  // Wait a short amount of time to ensure the page does not scroll.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
  run_loop.Run();
  RunUntilInputProcessed(GetWidgetHost());
  EXPECT_DID_SCROLL(false);
}

// Ensure the ForceLoadAtTop policy doesn't prevent same-document fragment
// navigations.
IN_PROC_BROWSER_TEST_F(ForceLoadAtTopBrowserTest, SameDocumentNavigation) {
  ASSERT_NO_FATAL_FAILURE(LoadScrollablePageWithContent("/index.html"));
  WebContents* main_contents = shell()->web_contents();

  ASSERT_DID_SCROLL(false);

  // Click on a link with a fragment id. Ensure we scroll to the targeted
  // element.
  ClickElementWithId(main_contents, "link");

  EXPECT_DID_SCROLL(true);
}

// Ensure the ForceLoadAtTop policy prevents scrolling to a navigated text
// directive.
IN_PROC_BROWSER_TEST_F(ForceLoadAtTopBrowserTest, TextFragmentAnchorDisabled) {
  ASSERT_NO_FATAL_FAILURE(
      LoadScrollablePageWithContent("/index.html#:~:text=text"));
  WebContents* main_contents = shell()->web_contents();

  // Wait a short amount of time to ensure the page does not scroll.
  base::RunLoop run_loop;
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE, run_loop.QuitClosure(), TestTimeouts::tiny_timeout());
  run_loop.Run();
  RunUntilInputProcessed(GetWidgetHost());
  EXPECT_DID_SCROLL(false);
}

// Tests that text fragments opened after a client redirect are considered as
// coming from an unknown source, even if the redirect is through a known
// search engine URL.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       LinkOpenSourceMetrics_GoogleClientRedirect) {
  base::HistogramTester histogram_tester;

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL first_url(embedded_test_server()->GetURL("google.com", "/empty.html"));
  GURL final_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));

  // This navigtion is simulated as if it came from the omnibox, hence it is
  // considered to be user initiated.
  EXPECT_TRUE(NavigateToURL(shell(), first_url));

  WebContents* main_contents = shell()->web_contents();
  TestNavigationObserver observer(main_contents);
  EXPECT_EQ(first_url, main_contents->GetLastCommittedURL());

  // This navigation occurs without a user gesture, simulating a client
  // redirect. However, because the above navigation didn't activate a text
  // fragment, permission should be propagated to this navigation.
  EXPECT_TRUE(ExecJs(main_contents,
                     "location.replace('" + final_url.spec() + "');",
                     EXECUTE_SCRIPT_NO_USER_GESTURE));
  observer.Wait();
  EXPECT_EQ(final_url, main_contents->GetLastCommittedURL());

  WaitForPageLoad(main_contents);
  RenderFrameSubmissionObserver frame_observer(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);

  // Bucket 0 is unknown source.
  content::FetchHistogramsFromChildProcesses();
  histogram_tester.ExpectUniqueSample("TextFragmentAnchor.LinkOpenSource", 0,
                                      1);
}

// Tests that text fragments opened after a server redirect are considered as
// coming from an unknown source, even if the redirect is through a known
// search engine URL.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       LinkOpenSourceMetrics_GoogleServerRedirect) {
  base::HistogramTester histogram_tester;

  ASSERT_TRUE(embedded_test_server()->Start());
  GURL initial_url(embedded_test_server()->GetURL("/simple_page.html"));
  GURL redirected_url(embedded_test_server()->GetURL(
      "/scrollable_page_with_content.html#:~:text=text"));
  GURL redirector_url(embedded_test_server()->GetURL(
      "google.com", "/server-redirect?" + redirected_url.spec()));

  // This navigtion is simulated as if it came from the omnibox, hence it is
  // considered to be user initiated.
  EXPECT_TRUE(NavigateToURL(shell(), initial_url));

  WebContents* main_contents = shell()->web_contents();
  TestNavigationObserver observer(main_contents);
  EXPECT_EQ(initial_url, main_contents->GetLastCommittedURL());

  // Simulate a user clicking on a link to the redirector url.
  EXPECT_TRUE(ExecJs(main_contents,
                     "var hyperLinkTag = document.createElement('a'); "
                     "hyperLinkTag.setAttribute('id','fragmentLink'); "
                     "hyperLinkTag.setAttribute('href','" +
                         redirector_url.spec() +
                         "'); document.body.appendChild(hyperLinkTag); "
                         "hyperLinkTag.appendChild(document.createTextNode('"
                         "Text Fragment Link.'));"
                         "document.getElementById('fragmentLink').click();"));

  observer.Wait();
  EXPECT_EQ(redirected_url, main_contents->GetLastCommittedURL());

  RenderFrameSubmissionObserver frame_observer(main_contents);
  frame_observer.WaitForScrollOffsetAtTop(
      /*expected_scroll_offset_at_top=*/false);
  EXPECT_DID_SCROLL(true);

  // Bucket 0 is unknown source.
  content::FetchHistogramsFromChildProcesses();
  histogram_tester.ExpectUniqueSample("TextFragmentAnchor.LinkOpenSource", 0,
                                      1);
}

}  // namespace content
