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_IN_PROCESS_BROWSER_TEST_H_
6#define CHROME_TEST_BASE_IN_PROCESS_BROWSER_TEST_H_
7
8#include "base/compiler_specific.h"
9#include "base/files/scoped_temp_dir.h"
10#include "base/memory/ref_counted.h"
11#include "base/memory/scoped_ptr.h"
12#include "content/public/common/page_transition_types.h"
13#include "content/public/test/browser_test.h"
14#include "content/public/test/browser_test_base.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17#if defined(OS_CHROMEOS)
18#include "chrome/browser/chromeos/cros/network_library.h"
19#endif  // defined(OS_CHROMEOS)
20
21namespace base {
22#if defined(OS_MACOSX)
23namespace mac {
24class ScopedNSAutoreleasePool;
25}  // namespace mac
26#endif  // defined(OS_MACOSX)
27
28#if defined(OS_WIN) && defined(USE_AURA)
29namespace win {
30class ScopedCOMInitializer;
31}
32#endif  // defined(OS_WIN) && defined(USE_AURA)
33}  // namespace base
34
35class Browser;
36class CommandLine;
37class Profile;
38
39namespace content {
40class ContentRendererClient;
41}
42
43namespace net {
44class RuleBasedHostResolverProc;
45}
46
47// Base class for tests wanting to bring up a browser in the unit test process.
48// Writing tests with InProcessBrowserTest is slightly different than that of
49// other tests. This is necessitated by InProcessBrowserTest running a message
50// loop. To use InProcessBrowserTest do the following:
51// . Use the macro IN_PROC_BROWSER_TEST_F to define your test.
52// . Your test method is invoked on the ui thread. If you need to block until
53//   state changes you'll need to run the message loop from your test method.
54//   For example, if you need to wait till a find bar has completely been shown
55//   you'll need to invoke content::RunMessageLoop. When the message bar is
56//   shown, invoke MessageLoop::current()->Quit() to return control back to your
57//   test method.
58// . If you subclass and override SetUp, be sure and invoke
59//   InProcessBrowserTest::SetUp. (But see also SetUpOnMainThread,
60//   SetUpInProcessBrowserTestFixture and other related hook methods for a
61//   cleaner alternative).
62//
63// Following three hook methods are called in sequence before calling
64// BrowserMain(), thus no browser has been created yet. They are mainly for
65// setting up the environment for running the browser.
66// . SetUpUserDataDirectory()
67// . SetUpCommandLine()
68// . SetUpInProcessBrowserTestFixture()
69//
70// SetUpOnMainThread() is called just after creating the default browser object
71// and before executing the real test code. It's mainly for setting up things
72// related to the browser object and associated window, like opening a new Tab
73// with a testing page loaded.
74//
75// CleanUpOnMainThread() is called just after executing the real test code to
76// do necessary cleanup before the browser is torn down.
77//
78// TearDownInProcessBrowserTestFixture() is called after BrowserMain() exits to
79// cleanup things setup for running the browser.
80//
81// By default InProcessBrowserTest creates a single Browser (as returned from
82// the CreateBrowser method). You can obviously create more as needed.
83
84// InProcessBrowserTest disables the sandbox when running.
85//
86// See ui_test_utils for a handful of methods designed for use with this class.
87//
88// It's possible to write browser tests that span a restart by splitting each
89// run of the browser process into a separate test. Example:
90//
91// IN_PROC_BROWSER_TEST_F(Foo, PRE_Bar) {
92//   do something
93// }
94//
95// IN_PROC_BROWSER_TEST_F(Foo, Bar) {
96//   verify something persisted from before
97// }
98//
99//  This is recursive, so PRE_PRE_Bar would run before PRE_BAR.
100class InProcessBrowserTest : public content::BrowserTestBase {
101 public:
102  InProcessBrowserTest();
103  virtual ~InProcessBrowserTest();
104
105  // Configures everything for an in process browser test, then invokes
106  // BrowserMain. BrowserMain ends up invoking RunTestOnMainThreadLoop.
107  virtual void SetUp() OVERRIDE;
108
109  // Restores state configured in SetUp.
110  virtual void TearDown() OVERRIDE;
111
112 protected:
113  // Returns the browser created by CreateBrowser.
114  Browser* browser() const { return browser_; }
115
116  // Convenience methods for adding tabs to a Browser.
117  void AddTabAtIndexToBrowser(Browser* browser,
118                              int index,
119                              const GURL& url,
120                              content::PageTransition transition);
121  void AddTabAtIndex(int index, const GURL& url,
122                     content::PageTransition transition);
123
124  // Initializes the contents of the user data directory. Called by SetUp()
125  // after creating the user data directory, but before any browser is launched.
126  // If a test wishes to set up some initial non-empty state in the user data
127  // directory before the browser starts up, it can do so here. Returns true if
128  // successful.
129  virtual bool SetUpUserDataDirectory() WARN_UNUSED_RESULT;
130
131  // Override this to add any custom cleanup code that needs to be done on the
132  // main thread before the browser is torn down.
133  virtual void CleanUpOnMainThread() {}
134
135  // BrowserTestBase:
136  virtual void RunTestOnMainThreadLoop() OVERRIDE;
137
138  // Creates a browser with a single tab (about:blank), waits for the tab to
139  // finish loading and shows the browser.
140  //
141  // This is invoked from Setup.
142  Browser* CreateBrowser(Profile* profile);
143
144  // Similar to |CreateBrowser|, but creates an incognito browser.
145  Browser* CreateIncognitoBrowser();
146
147  // Creates a browser for a popup window with a single tab (about:blank), waits
148  // for the tab to finish loading, and shows the browser.
149  Browser* CreateBrowserForPopup(Profile* profile);
150
151  // Creates a browser for an application and waits for it to load and shows
152  // the browser.
153  Browser* CreateBrowserForApp(const std::string& app_name, Profile* profile);
154
155  // Called from the various CreateBrowser methods to add a blank tab, wait for
156  // the navigation to complete, and show the browser's window.
157  void AddBlankTabAndShow(Browser* browser);
158
159#if !defined OS_MACOSX
160  // Return a CommandLine object that is used to relaunch the browser_test
161  // binary as a browser process. This function is deliberately not defined on
162  // the Mac because re-using an existing browser process when launching from
163  // the command line isn't a concept that we support on the Mac; AppleEvents
164  // are the Mac solution for the same need. Any test based on these functions
165  // doesn't apply to the Mac.
166  CommandLine GetCommandLineForRelaunch();
167#endif
168
169  // Returns the host resolver being used for the tests. Subclasses might want
170  // to configure it inside tests.
171  net::RuleBasedHostResolverProc* host_resolver() {
172    return host_resolver_.get();
173  }
174
175#if defined(OS_MACOSX)
176  // Returns the autorelease pool in use inside RunTestOnMainThreadLoop().
177  base::mac::ScopedNSAutoreleasePool* AutoreleasePool() const {
178    return autorelease_pool_;
179  }
180#endif  // OS_MACOSX
181
182  void set_exit_when_last_browser_closes(bool value) {
183    exit_when_last_browser_closes_ = value;
184  }
185
186  // This must be called before RunTestOnMainThreadLoop() to have any effect.
187  void set_multi_desktop_test(bool multi_desktop_test) {
188    multi_desktop_test_ = multi_desktop_test;
189  }
190
191 private:
192  // Creates a user data directory for the test if one is needed. Returns true
193  // if successful.
194  virtual bool CreateUserDataDirectory() WARN_UNUSED_RESULT;
195
196  // Quits all open browsers and waits until there are no more browsers.
197  void QuitBrowsers();
198
199  // Prepare command line that will be used to launch the child browser process
200  // with an in-process test.
201  void PrepareTestCommandLine(CommandLine* command_line);
202
203  // Browser created from CreateBrowser.
204  Browser* browser_;
205
206  // Host resolver to use during the test.
207  scoped_refptr<net::RuleBasedHostResolverProc> host_resolver_;
208
209  // Temporary user data directory. Used only when a user data directory is not
210  // specified in the command line.
211  base::ScopedTempDir temp_user_data_dir_;
212
213  // True if we should exit the tests after the last browser instance closes.
214  bool exit_when_last_browser_closes_;
215
216  // True if this is a multi-desktop test (in which case this browser test will
217  // not ensure that Browsers are only created on the tested desktop).
218  bool multi_desktop_test_;
219
220#if defined(OS_CHROMEOS)
221  chromeos::ScopedStubNetworkLibraryEnabler stub_network_library_enabler_;
222#endif  // defined(OS_CHROMEOS)
223
224#if defined(OS_MACOSX)
225  base::mac::ScopedNSAutoreleasePool* autorelease_pool_;
226#endif  // OS_MACOSX
227
228#if defined(OS_WIN) && defined(USE_AURA)
229  scoped_ptr<base::win::ScopedCOMInitializer> com_initializer_;
230#endif
231};
232
233#endif  // CHROME_TEST_BASE_IN_PROCESS_BROWSER_TEST_H_
234