Index: chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
diff --git a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
index 4d5a1ca1253e4e2a14eefbe8af41a381ecaa1253..c7274e7319bf832e5e1ee4c318f6a603314babe4 100644 |
--- a/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
+++ b/chrome/browser/page_load_metrics/page_load_metrics_browsertest.cc |
@@ -11,16 +11,24 @@ |
#include "base/test/histogram_tester.h" |
#include "base/threading/thread_restrictions.h" |
#include "base/time/time.h" |
+#include "build/build_config.h" |
+#include "chrome/browser/lifetime/keep_alive_types.h" |
+#include "chrome/browser/lifetime/scoped_keep_alive.h" |
#include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h" |
#include "chrome/browser/page_load_metrics/observers/aborts_page_load_metrics_observer.h" |
#include "chrome/browser/page_load_metrics/observers/core_page_load_metrics_observer.h" |
#include "chrome/browser/page_load_metrics/observers/document_write_page_load_metrics_observer.h" |
#include "chrome/browser/page_load_metrics/observers/no_state_prefetch_page_load_metrics_observer.h" |
+#include "chrome/browser/page_load_metrics/observers/session_restore_page_load_metrics_observer.h" |
#include "chrome/browser/page_load_metrics/page_load_tracker.h" |
+#include "chrome/browser/prefs/session_startup_pref.h" |
#include "chrome/browser/prerender/prerender_histograms.h" |
#include "chrome/browser/prerender/prerender_origin.h" |
#include "chrome/browser/profiles/profile.h" |
+#include "chrome/browser/sessions/session_service_factory.h" |
+#include "chrome/browser/sessions/session_service_test_helper.h" |
#include "chrome/browser/ui/browser.h" |
+#include "chrome/browser/ui/browser_commands.h" |
#include "chrome/browser/ui/browser_navigator_params.h" |
#include "chrome/browser/ui/tabs/tab_strip_model.h" |
#include "chrome/common/chrome_features.h" |
@@ -32,8 +40,10 @@ |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/render_process_host.h" |
#include "content/public/browser/render_view_host.h" |
+#include "content/public/common/browser_side_navigation_policy.h" |
#include "content/public/common/content_features.h" |
#include "content/public/common/content_switches.h" |
+#include "content/public/common/referrer.h" |
#include "content/public/test/browser_test_utils.h" |
#include "content/public/test/download_test_observer.h" |
#include "net/base/net_errors.h" |
@@ -1049,3 +1059,199 @@ IN_PROC_BROWSER_TEST_F(PageLoadMetricsBrowserTest, |
histogram_tester_.ExpectUniqueSample(internal::kHistogramTotalBytes, 0, 1); |
} |
+ |
+class SessionRestorePageLoadMetricsBrowserTest |
+ : public PageLoadMetricsBrowserTest { |
+ public: |
+ SessionRestorePageLoadMetricsBrowserTest() {} |
+ |
+ void SetUpOnMainThread() override { |
+ PageLoadMetricsBrowserTest::SetUpOnMainThread(); |
+ SessionStartupPref::SetStartupPref( |
+ browser()->profile(), SessionStartupPref(SessionStartupPref::LAST)); |
+ ASSERT_TRUE(embedded_test_server()->Start()); |
+#if defined(OS_CHROMEOS) |
+ SessionServiceTestHelper helper( |
+ SessionServiceFactory::GetForProfile(browser()->profile())); |
+ helper.SetForceBrowserNotAliveWithNoWindows(true); |
+ helper.ReleaseService(); |
+#endif |
+ } |
+ |
+ Browser* QuitBrowserAndRestore(Browser* browser) { |
+ Profile* profile = browser->profile(); |
+ |
+ // Close the browser. |
+ std::unique_ptr<ScopedKeepAlive> keep_alive(new ScopedKeepAlive( |
+ KeepAliveOrigin::SESSION_RESTORE, KeepAliveRestartOption::DISABLED)); |
+ CloseBrowserSynchronously(browser); |
+ |
+ // Create a new window, which should trigger session restore. |
+ chrome::NewEmptyWindow(profile); |
+ ui_test_utils::BrowserAddedObserver window_observer; |
+ return window_observer.WaitForSingleNewBrowser(); |
+ } |
+ |
+ std::unique_ptr<PageLoadMetricsWaiter> CreatePageLoadMetricsWaiter( |
+ content::WebContents* web_contents) const { |
+ return base::MakeUnique<PageLoadMetricsWaiter>(web_contents); |
+ } |
+ |
+ void WaitForFirstMeaningfulPaintOfActiveTab(Browser* browser) const { |
+ auto waiter = CreatePageLoadMetricsWaiter( |
+ browser->tab_strip_model()->GetActiveWebContents()); |
+ waiter->AddPageExpectation(TimingField::FIRST_MEANINGFUL_PAINT); |
+ waiter->Wait(); |
+ } |
+ |
+ void WaitForTabsToLoad(Browser* browser) { |
+ for (int i = 0; i < browser->tab_strip_model()->count(); ++i) { |
+ content::WebContents* contents = |
+ browser->tab_strip_model()->GetWebContentsAt(i); |
+ contents->GetController().LoadIfNecessary(); |
+ content::WaitForLoadStop(contents); |
+ } |
+ } |
+ |
+ GURL GetTestURL() const { |
+ return embedded_test_server()->GetURL( |
+ "/page_load_metrics/page_with_css.html"); |
+ } |
+ |
+ GURL GetTestURL2() const { |
+ return embedded_test_server()->GetURL( |
+ "/page_load_metrics/main_frame_with_iframe.html"); |
+ } |
+ |
+ void ExpectFirstPaintMetricsTotalCount(int expected_total_count) const { |
+ // SessionRestorePageLoadMetricsObserver is disabled when browser-side |
+ // navigation is enabled |
+ if (content::IsBrowserSideNavigationEnabled()) |
+ expected_total_count = 0; |
+ |
+ histogram_tester_.ExpectTotalCount( |
+ internal::kHistogramSessionRestoreForegroundTabFirstPaint, |
+ expected_total_count); |
+ histogram_tester_.ExpectTotalCount( |
+ internal::kHistogramSessionRestoreForegroundTabFirstContentfulPaint, |
+ expected_total_count); |
+ histogram_tester_.ExpectTotalCount( |
+ internal::kHistogramSessionRestoreForegroundTabFirstMeaningfulPaint, |
+ expected_total_count); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(SessionRestorePageLoadMetricsBrowserTest); |
+}; |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ NoSessionRestore) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ // No metrics recorded because navigation is outside of session restore. |
+ ExpectFirstPaintMetricsTotalCount(0); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ SingleTabSessionRestore) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ Browser* new_browser = QuitBrowserAndRestore(browser()); |
+ WaitForFirstMeaningfulPaintOfActiveTab(new_browser); |
+ ExpectFirstPaintMetricsTotalCount(1); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ MultipleTabsSessionRestore) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ ui_test_utils::NavigateToURLWithDisposition( |
+ browser(), GetTestURL(), WindowOpenDisposition::NEW_BACKGROUND_TAB, |
+ ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
+ Browser* new_browser = QuitBrowserAndRestore(browser()); |
+ |
+ TabStripModel* tab_strip = new_browser->tab_strip_model(); |
+ ASSERT_TRUE(tab_strip); |
+ ASSERT_EQ(2, tab_strip->count()); |
+ |
+ // Wait for first paints on the initial foreground tab and all tabs loaded. |
+ WaitForFirstMeaningfulPaintOfActiveTab(new_browser); |
+ WaitForTabsToLoad(new_browser); |
+ |
+ // Only metrics of the initial foreground tab are recorded. |
+ ExpectFirstPaintMetricsTotalCount(1); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ LoadingInForegroundTabInSessionRestore) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ ui_test_utils::NavigateToURLWithDisposition( |
+ browser(), GetTestURL2(), WindowOpenDisposition::NEW_BACKGROUND_TAB, |
+ ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
+ Browser* new_browser = QuitBrowserAndRestore(browser()); |
+ |
+ // Load a new page in the foreground tab before it finishes loading. |
+ chrome::NavigateParams params(new_browser, GetTestURL2(), |
+ ui::PAGE_TRANSITION_LINK); |
+ chrome::Navigate(¶ms); |
+ // When PlzNavigate enabled, the waiter does not see first paints |
+ if (!content::IsBrowserSideNavigationEnabled()) { |
ducbui
2017/07/03 23:38:44
Somehow the PageLoadMetricsWaiter does not see the
Bryan McQuade
2017/07/03 23:42:24
Ah, I missed these browser-side navigation checks.
|
+ auto waiter = |
+ base::MakeUnique<PageLoadMetricsWaiter>(params.target_contents); |
+ waiter->AddPageExpectation(TimingField::FIRST_MEANINGFUL_PAINT); |
+ waiter->Wait(); |
+ } |
+ |
+ // Do not count the new page load in the initial foreground tab. |
+ ExpectFirstPaintMetricsTotalCount(0); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ LoadingAfterSessionRestore) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ Browser* new_browser = QuitBrowserAndRestore(browser()); |
+ |
+ // Wait for session restore to finish (i.e., the end of the only tab). |
+ WaitForFirstMeaningfulPaintOfActiveTab(new_browser); |
+ ExpectFirstPaintMetricsTotalCount(1); |
+ |
+ // Load a new page after session restore. |
+ auto waiter = CreatePageLoadMetricsWaiter( |
+ new_browser->tab_strip_model()->GetActiveWebContents()); |
+ waiter->AddPageExpectation(TimingField::FIRST_MEANINGFUL_PAINT); |
+ ui_test_utils::NavigateToURL(new_browser, GetTestURL2()); |
+ waiter->Wait(); |
+ |
+ // No more metrics because the navigation is after session restore. |
+ ExpectFirstPaintMetricsTotalCount(1); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ InitialForegroundTabChanged) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ ui_test_utils::NavigateToURLWithDisposition( |
+ browser(), GetTestURL2(), WindowOpenDisposition::NEW_BACKGROUND_TAB, |
+ ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
+ Browser* new_browser = QuitBrowserAndRestore(browser()); |
+ |
+ // Change the foreground tab before the first meaningful paint. |
+ TabStripModel* tab_strip = new_browser->tab_strip_model(); |
+ ASSERT_TRUE(tab_strip); |
+ ASSERT_EQ(2, tab_strip->count()); |
+ ASSERT_EQ(0, tab_strip->active_index()); |
+ tab_strip->ActivateTabAt(1, true); |
+ |
+ // Wait for the first meaningful paint of the current foreground tab. |
+ WaitForFirstMeaningfulPaintOfActiveTab(new_browser); |
+ ExpectFirstPaintMetricsTotalCount(0); |
+} |
+ |
+IN_PROC_BROWSER_TEST_F(SessionRestorePageLoadMetricsBrowserTest, |
+ MultipleSessionRestores) { |
+ ui_test_utils::NavigateToURL(browser(), GetTestURL()); |
+ |
+ Browser* current_browser = browser(); |
+ const int num_session_restores = 3; |
+ for (int i = 1; i <= num_session_restores; ++i) { |
+ current_browser = QuitBrowserAndRestore(current_browser); |
+ WaitForFirstMeaningfulPaintOfActiveTab(current_browser); |
+ ExpectFirstPaintMetricsTotalCount(i); |
+ } |
+} |