blob: 73efa627e12709ac31191fc033f01355d6f377c1 [file] [log] [blame]
Torne (Richard Coles)58218062012-11-14 11:43:16 +00001// Copyright (c) 2012 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
5#include "chrome/test/base/browser_with_test_window_test.h"
6
Ben Murdocha3f7b4e2013-07-24 10:36:34 +01007#include "base/run_loop.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +00008#include "chrome/browser/profiles/profile_destroyer.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00009#include "chrome/browser/ui/browser.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000010#include "chrome/browser/ui/browser_navigator.h"
Torne (Richard Coles)58218062012-11-14 11:43:16 +000011#include "chrome/browser/ui/tabs/tab_strip_model.h"
12#include "chrome/common/render_messages.h"
13#include "chrome/test/base/testing_profile.h"
14#include "content/public/browser/navigation_controller.h"
15#include "content/public/browser/navigation_entry.h"
16#include "content/public/browser/web_contents.h"
17#include "content/public/common/page_transition_types.h"
18#include "content/public/test/test_renderer_host.h"
19
20#if defined(USE_AURA)
21#include "ui/aura/test/aura_test_helper.h"
22#endif
23
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010024#if defined(USE_ASH)
25#include "ash/test/ash_test_helper.h"
26#endif
27
Torne (Richard Coles)58218062012-11-14 11:43:16 +000028using content::NavigationController;
29using content::RenderViewHost;
30using content::RenderViewHostTester;
31using content::WebContents;
32
33BrowserWithTestWindowTest::BrowserWithTestWindowTest()
Ben Murdocha3f7b4e2013-07-24 10:36:34 +010034 : host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000035}
36
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010037BrowserWithTestWindowTest::~BrowserWithTestWindowTest() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010038}
39
40void BrowserWithTestWindowTest::SetHostDesktopType(
41 chrome::HostDesktopType host_desktop_type) {
42 DCHECK(!window_);
43 host_desktop_type_ = host_desktop_type;
Torne (Richard Coles)58218062012-11-14 11:43:16 +000044}
45
46void BrowserWithTestWindowTest::SetUp() {
47 testing::Test::SetUp();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010048#if defined(OS_CHROMEOS)
49 // TODO(jamescook): Windows Ash support. This will require refactoring
50 // AshTestHelper and AuraTestHelper so they can be used at the same time,
51 // perhaps by AshTestHelper owning an AuraTestHelper.
Ben Murdocha3f7b4e2013-07-24 10:36:34 +010052 ash_test_helper_.reset(new ash::test::AshTestHelper(
53 base::MessageLoopForUI::current()));
Ben Murdochbb1529c2013-08-08 10:24:53 +010054 ash_test_helper_->SetUp(true);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010055#elif defined(USE_AURA)
Ben Murdocha3f7b4e2013-07-24 10:36:34 +010056 aura_test_helper_.reset(new aura::test::AuraTestHelper(
57 base::MessageLoopForUI::current()));
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010058 aura_test_helper_->SetUp();
59#endif // USE_AURA
Torne (Richard Coles)58218062012-11-14 11:43:16 +000060
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010061 // Subclasses can provide their own Profile.
62 profile_.reset(CreateProfile());
63 // Subclasses can provide their own test BrowserWindow. If they return NULL
64 // then Browser will create the a production BrowserWindow and the subclass
65 // is responsible for cleaning it up (usually by NativeWidget destruction).
66 window_.reset(CreateBrowserWindow());
Torne (Richard Coles)58218062012-11-14 11:43:16 +000067
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000068 Browser::CreateParams params(profile(), host_desktop_type_);
Torne (Richard Coles)58218062012-11-14 11:43:16 +000069 params.window = window_.get();
70 browser_.reset(new Browser(params));
Torne (Richard Coles)58218062012-11-14 11:43:16 +000071}
72
73void BrowserWithTestWindowTest::TearDown() {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010074 // Some tests end up posting tasks to the DB thread that must be completed
75 // before the profile can be destroyed and the test safely shut down.
Ben Murdocha3f7b4e2013-07-24 10:36:34 +010076 base::RunLoop().RunUntilIdle();
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010077
78 // Reset the profile here because some profile keyed services (like the
79 // audio service) depend on test stubs that the helpers below will remove.
80 DestroyBrowserAndProfile();
81
82#if defined(OS_CHROMEOS)
83 ash_test_helper_->TearDown();
84#elif defined(USE_AURA)
85 aura_test_helper_->TearDown();
86#endif
87 testing::Test::TearDown();
88
89 // A Task is leaked if we don't destroy everything, then run the message
90 // loop.
Torne (Richard Coles)a93a17c2013-05-15 11:34:50 +010091 base::MessageLoop::current()->PostTask(FROM_HERE,
92 base::MessageLoop::QuitClosure());
93 base::MessageLoop::current()->Run();
Torne (Richard Coles)58218062012-11-14 11:43:16 +000094}
95
Torne (Richard Coles)58218062012-11-14 11:43:16 +000096void BrowserWithTestWindowTest::AddTab(Browser* browser, const GURL& url) {
97 chrome::NavigateParams params(browser, url, content::PAGE_TRANSITION_TYPED);
98 params.tabstrip_index = 0;
99 params.disposition = NEW_FOREGROUND_TAB;
100 chrome::Navigate(&params);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000101 CommitPendingLoad(&params.target_contents->GetController());
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000102}
103
104void BrowserWithTestWindowTest::CommitPendingLoad(
105 NavigationController* controller) {
106 if (!controller->GetPendingEntry())
107 return; // Nothing to commit.
108
109 RenderViewHost* old_rvh =
110 controller->GetWebContents()->GetRenderViewHost();
111
112 RenderViewHost* pending_rvh = RenderViewHostTester::GetPendingForController(
113 controller);
114 if (pending_rvh) {
115 // Simulate the ShouldClose_ACK that is received from the current renderer
116 // for a cross-site navigation.
117 DCHECK_NE(old_rvh, pending_rvh);
118 RenderViewHostTester::For(old_rvh)->SendShouldCloseACK(true);
119 }
120 // Commit on the pending_rvh, if one exists.
121 RenderViewHost* test_rvh = pending_rvh ? pending_rvh : old_rvh;
122 RenderViewHostTester* test_rvh_tester = RenderViewHostTester::For(test_rvh);
123
Ben Murdoch7dbb3d52013-07-17 14:55:54 +0100124 // Simulate a SwapOut_ACK before the navigation commits.
125 if (pending_rvh)
126 RenderViewHostTester::For(old_rvh)->SimulateSwapOutACK();
127
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000128 // For new navigations, we need to send a larger page ID. For renavigations,
129 // we need to send the preexisting page ID. We can tell these apart because
130 // renavigations will have a pending_entry_index while new ones won't (they'll
131 // just have a standalong pending_entry that isn't in the list already).
132 if (controller->GetPendingEntryIndex() >= 0) {
133 test_rvh_tester->SendNavigateWithTransition(
134 controller->GetPendingEntry()->GetPageID(),
135 controller->GetPendingEntry()->GetURL(),
136 controller->GetPendingEntry()->GetTransitionType());
137 } else {
138 test_rvh_tester->SendNavigateWithTransition(
139 controller->GetWebContents()->
140 GetMaxPageIDForSiteInstance(test_rvh->GetSiteInstance()) + 1,
141 controller->GetPendingEntry()->GetURL(),
142 controller->GetPendingEntry()->GetTransitionType());
143 }
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000144}
145
146void BrowserWithTestWindowTest::NavigateAndCommit(
147 NavigationController* controller,
148 const GURL& url) {
149 controller->LoadURL(
150 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string());
151 CommitPendingLoad(controller);
152}
153
154void BrowserWithTestWindowTest::NavigateAndCommitActiveTab(const GURL& url) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000155 NavigateAndCommit(&browser()->tab_strip_model()->GetActiveWebContents()->
156 GetController(),
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000157 url);
158}
159
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000160void BrowserWithTestWindowTest::NavigateAndCommitActiveTabWithTitle(
161 Browser* navigating_browser,
162 const GURL& url,
163 const string16& title) {
164 NavigationController* controller = &navigating_browser->tab_strip_model()->
165 GetActiveWebContents()->GetController();
166 NavigateAndCommit(controller, url);
167 controller->GetActiveEntry()->SetTitle(title);
168}
169
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000170void BrowserWithTestWindowTest::DestroyBrowserAndProfile() {
171 if (browser_.get()) {
172 // Make sure we close all tabs, otherwise Browser isn't happy in its
173 // destructor.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000174 browser()->tab_strip_model()->CloseAllTabs();
Torne (Richard Coles)58218062012-11-14 11:43:16 +0000175 browser_.reset(NULL);
176 }
177 window_.reset(NULL);
178 // Destroy the profile here - otherwise, if the profile is freed in the
179 // destructor, and a test subclass owns a resource that the profile depends
180 // on (such as g_browser_process()->local_state()) there's no way for the
181 // subclass to free it after the profile.
182 profile_.reset(NULL);
183}
184
185TestingProfile* BrowserWithTestWindowTest::CreateProfile() {
186 return new TestingProfile();
187}
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100188
189BrowserWindow* BrowserWithTestWindowTest::CreateBrowserWindow() {
190 return new TestBrowserWindow();
191}