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_UI_TEST_UTILS_H_
      6 #define CHROME_TEST_BASE_UI_TEST_UTILS_H_
      7 
      8 #include <map>
      9 #include <queue>
     10 #include <set>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/basictypes.h"
     15 #include "base/memory/ref_counted.h"
     16 #include "base/strings/string16.h"
     17 #include "chrome/browser/history/history_service.h"
     18 #include "content/public/browser/notification_details.h"
     19 #include "content/public/browser/notification_observer.h"
     20 #include "content/public/browser/notification_registrar.h"
     21 #include "content/public/browser/notification_source.h"
     22 #include "content/public/test/test_utils.h"
     23 #include "testing/gtest/include/gtest/gtest.h"
     24 #include "ui/base/window_open_disposition.h"
     25 #include "ui/events/keycodes/keyboard_codes.h"
     26 #include "ui/gfx/native_widget_types.h"
     27 #include "url/gurl.h"
     28 
     29 class AppModalDialog;
     30 class Browser;
     31 class DevToolsWindow;
     32 class LocationBar;
     33 class Profile;
     34 class SkBitmap;
     35 class TemplateURLService;
     36 
     37 namespace base {
     38 class FilePath;
     39 }
     40 
     41 namespace chrome {
     42 struct NavigateParams;
     43 }
     44 
     45 namespace content {
     46 class MessageLoopRunner;
     47 class RenderViewHost;
     48 class RenderWidgetHost;
     49 class WebContents;
     50 }
     51 
     52 namespace gfx {
     53 class Rect;
     54 class Size;
     55 }
     56 
     57 // A collections of functions designed for use with InProcessBrowserTest.
     58 namespace ui_test_utils {
     59 
     60 // Flags to indicate what to wait for in a navigation test.
     61 // They can be ORed together.
     62 // The order in which the waits happen when more than one is selected, is:
     63 //    Browser
     64 //    Tab
     65 //    Navigation
     66 enum BrowserTestWaitFlags {
     67   BROWSER_TEST_NONE = 0,                      // Don't wait for anything.
     68   BROWSER_TEST_WAIT_FOR_BROWSER = 1 << 0,     // Wait for a new browser.
     69   BROWSER_TEST_WAIT_FOR_TAB = 1 << 1,         // Wait for a new tab.
     70   BROWSER_TEST_WAIT_FOR_NAVIGATION = 1 << 2,  // Wait for navigation to finish.
     71 
     72   BROWSER_TEST_MASK = BROWSER_TEST_WAIT_FOR_BROWSER |
     73                       BROWSER_TEST_WAIT_FOR_TAB |
     74                       BROWSER_TEST_WAIT_FOR_NAVIGATION
     75 };
     76 
     77 // Puts the current tab title in |title|. Returns true on success.
     78 bool GetCurrentTabTitle(const Browser* browser, base::string16* title);
     79 
     80 // Opens |url| in an incognito browser window with the incognito profile of
     81 // |profile|, blocking until the navigation finishes. This will create a new
     82 // browser if a browser with the incognito profile does not exist. Returns the
     83 // incognito window Browser.
     84 Browser* OpenURLOffTheRecord(Profile* profile, const GURL& url);
     85 
     86 // Performs the provided navigation process, blocking until the navigation
     87 // finishes. May change the params in some cases (i.e. if the navigation
     88 // opens a new browser window). Uses chrome::Navigate.
     89 void NavigateToURL(chrome::NavigateParams* params);
     90 
     91 // Navigates the selected tab of |browser| to |url|, blocking until the
     92 // navigation finishes. Simulates a POST and uses chrome::Navigate.
     93 void NavigateToURLWithPost(Browser* browser, const GURL& url);
     94 
     95 // Navigates the selected tab of |browser| to |url|, blocking until the
     96 // navigation finishes. Uses Browser::OpenURL --> chrome::Navigate.
     97 void NavigateToURL(Browser* browser, const GURL& url);
     98 
     99 // Navigates the specified tab of |browser| to |url|, blocking until the
    100 // navigation finishes.
    101 // |disposition| indicates what tab the navigation occurs in, and
    102 // |browser_test_flags| controls what to wait for before continuing.
    103 void NavigateToURLWithDisposition(Browser* browser,
    104                                   const GURL& url,
    105                                   WindowOpenDisposition disposition,
    106                                   int browser_test_flags);
    107 
    108 // Navigates the selected tab of |browser| to |url|, blocking until the
    109 // number of navigations specified complete.
    110 void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
    111                                                 const GURL& url,
    112                                                 int number_of_navigations);
    113 
    114 // Blocks until DevTools window is loaded.
    115 void WaitUntilDevToolsWindowLoaded(DevToolsWindow* window);
    116 
    117 // Generate the file path for testing a particular test.
    118 // The file for the tests is all located in
    119 // test_root_directory/dir/<file>
    120 // The returned path is base::FilePath format.
    121 base::FilePath GetTestFilePath(const base::FilePath& dir,
    122                                const base::FilePath& file);
    123 
    124 // Generate the URL for testing a particular test.
    125 // HTML for the tests is all located in
    126 // test_root_directory/dir/<file>
    127 // The returned path is GURL format.
    128 GURL GetTestUrl(const base::FilePath& dir, const base::FilePath& file);
    129 
    130 // Generate the path of the build directory, relative to the source root.
    131 bool GetRelativeBuildDirectory(base::FilePath* build_dir);
    132 
    133 // Blocks until an application modal dialog is showns and returns it.
    134 AppModalDialog* WaitForAppModalDialog();
    135 
    136 // Performs a find in the page of the specified tab. Returns the number of
    137 // matches found.  |ordinal| is an optional parameter which is set to the index
    138 // of the current match. |selection_rect| is an optional parameter which is set
    139 // to the location of the current match.
    140 int FindInPage(content::WebContents* tab,
    141                const base::string16& search_string,
    142                bool forward,
    143                bool case_sensitive,
    144                int* ordinal,
    145                gfx::Rect* selection_rect);
    146 
    147 // Blocks until |service| finishes loading.
    148 void WaitForTemplateURLServiceToLoad(TemplateURLService* service);
    149 
    150 // Blocks until the |history_service|'s history finishes loading.
    151 void WaitForHistoryToLoad(HistoryService* history_service);
    152 
    153 // Download the given file and waits for the download to complete.
    154 void DownloadURL(Browser* browser, const GURL& download_url);
    155 
    156 // Send the given text to the omnibox and wait until it's updated.
    157 void SendToOmniboxAndSubmit(LocationBar* location_bar,
    158                             const std::string& input);
    159 
    160 // Gets the first browser that is not in the specified set.
    161 Browser* GetBrowserNotInSet(std::set<Browser*> excluded_browsers);
    162 
    163 // Gets the size and value of the cookie string for |url| in the given tab.
    164 // Can be called from any thread.
    165 void GetCookies(const GURL& url,
    166                 content::WebContents* contents,
    167                 int* value_size,
    168                 std::string* value);
    169 
    170 // A WindowedNotificationObserver hard-wired to observe
    171 // chrome::NOTIFICATION_TAB_ADDED.
    172 class WindowedTabAddedNotificationObserver
    173     : public content::WindowedNotificationObserver {
    174  public:
    175   // Register to listen for notifications of NOTIFICATION_TAB_ADDED from either
    176   // a specific source, or from all sources if |source| is
    177   // NotificationService::AllSources().
    178   explicit WindowedTabAddedNotificationObserver(
    179       const content::NotificationSource& source);
    180 
    181   // Returns the added tab, or NULL if no notification was observed yet.
    182   content::WebContents* GetTab() { return added_tab_; }
    183 
    184   virtual void Observe(int type,
    185                        const content::NotificationSource& source,
    186                        const content::NotificationDetails& details) OVERRIDE;
    187 
    188  private:
    189   content::WebContents* added_tab_;
    190 
    191   DISALLOW_COPY_AND_ASSIGN(WindowedTabAddedNotificationObserver);
    192 };
    193 
    194 // Similar to WindowedNotificationObserver but also provides a way of retrieving
    195 // the details associated with the notification.
    196 // Note that in order to use that class the details class should be copiable,
    197 // which is the case with most notifications.
    198 template <class U>
    199 class WindowedNotificationObserverWithDetails
    200     : public content::WindowedNotificationObserver {
    201  public:
    202   WindowedNotificationObserverWithDetails(
    203       int notification_type,
    204       const content::NotificationSource& source)
    205       : content::WindowedNotificationObserver(notification_type, source) {}
    206 
    207   // Fills |details| with the details of the notification received for |source|.
    208   bool GetDetailsFor(uintptr_t source, U* details) {
    209     typename std::map<uintptr_t, U>::const_iterator iter =
    210         details_.find(source);
    211     if (iter == details_.end())
    212       return false;
    213     *details = iter->second;
    214     return true;
    215   }
    216 
    217   virtual void Observe(int type,
    218                        const content::NotificationSource& source,
    219                        const content::NotificationDetails& details) OVERRIDE {
    220     const U* details_ptr = content::Details<U>(details).ptr();
    221     if (details_ptr)
    222       details_[source.map_key()] = *details_ptr;
    223     content::WindowedNotificationObserver::Observe(type, source, details);
    224   }
    225 
    226  private:
    227   std::map<uintptr_t, U> details_;
    228 
    229   DISALLOW_COPY_AND_ASSIGN(WindowedNotificationObserverWithDetails);
    230 };
    231 
    232 // Notification observer which waits for navigation events and blocks until
    233 // a specific URL is loaded. The URL must be an exact match.
    234 class UrlLoadObserver : public content::WindowedNotificationObserver {
    235  public:
    236   // Register to listen for notifications of the given type from either a
    237   // specific source, or from all sources if |source| is
    238   // NotificationService::AllSources().
    239   UrlLoadObserver(const GURL& url, const content::NotificationSource& source);
    240   virtual ~UrlLoadObserver();
    241 
    242   // content::NotificationObserver:
    243   virtual void Observe(int type,
    244                        const content::NotificationSource& source,
    245                        const content::NotificationDetails& details) OVERRIDE;
    246 
    247  private:
    248   GURL url_;
    249 
    250   DISALLOW_COPY_AND_ASSIGN(UrlLoadObserver);
    251 };
    252 
    253 // Convenience class for waiting for a new browser to be created.
    254 // Like WindowedNotificationObserver, this class provides a safe, non-racey
    255 // way to wait for a new browser to be created.
    256 class BrowserAddedObserver {
    257  public:
    258   BrowserAddedObserver();
    259   ~BrowserAddedObserver();
    260 
    261   // Wait for a new browser to be created, and return a pointer to it.
    262   Browser* WaitForSingleNewBrowser();
    263 
    264  private:
    265   content::WindowedNotificationObserver notification_observer_;
    266   std::set<Browser*> original_browsers_;
    267 
    268   DISALLOW_COPY_AND_ASSIGN(BrowserAddedObserver);
    269 };
    270 
    271 // Takes a snapshot of the entire page, according to the width and height
    272 // properties of the DOM's document. Returns true on success. DOMAutomation
    273 // must be enabled.
    274 bool TakeEntirePageSnapshot(content::RenderViewHost* rvh,
    275                             SkBitmap* bitmap) WARN_UNUSED_RESULT;
    276 
    277 #if defined(OS_WIN)
    278 // Saves a snapshot of the entire screen to a file named
    279 // ChromiumSnapshotYYYYMMDDHHMMSS.png to |directory|, returning true on success.
    280 // The path to the file produced is returned in |screenshot_path| if non-NULL.
    281 bool SaveScreenSnapshotToDirectory(const base::FilePath& directory,
    282                                    base::FilePath* screenshot_path);
    283 
    284 // Saves a snapshot of the entire screen as above to the current user's desktop.
    285 // The Chrome path provider must be registered prior to calling this function.
    286 bool SaveScreenSnapshotToDesktop(base::FilePath* screenshot_path);
    287 #endif
    288 
    289 // Configures the geolocation provider to always return the given position.
    290 void OverrideGeolocation(double latitude, double longitude);
    291 
    292 // Enumerates all history contents on the backend thread. Returns them in
    293 // descending order by time.
    294 class HistoryEnumerator {
    295  public:
    296   explicit HistoryEnumerator(Profile* profile);
    297   ~HistoryEnumerator();
    298 
    299   std::vector<GURL>& urls() { return urls_; }
    300 
    301  private:
    302   void HistoryQueryComplete(
    303       const base::Closure& quit_task,
    304       HistoryService::Handle request_handle,
    305       history::QueryResults* results);
    306 
    307   std::vector<GURL> urls_;
    308 
    309   CancelableRequestConsumer consumer_;
    310 
    311   DISALLOW_COPY_AND_ASSIGN(HistoryEnumerator);
    312 };
    313 
    314 }  // namespace ui_test_utils
    315 
    316 #endif  // CHROME_TEST_BASE_UI_TEST_UTILS_H_
    317