performance_manager_browsertest.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/performance_manager/public/performance_manager.h"
  5. #include <utility>
  6. #include "base/run_loop.h"
  7. #include "base/test/bind.h"
  8. #include "components/performance_manager/graph/frame_node_impl.h"
  9. #include "components/performance_manager/performance_manager_tab_helper.h"
  10. #include "components/performance_manager/public/graph/frame_node.h"
  11. #include "components/performance_manager/public/graph/page_node.h"
  12. #include "components/performance_manager/public/render_frame_host_proxy.h"
  13. #include "components/performance_manager/public/web_contents_proxy.h"
  14. #include "components/performance_manager/test_support/performance_manager_browsertest_harness.h"
  15. #include "content/public/browser/browser_task_traits.h"
  16. #include "content/public/browser/browser_thread.h"
  17. #include "content/public/browser/render_frame_host.h"
  18. #include "content/public/test/browser_test.h"
  19. #include "content/public/test/content_browser_test_utils.h"
  20. #include "content/public/test/fenced_frame_test_util.h"
  21. #include "content/shell/browser/shell.h"
  22. #include "net/test/embedded_test_server/embedded_test_server.h"
  23. #include "testing/gtest/include/gtest/gtest.h"
  24. namespace performance_manager {
  25. using PerformanceManagerBrowserTest = PerformanceManagerBrowserTestHarness;
  26. // A full browser test is required for this because we need RenderFrameHosts
  27. // to be created.
  28. IN_PROC_BROWSER_TEST_F(PerformanceManagerBrowserTest,
  29. GetFrameNodeForRenderFrameHost) {
  30. // NavigateToURL blocks until the load has completed. We assert that the
  31. // contents has been reused as we don't have general WebContents creation
  32. // hooks in our BrowserTest fixture, and if a new contents was created it
  33. // would be missing the PM tab helper.
  34. auto* old_contents = shell()->web_contents();
  35. static const char kUrl[] = "about:blank";
  36. ASSERT_TRUE(NavigateToURL(shell(), GURL(kUrl)));
  37. content::WebContents* contents = shell()->web_contents();
  38. ASSERT_EQ(contents, old_contents);
  39. ASSERT_EQ(contents->GetLastCommittedURL().possibly_invalid_spec(), kUrl);
  40. content::RenderFrameHost* rfh = contents->GetPrimaryMainFrame();
  41. ASSERT_TRUE(rfh->IsRenderFrameLive());
  42. base::WeakPtr<FrameNode> frame_node =
  43. PerformanceManager::GetFrameNodeForRenderFrameHost(rfh);
  44. // Post a task to the Graph and make it call a function on the UI thread that
  45. // will ensure that |frame_node| is really associated with |rfh|.
  46. base::RunLoop run_loop;
  47. auto check_rfh_on_main_thread =
  48. base::BindLambdaForTesting([&](const RenderFrameHostProxy& rfh_proxy) {
  49. EXPECT_EQ(rfh, rfh_proxy.Get());
  50. run_loop.Quit();
  51. });
  52. auto call_on_graph_cb = base::BindLambdaForTesting([&]() {
  53. EXPECT_TRUE(frame_node.get());
  54. content::GetUIThreadTaskRunner({})->PostTask(
  55. FROM_HERE, base::BindOnce(std::move(check_rfh_on_main_thread),
  56. frame_node->GetRenderFrameHostProxy()));
  57. });
  58. PerformanceManager::CallOnGraph(FROM_HERE, call_on_graph_cb);
  59. // Wait for |check_rfh_on_main_thread| to be called.
  60. run_loop.Run();
  61. // This closes the window, and destroys the underlying WebContents.
  62. shell()->Close();
  63. contents = nullptr;
  64. // After deleting |contents| the corresponding FrameNode WeakPtr should be
  65. // invalid.
  66. base::RunLoop run_loop_after_contents_reset;
  67. auto quit_closure = run_loop_after_contents_reset.QuitClosure();
  68. auto call_on_graph_cb_2 = base::BindLambdaForTesting([&]() {
  69. EXPECT_FALSE(frame_node.get());
  70. std::move(quit_closure).Run();
  71. });
  72. PerformanceManager::CallOnGraph(FROM_HERE, call_on_graph_cb_2);
  73. run_loop_after_contents_reset.Run();
  74. }
  75. IN_PROC_BROWSER_TEST_F(PerformanceManagerBrowserTest, OpenerTrackingWorks) {
  76. // Load a page that will load a popup.
  77. GURL url(embedded_test_server()->GetURL("a.com", "/a_popup_a.html"));
  78. content::ShellAddedObserver shell_added_observer;
  79. ASSERT_TRUE(NavigateToURL(shell(), url));
  80. // Wait for the popup window to appear, and then wait for it to load.
  81. auto* popup = shell_added_observer.GetShell();
  82. ASSERT_TRUE(popup);
  83. WaitForLoad(popup->web_contents());
  84. auto* contents = shell()->web_contents();
  85. auto page = PerformanceManager::GetPrimaryPageNodeForWebContents(contents);
  86. // Jump into the graph and make sure everything is connected as expected.
  87. base::RunLoop run_loop;
  88. PerformanceManager::CallOnGraph(
  89. FROM_HERE, base::BindLambdaForTesting([&page, &run_loop]() {
  90. EXPECT_TRUE(page);
  91. auto* frame = page->GetMainFrameNode();
  92. EXPECT_EQ(1u, frame->GetOpenedPageNodes().size());
  93. auto* embedded_page = *(frame->GetOpenedPageNodes().begin());
  94. EXPECT_EQ(frame, embedded_page->GetOpenerFrameNode());
  95. run_loop.Quit();
  96. }));
  97. run_loop.Run();
  98. }
  99. class PerformanceManagerFencedFrameBrowserTest
  100. : public PerformanceManagerBrowserTest {
  101. public:
  102. PerformanceManagerFencedFrameBrowserTest() = default;
  103. ~PerformanceManagerFencedFrameBrowserTest() override = default;
  104. PerformanceManagerFencedFrameBrowserTest(
  105. const PerformanceManagerFencedFrameBrowserTest&) = delete;
  106. PerformanceManagerFencedFrameBrowserTest& operator=(
  107. const PerformanceManagerFencedFrameBrowserTest&) = delete;
  108. content::test::FencedFrameTestHelper& fenced_frame_test_helper() {
  109. return fenced_frame_helper_;
  110. }
  111. content::WebContents* GetWebContents() { return shell()->web_contents(); }
  112. private:
  113. content::test::FencedFrameTestHelper fenced_frame_helper_;
  114. };
  115. IN_PROC_BROWSER_TEST_F(PerformanceManagerFencedFrameBrowserTest,
  116. FencedFrameDoesNotHaveParentFrameNode) {
  117. auto initial_url = embedded_test_server()->GetURL("/empty.html");
  118. ASSERT_TRUE(NavigateToURL(shell(), initial_url));
  119. PerformanceManagerTabHelper* tab_helper =
  120. PerformanceManagerTabHelper::FromWebContents(GetWebContents());
  121. DCHECK(tab_helper);
  122. EXPECT_EQ(tab_helper->frames_.size(), 1U);
  123. // Load a fenced frame.
  124. GURL fenced_frame_url =
  125. embedded_test_server()->GetURL("/fenced_frames/title1.html");
  126. content::RenderFrameHost* fenced_frame_host =
  127. fenced_frame_test_helper().CreateFencedFrame(
  128. GetWebContents()->GetPrimaryMainFrame(), fenced_frame_url);
  129. // Jump into the graph and make sure |fenced_frame_host| does not have a
  130. // parent frame node.
  131. base::RunLoop run_loop;
  132. PerformanceManager::CallOnGraph(
  133. FROM_HERE,
  134. base::BindLambdaForTesting([tab_helper, fenced_frame_host, &run_loop]() {
  135. // Fenced frame and Portals have an embedder frame node instead of a
  136. // parent frame node. So, the fenced frame should not have a parent
  137. // frame node.
  138. ASSERT_EQ(tab_helper->frames_[fenced_frame_host]->parent_frame_node(),
  139. nullptr);
  140. // TODO(crbug.com/1260363): Check that the embedder relationship exists.
  141. // See also crbug.com/1261454 because the check of
  142. // tab_helper->frames_.size() caused a flaky test failure.
  143. run_loop.Quit();
  144. }));
  145. run_loop.Run();
  146. }
  147. } // namespace performance_manager