- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / base / browser_with_test_window_test.cc
1 // 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
7 #include "base/run_loop.h"
8 #include "chrome/browser/profiles/profile_destroyer.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_navigator.h"
11 #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
24 #if defined(USE_ASH)
25 #include "ash/test/ash_test_helper.h"
26 #endif
27
28 using content::NavigationController;
29 using content::RenderViewHost;
30 using content::RenderViewHostTester;
31 using content::WebContents;
32
33 BrowserWithTestWindowTest::BrowserWithTestWindowTest()
34     : host_desktop_type_(chrome::HOST_DESKTOP_TYPE_NATIVE) {
35 }
36
37 BrowserWithTestWindowTest::~BrowserWithTestWindowTest() {
38 }
39
40 void BrowserWithTestWindowTest::SetHostDesktopType(
41     chrome::HostDesktopType host_desktop_type) {
42   DCHECK(!window_);
43   host_desktop_type_ = host_desktop_type;
44 }
45
46 void BrowserWithTestWindowTest::SetUp() {
47   testing::Test::SetUp();
48 #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.
52   ash_test_helper_.reset(new ash::test::AshTestHelper(
53       base::MessageLoopForUI::current()));
54   ash_test_helper_->SetUp(true);
55 #elif defined(USE_AURA)
56   aura_test_helper_.reset(new aura::test::AuraTestHelper(
57       base::MessageLoopForUI::current()));
58   aura_test_helper_->SetUp();
59 #endif  // USE_AURA
60
61   // Subclasses can provide their own Profile.
62   profile_ = 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());
67
68   Browser::CreateParams params(profile(), host_desktop_type_);
69   params.window = window_.get();
70   browser_.reset(new Browser(params));
71 }
72
73 void BrowserWithTestWindowTest::TearDown() {
74   // 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.
76   base::RunLoop().RunUntilIdle();
77
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.
91   base::MessageLoop::current()->PostTask(FROM_HERE,
92                                          base::MessageLoop::QuitClosure());
93   base::MessageLoop::current()->Run();
94 }
95
96 void 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);
101   CommitPendingLoad(&params.target_contents->GetController());
102 }
103
104 void 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
124   // Simulate a SwapOut_ACK before the navigation commits.
125   if (pending_rvh)
126     RenderViewHostTester::For(old_rvh)->SimulateSwapOutACK();
127
128   // 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   }
144 }
145
146 void 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
154 void BrowserWithTestWindowTest::NavigateAndCommitActiveTab(const GURL& url) {
155   NavigateAndCommit(&browser()->tab_strip_model()->GetActiveWebContents()->
156                         GetController(),
157                     url);
158 }
159
160 void 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
170 void BrowserWithTestWindowTest::DestroyBrowserAndProfile() {
171   if (browser_.get()) {
172     // Make sure we close all tabs, otherwise Browser isn't happy in its
173     // destructor.
174     browser()->tab_strip_model()->CloseAllTabs();
175     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   if (profile_)
183     DestroyProfile(profile_);
184   profile_ = NULL;
185 }
186
187 TestingProfile* BrowserWithTestWindowTest::CreateProfile() {
188   return new TestingProfile();
189 }
190
191 void BrowserWithTestWindowTest::DestroyProfile(TestingProfile* profile) {
192   delete profile;
193 }
194
195 BrowserWindow* BrowserWithTestWindowTest::CreateBrowserWindow() {
196   return new TestBrowserWindow();
197 }