summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sessions/session_restore_browsertest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/sessions/session_restore_browsertest.cc')
-rw-r--r--chrome/browser/sessions/session_restore_browsertest.cc122
1 files changed, 122 insertions, 0 deletions
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc
index 5d39701..cea36b2 100644
--- a/chrome/browser/sessions/session_restore_browsertest.cc
+++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -212,6 +212,55 @@ class SessionRestoreTest : public InProcessBrowserTest {
const BrowserList* active_browser_list_;
};
+// Activates the smart restore behaviour and can track the loading of tabs.
+class SmartSessionRestoreTest : public SessionRestoreTest,
+ public content::NotificationObserver {
+ public:
+ SmartSessionRestoreTest() {}
+ void StartObserving(int num_tabs) {
+ num_tabs_ = num_tabs;
+ registrar_.Add(this, content::NOTIFICATION_LOAD_START,
+ content::NotificationService::AllSources());
+ }
+ void Observe(int type,
+ const content::NotificationSource& source,
+ const content::NotificationDetails& details) override {
+ switch (type) {
+ case content::NOTIFICATION_LOAD_START: {
+ content::NavigationController* controller =
+ content::Source<content::NavigationController>(source).ptr();
+ web_contents_.push_back(controller->GetWebContents());
+ if (web_contents_.size() == static_cast<size_t>(num_tabs_))
+ message_loop_runner_->Quit();
+ break;
+ }
+ }
+ }
+ const std::vector<content::WebContents*>& web_contents() const {
+ return web_contents_;
+ }
+
+ void WaitForAllTabsToStartLoading() {
+ message_loop_runner_ = new content::MessageLoopRunner;
+ message_loop_runner_->Run();
+ }
+
+ protected:
+ void SetUpCommandLine(base::CommandLine* command_line) override {
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kForceFieldTrials, "SessionRestoreBackgroundLoading/Smart/");
+ }
+
+ private:
+ content::NotificationRegistrar registrar_;
+ // Ordered by load start order.
+ std::vector<content::WebContents*> web_contents_;
+ scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
+ int num_tabs_;
+
+ DISALLOW_COPY_AND_ASSIGN(SmartSessionRestoreTest);
+};
+
// Verifies that restored tabs have a root window. This is important
// otherwise the wrong information is communicated to the renderer.
// (http://crbug.com/342672).
@@ -1280,3 +1329,76 @@ IN_PROC_BROWSER_TEST_F(SessionRestoreTest, SessionStorageAfterTabReplace) {
ASSERT_EQ(1u, active_browser_list_->size());
EXPECT_EQ(1, new_browser->tab_strip_model()->count());
}
+
+IN_PROC_BROWSER_TEST_F(SmartSessionRestoreTest, CorrectLoadingOrder) {
+ ASSERT_TRUE(SessionRestore::SmartLoadingEnabled());
+
+ const int NumTabs = 6;
+
+ // Start observing the loading of tabs, to make sure the order is correct.
+ StartObserving(NumTabs);
+
+ struct TabInfo {
+ GURL url;
+ bool pinned;
+ int expected_load_order;
+ };
+
+ TabInfo tab_info[NumTabs] = {
+ // This will be the foreground tab and will always load first.
+ {GURL("http://google.com/1"), false, 1},
+ {GURL("http://google.com/2"), false, 3},
+ // Internal page, should load last.
+ {GURL(chrome::kChromeUINewTabURL), false, 6},
+ {GURL("http://google.com/4"), false, 4},
+ {GURL("http://google.com/5"), true, 2}, // Pinned, should load second.
+ {GURL("http://google.com/6"), false, 5},
+ };
+
+ // Set up the restore data.
+ std::vector<const sessions::SessionWindow*> session;
+ sessions::SessionWindow window;
+ sessions::SessionTab tab[NumTabs];
+
+ for (int i = 0; i < NumTabs; i++) {
+ SerializedNavigationEntry nav =
+ SerializedNavigationEntryTestHelper::CreateNavigation(
+ tab_info[i].url.spec(), tab_info[i].url.spec().c_str());
+ sync_pb::SessionTab sync_data;
+ sync_data.set_tab_visual_index(0);
+ sync_data.set_current_navigation_index(0);
+ sync_data.add_navigation()->CopyFrom(nav.ToSyncData());
+ sync_data.set_pinned(tab_info[i].pinned);
+ tab[i].SetFromSyncData(sync_data, base::Time::Now());
+ window.tabs.push_back(tab + i);
+ }
+
+ session.push_back(&window);
+ Profile* profile = browser()->profile();
+ ui_test_utils::BrowserAddedObserver window_observer;
+ std::vector<Browser*> browsers = SessionRestore::RestoreForeignSessionWindows(
+ profile, browser()->host_desktop_type(), session.begin(), session.end());
+
+ ASSERT_EQ(1u, browsers.size());
+ ASSERT_TRUE(browsers[0]);
+ ASSERT_EQ(NumTabs, browsers[0]->tab_strip_model()->count());
+
+ WaitForAllTabsToStartLoading();
+
+ ASSERT_EQ(static_cast<size_t>(NumTabs), web_contents().size());
+
+ // Make sure that contents are loaded in the correct order, ie. each tab rank
+ // is higher that its preceding one.
+ std::map<GURL, int> ranks;
+ for (auto t : tab_info)
+ ranks[t.url] = t.expected_load_order;
+ for (size_t i = 1; i < web_contents().size(); i++) {
+ int current_rank = ranks[web_contents()[i]->GetLastCommittedURL()];
+ int previous_rank = ranks[web_contents()[i - 1]->GetLastCommittedURL()];
+ ASSERT_LT(previous_rank, current_rank);
+ }
+
+ // The SessionWindow destructor deletes the tabs, so we have to clear them
+ // here to avoid a crash.
+ window.tabs.clear();
+}