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_WEB_UI_BROWSERTEST_H_
      6 #define CHROME_TEST_BASE_WEB_UI_BROWSERTEST_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/files/file_path.h"
     12 #include "base/memory/scoped_vector.h"
     13 #include "base/strings/string16.h"
     14 #include "chrome/test/base/in_process_browser_test.h"
     15 #include "content/public/test/js_injection_ready_observer.h"
     16 
     17 namespace base {
     18 class Value;
     19 }
     20 
     21 namespace content {
     22 class RenderViewHost;
     23 class WebUI;
     24 class WebUIMessageHandler;
     25 }
     26 
     27 class TestChromeWebUIControllerFactory;
     28 class WebUITestHandler;
     29 
     30 // This macro simplifies the declaration of simple javascript unit tests.
     31 // Use:
     32 //   WEB_UI_UNITTEST_F(MyWebUIPageTest, myJavascriptUnittest);
     33 #define WEB_UI_UNITTEST_F(x, y) \
     34   IN_PROC_BROWSER_TEST_F(x, y) { \
     35     ASSERT_TRUE(RunJavascriptTest(#y)); \
     36   }
     37 
     38 // The runner of WebUI javascript based tests.
     39 // See chrome/test/data/webui/test_api.js for the javascript side test API's.
     40 //
     41 // These tests should follow the form given in:
     42 // chrome/test/data/webui/sample_downloads.js.
     43 // and the lone test within this class.
     44 class WebUIBrowserTest
     45     : public InProcessBrowserTest,
     46       public content::JsInjectionReadyObserver {
     47  public:
     48   typedef ScopedVector<const base::Value> ConstValueVector;
     49   virtual ~WebUIBrowserTest();
     50 
     51   // Add a custom helper JS library for your test.
     52   // If a relative path is specified, it'll be read
     53   // as relative to the test data dir.
     54   void AddLibrary(const base::FilePath& library_path);
     55 
     56   // Runs a javascript function in the context of all libraries.
     57   // Note that calls to functions in test_api.js are not supported.
     58   // Takes ownership of Value* arguments.
     59   bool RunJavascriptFunction(const std::string& function_name);
     60   bool RunJavascriptFunction(const std::string& function_name,
     61                              base::Value* arg);
     62   bool RunJavascriptFunction(const std::string& function_name,
     63                              base::Value* arg1,
     64                              base::Value* arg2);
     65   bool RunJavascriptFunction(const std::string& function_name,
     66                              const ConstValueVector& function_arguments);
     67 
     68   // Runs a test fixture that may include calls to functions in test_api.js.
     69   bool RunJavascriptTestF(bool is_async,
     70                           const std::string& test_fixture,
     71                           const std::string& test_name);
     72 
     73   // Runs a test that may include calls to functions in test_api.js.
     74   // Takes ownership of Value* arguments.
     75   bool RunJavascriptTest(const std::string& test_name);
     76   bool RunJavascriptTest(const std::string& test_name,
     77                          base::Value* arg);
     78   bool RunJavascriptTest(const std::string& test_name,
     79                          base::Value* arg1,
     80                          base::Value* arg2);
     81   bool RunJavascriptTest(const std::string& test_name,
     82                          const ConstValueVector& test_arguments);
     83 
     84   // Runs a test that may include calls to functions in test_api.js, and waits
     85   // for call to testDone().  Takes ownership of Value* arguments.
     86   bool RunJavascriptAsyncTest(const std::string& test_name);
     87   bool RunJavascriptAsyncTest(const std::string& test_name,
     88                               base::Value* arg);
     89   bool RunJavascriptAsyncTest(const std::string& test_name,
     90                               base::Value* arg1,
     91                               base::Value* arg2);
     92   bool RunJavascriptAsyncTest(const std::string& test_name,
     93                               base::Value* arg1,
     94                               base::Value* arg2,
     95                               base::Value* arg3);
     96   bool RunJavascriptAsyncTest(const std::string& test_name,
     97                               const ConstValueVector& test_arguments);
     98 
     99   // Sends message through |preload_host| to preload javascript libraries and
    100   // sets the |libraries_preloaded| flag to prevent re-loading at next
    101   // javascript invocation.
    102   void PreLoadJavascriptLibraries(const std::string& preload_test_fixture,
    103                                   const std::string& preload_test_name,
    104                                   content::RenderViewHost* preload_host);
    105 
    106   // Called by javascript-generated test bodies to browse to a page and preload
    107   // the javascript for the given |preload_test_fixture| and
    108   // |preload_test_name|. chrome.send will be overridden to allow javascript
    109   // handler mocking.
    110   void BrowsePreload(const GURL& browse_to);
    111 
    112   // Called by javascript-generated test bodies to browse to a page and preload
    113   // the javascript for the given |preload_test_fixture| and
    114   // |preload_test_name|. chrome.send will be overridden to allow javascript
    115   // handler mocking.
    116   void BrowsePrintPreload(const GURL& browse_to);
    117 
    118  protected:
    119   // URL to dummy WebUI page for testing framework.
    120   static const char kDummyURL[];
    121 
    122   WebUIBrowserTest();
    123 
    124   // Accessors for preload test fixture and name.
    125   void set_preload_test_fixture(const std::string& preload_test_fixture);
    126   void set_preload_test_name(const std::string& preload_test_name);
    127 
    128   // Set up & tear down console error catching.
    129   virtual void SetUpOnMainThread() OVERRIDE;
    130   virtual void CleanUpOnMainThread() OVERRIDE;
    131 
    132   // Set a WebUI instance to run tests on.
    133   void SetWebUIInstance(content::WebUI* web_ui);
    134 
    135   // Returns a mock WebUI object under test (if any).
    136   virtual content::WebUIMessageHandler* GetMockMessageHandler();
    137 
    138   // Returns a file:// GURL constructed from |path| inside the test data dir for
    139   // webui tests.
    140   static GURL WebUITestDataPathToURL(const base::FilePath::StringType& path);
    141 
    142  private:
    143   // content::JsInjectionReadyObserver implementation.
    144   virtual void OnJsInjectionReady(
    145       content::RenderViewHost* render_view_host) OVERRIDE;
    146 
    147   // Builds a string containing all added javascript libraries.
    148   void BuildJavascriptLibraries(string16* content);
    149 
    150   // Builds a string with a call to the runTest JS function, passing the
    151   // given |is_async|, |test_name| and its |args|.
    152   string16 BuildRunTestJSCall(bool is_async,
    153                               const std::string& test_name,
    154                               const WebUIBrowserTest::ConstValueVector& args);
    155 
    156   // Loads all libraries added with AddLibrary(), and calls |function_name| with
    157   // |function_arguments|. When |is_test| is true, the framework wraps
    158   // |function_name| with a test helper function, which waits for completion,
    159   // logging an error message on failure, otherwise |function_name| is called
    160   // asynchronously. When |preload_host| is non-NULL, sends the javascript to
    161   // the RenderView for evaluation at the appropriate time before the onload
    162   // call is made. Passes |is_async| along to runTest wrapper.
    163   bool RunJavascriptUsingHandler(const std::string& function_name,
    164                                  const ConstValueVector& function_arguments,
    165                                  bool is_test,
    166                                  bool is_async,
    167                                  content::RenderViewHost* preload_host);
    168 
    169   // Attaches mock and test handlers.
    170   void SetupHandlers();
    171 
    172   // Handles test framework messages.
    173   scoped_ptr<WebUITestHandler> test_handler_;
    174 
    175   // Location of test data (currently test/data/webui).
    176   base::FilePath test_data_directory_;
    177 
    178   // Location of generated test data (<(PROGRAM_DIR)/test_data).
    179   base::FilePath gen_test_data_directory_;
    180 
    181   // User added libraries
    182   std::vector<base::FilePath> user_libraries_;
    183 
    184   // Indicates that the libraries have been pre-loaded and to not load them
    185   // again.
    186   bool libraries_preloaded_;
    187 
    188   // Saves the states of |test_fixture| and |test_name| for calling
    189   // PreloadJavascriptLibraries().
    190   std::string preload_test_fixture_;
    191   std::string preload_test_name_;
    192 
    193   // When this is non-NULL, this is The WebUI instance used for testing.
    194   // Otherwise the selected tab's web_ui is used.
    195   content::WebUI* override_selected_web_ui_;
    196 
    197   scoped_ptr<TestChromeWebUIControllerFactory> test_factory_;
    198 };
    199 
    200 #endif  // CHROME_TEST_BASE_WEB_UI_BROWSERTEST_H_
    201