Avi Drissman | 4e1b7bc3 | 2022-09-15 14:03:50 | [diff] [blame] | 1 | // Copyright 2021 The Chromium Authors |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
Avi Drissman | adac2199 | 2023-01-11 23:46:39 | [diff] [blame] | 5 | #include "base/functional/bind.h" |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 6 | #include "content/browser/renderer_host/document_service_echo_impl.h" |
| 7 | #include "content/public/browser/document_service.h" |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 8 | #include "content/public/browser/render_frame_host.h" |
| 9 | #include "content/public/browser/web_contents.h" |
| 10 | #include "content/public/common/content_features.h" |
Rakina Zata Amni | e59ab76 | 2022-02-08 06:50:47 | [diff] [blame] | 11 | #include "content/public/test/back_forward_cache_util.h" |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 12 | #include "content/public/test/browser_test.h" |
| 13 | #include "content/public/test/content_browser_test.h" |
| 14 | #include "content/public/test/content_browser_test_utils.h" |
| 15 | #include "content/public/test/prerender_test_util.h" |
| 16 | #include "content/public/test/test_utils.h" |
| 17 | #include "content/shell/browser/shell.h" |
| 18 | #include "content/test/content_browser_test_utils_internal.h" |
| 19 | #include "content/test/echo.test-mojom.h" |
| 20 | #include "mojo/public/cpp/bindings/remote.h" |
| 21 | #include "net/dns/mock_host_resolver.h" |
| 22 | #include "net/test/embedded_test_server/embedded_test_server.h" |
| 23 | #include "testing/gtest/include/gtest/gtest.h" |
| 24 | #include "url/gurl.h" |
| 25 | |
| 26 | namespace content { |
| 27 | |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 28 | class DocumentServiceBrowserTest : public ContentBrowserTest { |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 29 | public: |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 30 | DocumentServiceBrowserTest() = default; |
| 31 | ~DocumentServiceBrowserTest() override = default; |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 32 | |
| 33 | void SetUpOnMainThread() override { |
| 34 | host_resolver()->AddRule("*", "127.0.0.1"); |
| 35 | ASSERT_TRUE(test_server_handle_ = |
| 36 | embedded_test_server()->StartAndReturnHandle()); |
| 37 | } |
| 38 | |
| 39 | WebContents* web_contents() const { return shell()->web_contents(); } |
| 40 | |
| 41 | private: |
| 42 | net::test_server::EmbeddedTestServerHandle test_server_handle_; |
| 43 | }; |
| 44 | |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 45 | class DocumentServicePrerenderingBrowserTest |
| 46 | : public DocumentServiceBrowserTest { |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 47 | public: |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 48 | DocumentServicePrerenderingBrowserTest() |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 49 | : prerender_helper_(base::BindRepeating( |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 50 | &DocumentServicePrerenderingBrowserTest::web_contents, |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 51 | base::Unretained(this))) {} |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 52 | ~DocumentServicePrerenderingBrowserTest() override = default; |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 53 | |
| 54 | void SetUp() override { |
Robert Lin | eb2a99c | 2023-08-24 02:42:26 | [diff] [blame] | 55 | prerender_helper_.RegisterServerRequestMonitor(embedded_test_server()); |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 56 | DocumentServiceBrowserTest::SetUp(); |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | test::PrerenderTestHelper* prerender_helper() { return &prerender_helper_; } |
| 60 | |
| 61 | private: |
| 62 | test::PrerenderTestHelper prerender_helper_; |
| 63 | }; |
| 64 | |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 65 | // Tests that DocumentService is not destroyed on prerendering activation. |
| 66 | IN_PROC_BROWSER_TEST_F(DocumentServicePrerenderingBrowserTest, |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 67 | NotClosedInPrerenderingActivation) { |
| 68 | const GURL kInitialUrl = embedded_test_server()->GetURL("/empty.html"); |
| 69 | const GURL kPrerenderingUrl = embedded_test_server()->GetURL("/title1.html"); |
Rakina Zata Amni | e59ab76 | 2022-02-08 06:50:47 | [diff] [blame] | 70 | // The test assumes documents and their DocumentServices get deleted after |
| 71 | // non-activation navigations. To ensure this, disable back/forward cache. |
| 72 | DisableBackForwardCacheForTesting( |
| 73 | shell()->web_contents(), |
| 74 | content::BackForwardCache::TEST_REQUIRES_NO_CACHING); |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 75 | |
| 76 | // Navigate to an initial page. |
| 77 | ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); |
| 78 | |
Avi Drissman | 580a3da6 | 2024-09-04 16:16:56 | [diff] [blame] | 79 | FrameTreeNodeId host_id = prerender_helper()->AddPrerender(kPrerenderingUrl); |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 80 | RenderFrameHost* prerendered_frame_host = |
| 81 | prerender_helper()->GetPrerenderedMainFrameHost(host_id); |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 82 | |
| 83 | mojo::Remote<mojom::Echo> echo_remote; |
| 84 | bool echo_deleted = false; |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 85 | new DocumentServiceEchoImpl( |
danakj | c70aec1f | 2022-07-07 15:48:19 | [diff] [blame] | 86 | *prerendered_frame_host, echo_remote.BindNewPipeAndPassReceiver(), |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 87 | base::BindOnce([](bool* deleted) { *deleted = true; }, &echo_deleted)); |
| 88 | |
| 89 | // Activate the prerendered page. |
| 90 | prerender_helper()->NavigatePrimaryPage(kPrerenderingUrl); |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 91 | // DocumentService should not be destroyed. |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 92 | EXPECT_FALSE(echo_deleted); |
| 93 | |
| 94 | ASSERT_TRUE(NavigateToURL(shell(), kInitialUrl)); |
| 95 | // It should be destroyed on navigation. |
| 96 | EXPECT_TRUE(echo_deleted); |
| 97 | } |
| 98 | |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 99 | class DocumentServiceBFCacheBrowserTest : public DocumentServiceBrowserTest { |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 100 | public: |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 101 | DocumentServiceBFCacheBrowserTest() { |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 102 | feature_list_.InitWithFeaturesAndParameters( |
Ming-Ying Chung | 7263618 | 2023-02-28 12:16:04 | [diff] [blame] | 103 | GetDefaultEnabledBackForwardCacheFeaturesForTesting(), |
| 104 | GetDefaultDisabledBackForwardCacheFeaturesForTesting()); |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 105 | } |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 106 | ~DocumentServiceBFCacheBrowserTest() override = default; |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 107 | |
| 108 | private: |
| 109 | base::test::ScopedFeatureList feature_list_; |
| 110 | }; |
| 111 | |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 112 | IN_PROC_BROWSER_TEST_F(DocumentServiceBFCacheBrowserTest, DocumentService) { |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 113 | GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); |
| 114 | GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); |
| 115 | |
| 116 | // 1) Navigate to A. |
| 117 | ASSERT_TRUE(NavigateToURL(shell(), url_a)); |
| 118 | RenderFrameHost* rfh_a = |
Dave Tapuska | 327c06c9 | 2022-06-13 20:31:51 | [diff] [blame] | 119 | web_contents()->GetPrimaryMainFrame(); // current_frame_host(); |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 120 | RenderFrameDeletedObserver delete_observer_rfh_a(rfh_a); |
| 121 | |
| 122 | mojo::Remote<mojom::Echo> echo_remote; |
| 123 | bool echo_deleted = false; |
Daniel Cheng | 9fb887ff | 2021-10-01 20:27:38 | [diff] [blame] | 124 | new DocumentServiceEchoImpl( |
danakj | c70aec1f | 2022-07-07 15:48:19 | [diff] [blame] | 125 | *rfh_a, echo_remote.BindNewPipeAndPassReceiver(), |
Julie Jeongeun Kim | 5a66adb4 | 2021-08-11 07:14:10 | [diff] [blame] | 126 | base::BindOnce([](bool* deleted) { *deleted = true; }, &echo_deleted)); |
| 127 | |
| 128 | // 2) Navigate to B. |
| 129 | ASSERT_TRUE(NavigateToURL(shell(), url_b)); |
| 130 | |
| 131 | // - Page A should be in the cache. |
| 132 | ASSERT_FALSE(delete_observer_rfh_a.deleted()); |
| 133 | EXPECT_EQ(rfh_a->GetLifecycleState(), |
| 134 | RenderFrameHost::LifecycleState::kInBackForwardCache); |
| 135 | EXPECT_FALSE(echo_deleted); |
| 136 | |
| 137 | // 3) Go back. |
| 138 | web_contents()->GetController().GoBack(); |
| 139 | EXPECT_TRUE(WaitForLoadStop(shell()->web_contents())); |
| 140 | EXPECT_FALSE(echo_deleted); |
| 141 | |
| 142 | // 4) Prevent caching and navigate to B. |
| 143 | DisableBFCacheForRFHForTesting(rfh_a); |
| 144 | ASSERT_TRUE(NavigateToURL(shell(), url_b)); |
| 145 | delete_observer_rfh_a.WaitUntilDeleted(); |
| 146 | EXPECT_TRUE(echo_deleted); |
| 147 | } |
| 148 | |
| 149 | } // namespace content |