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