// 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/task/single_thread_task_runner.h"
#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 {
 protected:
  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
  }

  void SetUpCommandLine(base::CommandLine* command_line) override {
    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));
  }

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

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

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::SingleThreadTaskRunner::GetCurrentDefault()->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::SingleThreadTaskRunner::GetCurrentDefault()->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);
}

// crbug.com/1470712: Flaky on CrOS Debug
#if BUILDFLAG(IS_CHROMEOS) && !defined(NDEBUG)
#define MAYBE_SameDocumentBrowserNavigation \
  DISABLED_SameDocumentBrowserNavigation
#else
#define MAYBE_SameDocumentBrowserNavigation SameDocumentBrowserNavigation
#endif
// Ensure a same-document navigation from browser UI scrolls to the text
// fragment.
IN_PROC_BROWSER_TEST_F(TextFragmentAnchorBrowserTest,
                       MAYBE_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);
}

// crbug.com/1470712: Flaky on CrOS Debug
#if BUILDFLAG(IS_CHROMEOS) && !defined(NDEBUG)
#define MAYBE_SameDocumentBrowserNavigationOnScriptNavigatedDocument \
  DISABLED_SameDocumentBrowserNavigationOnScriptNavigatedDocument
#else
#define MAYBE_SameDocumentBrowserNavigationOnScriptNavigatedDocument \
  SameDocumentBrowserNavigationOnScriptNavigatedDocument
#endif
IN_PROC_BROWSER_TEST_F(
    TextFragmentAnchorBrowserTest,
    MAYBE_SameDocumentBrowserNavigationOnScriptNavigatedDocument) {
  ASSERT_TRUE(embedded_test_server()->Start());
  WebContents* main_contents = shell()->web_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();

    RenderFrameSubmissionObserver frame_observer(main_contents);
    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.
  {
    RenderFrameSubmissionObserver frame_observer(main_contents);
    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));

    RenderFrameSubmissionObserver frame_observer(main_contents);
    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::SingleThreadTaskRunner::GetCurrentDefault()->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();
  ASSERT_TRUE(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();
  ASSERT_TRUE(navigation_manager.WaitForNavigationFinished());

  WaitForPageLoad(main_contents);
  // Wait a short amount of time to ensure the page does not scroll.
  base::RunLoop run_loop;
  base::SingleThreadTaskRunner::GetCurrentDefault()->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();
    ASSERT_TRUE(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::SingleThreadTaskRunner::GetCurrentDefault()->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::SingleThreadTaskRunner::GetCurrentDefault()->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");
  RunUntilInputProcessed(GetWidgetHost());

  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::SingleThreadTaskRunner::GetCurrentDefault()->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
