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#ifndef CHROME_TEST_BASE_BROWSER_WITH_TEST_WINDOW_TEST_H_
6#define CHROME_TEST_BASE_BROWSER_WITH_TEST_WINDOW_TEST_H_
7
8#include "base/at_exit.h"
9#include "base/message_loop/message_loop.h"
10#include "chrome/browser/ui/browser.h"
11#include "chrome/browser/ui/host_desktop.h"
12#include "chrome/test/base/test_browser_window.h"
13#include "chrome/test/base/testing_profile.h"
14#include "content/public/test/test_browser_thread_bundle.h"
15#include "content/public/test/test_renderer_host.h"
16#include "testing/gtest/include/gtest/gtest.h"
17
18#if defined(OS_CHROMEOS)
19#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
20#include "chrome/browser/chromeos/settings/cros_settings.h"
21#include "chrome/browser/chromeos/settings/device_settings_service.h"
22#endif
23
24#if defined(OS_WIN)
25#include "ui/base/win/scoped_ole_initializer.h"
26#endif
27
28class GURL;
29
30#if defined(USE_ASH)
31namespace ash {
32namespace test {
33class AshTestHelper;
34}
35}
36#endif
37
38#if defined(USE_AURA)
39namespace aura {
40namespace test {
41class AuraTestHelper;
42}
43}
44#endif
45
46#if defined(TOOLKIT_VIEWS)
47namespace views {
48class ViewsDelegate;
49}
50#endif
51
52namespace content {
53class NavigationController;
54class WebContents;
55}
56
57// Base class for browser based unit tests. BrowserWithTestWindowTest creates a
58// Browser with a TestingProfile and TestBrowserWindow. To add a tab use
59// AddTab. For example, the following adds a tab and navigates to
60// two URLs that target the TestWebContents:
61//
62//   // Add a new tab and navigate it. This will be at index 0.
63//   AddTab(browser(), GURL("http://foo/1"));
64//   NavigationController* controller =
65//       &browser()->tab_strip_model()->GetWebContentsAt(0)->GetController();
66//
67//   // Navigate somewhere else.
68//   GURL url2("http://foo/2");
69//   NavigateAndCommit(controller, url2);
70//
71//   // This is equivalent to the above, and lets you test pending navigations.
72//   browser()->OpenURL(OpenURLParams(
73//       GURL("http://foo/2"), GURL(), CURRENT_TAB,
74//       ui::PAGE_TRANSITION_TYPED, false));
75//   CommitPendingLoad(controller);
76//
77// Subclasses must invoke BrowserWithTestWindowTest::SetUp as it is responsible
78// for creating the various objects of this class.
79class BrowserWithTestWindowTest : public testing::Test {
80 public:
81  // Creates a BrowserWithTestWindowTest for which the initial window will be
82  // a tabbed browser created on the native desktop, which is not a hosted app.
83  BrowserWithTestWindowTest();
84
85  // Creates a BrowserWithTestWindowTest for which the initial window will be
86  // the specified type.
87  BrowserWithTestWindowTest(Browser::Type browser_type,
88                            chrome::HostDesktopType host_desktop_type,
89                            bool hosted_app);
90
91  virtual ~BrowserWithTestWindowTest();
92
93  virtual void SetUp() OVERRIDE;
94  virtual void TearDown() OVERRIDE;
95
96 protected:
97  BrowserWindow* window() const { return window_.get(); }
98
99  Browser* browser() const { return browser_.get(); }
100  void set_browser(Browser* browser) {
101    browser_.reset(browser);
102  }
103  Browser* release_browser() WARN_UNUSED_RESULT {
104    return browser_.release();
105  }
106
107  TestingProfile* profile() const { return profile_; }
108
109  TestingProfile* GetProfile() { return profile_; }
110
111  BrowserWindow* release_browser_window() WARN_UNUSED_RESULT {
112    return window_.release();
113  }
114
115  // Adds a tab to |browser| with the given URL and commits the load.
116  // This is a convenience function. The new tab will be added at index 0.
117  void AddTab(Browser* browser, const GURL& url);
118
119  // Commits the pending load on the given controller. It will keep the
120  // URL of the pending load. If there is no pending load, this does nothing.
121  void CommitPendingLoad(content::NavigationController* controller);
122
123  // Creates a pending navigation on the given navigation controller to the
124  // given URL with the default parameters and the commits the load with a page
125  // ID one larger than any seen. This emulates what happens on a new
126  // navigation.
127  void NavigateAndCommit(content::NavigationController* controller,
128                         const GURL& url);
129
130  // Navigates the current tab. This is a wrapper around NavigateAndCommit.
131  void NavigateAndCommitActiveTab(const GURL& url);
132
133  // Set the |title| of the current tab.
134  void NavigateAndCommitActiveTabWithTitle(Browser* browser,
135                                           const GURL& url,
136                                           const base::string16& title);
137
138  // Destroys the browser, window, and profile created by this class. This is
139  // invoked from the destructor.
140  void DestroyBrowserAndProfile();
141
142  // Creates the profile used by this test. The caller owns the return value.
143  virtual TestingProfile* CreateProfile();
144
145  // Destroys the profile which was created through |CreateProfile|.
146  virtual void DestroyProfile(TestingProfile* profile);
147
148  // Creates the BrowserWindow used by this test. The caller owns the return
149  // value. Can return NULL to use the default window created by Browser.
150  virtual BrowserWindow* CreateBrowserWindow();
151
152  // Creates the browser given |profile|, |browser_type|, |hosted_app|,
153  // |host_desktop_type| and |browser_window|. The caller owns the return value.
154  virtual Browser* CreateBrowser(Profile* profile,
155                                 Browser::Type browser_type,
156                                 bool hosted_app,
157                                 chrome::HostDesktopType host_desktop_type,
158                                 BrowserWindow* browser_window);
159
160 private:
161#if !defined(OS_CHROMEOS) && defined(TOOLKIT_VIEWS)
162  // Creates the ViewsDelegate to use, may be overriden to create a different
163  // ViewsDelegate.
164  views::ViewsDelegate* CreateViewsDelegate();
165#endif
166
167  // We need to create a MessageLoop, otherwise a bunch of things fails.
168  content::TestBrowserThreadBundle thread_bundle_;
169  base::ShadowingAtExitManager at_exit_manager_;
170
171#if defined(OS_CHROMEOS)
172  chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
173  chromeos::ScopedTestCrosSettings test_cros_settings_;
174  chromeos::ScopedTestUserManager test_user_manager_;
175#endif
176
177  // The profile will automatically be destroyed by TearDown using the
178  // |DestroyProfile()| function - which can be overwritten by derived testing
179  // frameworks.
180  TestingProfile* profile_;
181  scoped_ptr<BrowserWindow> window_;  // Usually a TestBrowserWindow.
182  scoped_ptr<Browser> browser_;
183
184  // The existence of this object enables tests via
185  // RenderViewHostTester.
186  content::RenderViewHostTestEnabler rvh_test_enabler_;
187
188#if defined(USE_ASH)
189  scoped_ptr<ash::test::AshTestHelper> ash_test_helper_;
190#endif
191#if defined(USE_AURA)
192  scoped_ptr<aura::test::AuraTestHelper> aura_test_helper_;
193#endif
194
195#if defined(TOOLKIT_VIEWS)
196  scoped_ptr<views::ViewsDelegate> views_delegate_;
197#endif
198
199#if defined(OS_WIN)
200  ui::ScopedOleInitializer ole_initializer_;
201#endif
202
203  // The type of browser to create (tabbed or popup).
204  Browser::Type browser_type_;
205
206  // The desktop to create the initial window on.
207  chrome::HostDesktopType host_desktop_type_;
208
209  // Whether the browser is part of a hosted app.
210  bool hosted_app_;
211
212  DISALLOW_COPY_AND_ASSIGN(BrowserWithTestWindowTest);
213};
214
215#endif  // CHROME_TEST_BASE_BROWSER_WITH_TEST_WINDOW_TEST_H_
216