1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chained_back_navigation_tracker.h"
#include "base/test/bind.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/navigation_simulator.h"
#include "net/dns/mock_host_resolver.h"
class ChainedBackNavigationTrackerBrowserTest : public InProcessBrowserTest {
public:
ChainedBackNavigationTrackerBrowserTest() = default;
ChainedBackNavigationTrackerBrowserTest(
const ChainedBackNavigationTrackerBrowserTest&) = delete;
ChainedBackNavigationTrackerBrowserTest& operator=(
const ChainedBackNavigationTrackerBrowserTest&) = delete;
~ChainedBackNavigationTrackerBrowserTest() override = default;
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
}
protected:
content::WebContents* web_contents() const {
return browser()->tab_strip_model()->GetActiveWebContents();
}
const uint32_t min_navigation_cnt_ =
ChainedBackNavigationTracker::kMinimumChainedBackNavigationLength;
const int64_t max_navigation_interval_ = ChainedBackNavigationTracker::
kMaxChainedBackNavigationIntervalInMilliseconds;
};
IN_PROC_BROWSER_TEST_F(ChainedBackNavigationTrackerBrowserTest,
SubframeBackNavigationIsCountedAsChained) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url_a1 = embedded_test_server()->GetURL("a1.com", "/title1.html");
GURL url_a2 = embedded_test_server()->GetURL("a2.com", "/title1.html");
GURL url_b = embedded_test_server()->GetURL("b.com", "/title1.html");
GURL url_c = embedded_test_server()->GetURL("c.com", "/title1.html");
ASSERT_TRUE(content::NavigateToURL(web_contents(), url_a1));
ASSERT_TRUE(content::NavigateToURL(web_contents(), url_a2));
ChainedBackNavigationTracker::CreateForWebContents(web_contents());
ChainedBackNavigationTracker* tracker =
ChainedBackNavigationTracker::FromWebContents(web_contents());
ASSERT_TRUE(tracker);
// The main frame back navigation should increment the count by 1.
ASSERT_TRUE(content::HistoryGoBack(web_contents()));
ASSERT_EQ(url_a1, web_contents()->GetLastCommittedURL());
ASSERT_EQ(1u, tracker->chained_back_navigation_count_);
// Create a subframe and append it to the document.
ASSERT_TRUE(
ExecJs(web_contents(),
content::JsReplace("let frame = document.createElement('iframe');"
"frame.src = $1;"
"document.body.appendChild(frame);",
url_b)));
ASSERT_TRUE(content::WaitForLoadStop(web_contents()));
content::RenderFrameHost* subframe_host =
ChildFrameAt(web_contents()->GetPrimaryMainFrame(), 0);
// Navigate the subframe away, the chained back navigation count should be
// reset to 0.
ASSERT_TRUE(content::ExecJs(
subframe_host, content::JsReplace("window.location.href = $1;", url_c)));
ASSERT_TRUE(content::WaitForLoadStop(web_contents()));
ASSERT_EQ(0u, tracker->chained_back_navigation_count_);
// The sub frame back navigation should increment the count by 1.
ASSERT_TRUE(content::HistoryGoBack(web_contents()));
ASSERT_EQ(1u, tracker->chained_back_navigation_count_);
}
IN_PROC_BROWSER_TEST_F(ChainedBackNavigationTrackerBrowserTest,
RendererInitiatedBackNavigationIsNotCountedAsChained) {
ASSERT_TRUE(embedded_test_server()->Start());
GURL url_a = embedded_test_server()->GetURL("a.com", "/title1.html");
GURL url_b = embedded_test_server()->GetURL("b.com", "/title1.html");
GURL url_c = embedded_test_server()->GetURL("c.com", "/title1.html");
GURL url_d = embedded_test_server()->GetURL("d.com", "/title1.html");
ASSERT_TRUE(content::NavigateToURL(web_contents(), url_a));
ASSERT_TRUE(content::NavigateToURL(web_contents(), url_b));
ASSERT_TRUE(content::NavigateToURL(web_contents(), url_c));
ASSERT_TRUE(content::NavigateToURL(web_contents(), url_d));
ChainedBackNavigationTracker::CreateForWebContents(web_contents());
ChainedBackNavigationTracker* tracker =
ChainedBackNavigationTracker::FromWebContents(web_contents());
ASSERT_TRUE(tracker);
// No back navigation is performed yet, the chain length should not be
// updated.
ASSERT_EQ(0u, tracker->chained_back_navigation_count_);
// The back navigation is renderer initiated, it should not increment the
// chain length.
ASSERT_TRUE(content::ExecJs(web_contents(), "window.history.back();"));
ASSERT_TRUE(content::WaitForLoadStop(web_contents()));
ASSERT_EQ(url_c, web_contents()->GetLastCommittedURL());
ASSERT_EQ(0u, tracker->chained_back_navigation_count_);
// The back navigation is browser initiated, it should increment the chain
// length.
ASSERT_TRUE(content::HistoryGoBack(web_contents()));
ASSERT_EQ(url_b, web_contents()->GetLastCommittedURL());
ASSERT_EQ(1u, tracker->chained_back_navigation_count_);
// The back navigation is renderer initiated, it should reset the chain
// length.
ASSERT_TRUE(content::ExecJs(web_contents(), "window.history.back();"));
ASSERT_TRUE(content::WaitForLoadStop(web_contents()));
ASSERT_EQ(url_a, web_contents()->GetLastCommittedURL());
ASSERT_EQ(0u, tracker->chained_back_navigation_count_);
}
|