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/keycodes/keyboard_codes.h"
     25 #include "ui/base/window_open_disposition.h"
     26 #include "ui/gfx/native_widget_types.h"
     27 #include "url/gurl.h"
     28 
     29 class AppModalDialog;
     30 class BookmarkModel;
     31 class Browser;
     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, 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. Uses Browser::OpenURL --> chrome::Navigate.
     93 void NavigateToURL(Browser* browser, const GURL& url);
     94 
     95 // Navigates the specified tab of |browser| to |url|, blocking until the
     96 // navigation finishes.
     97 // |disposition| indicates what tab the navigation occurs in, and
     98 // |browser_test_flags| controls what to wait for before continuing.
     99 void NavigateToURLWithDisposition(Browser* browser,
    100                                   const GURL& url,
    101                                   WindowOpenDisposition disposition,
    102                                   int browser_test_flags);
    103 
    104 // Navigates the selected tab of |browser| to |url|, blocking until the
    105 // number of navigations specified complete.
    106 void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
    107                                                 const GURL& url,
    108                                                 int number_of_navigations);
    109 
    110 // Generate the file path for testing a particular test.
    111 // The file for the tests is all located in
    112 // test_root_directory/dir/<file>
    113 // The returned path is base::FilePath format.
    114 base::FilePath GetTestFilePath(const base::FilePath& dir,
    115                                const base::FilePath& file);
    116 
    117 // Generate the URL for testing a particular test.
    118 // HTML for the tests is all located in
    119 // test_root_directory/dir/<file>
    120 // The returned path is GURL format.
    121 GURL GetTestUrl(const base::FilePath& dir, const base::FilePath& file);
    122 
    123 // Generate the path of the build directory, relative to the source root.
    124 bool GetRelativeBuildDirectory(base::FilePath* build_dir);
    125 
    126 // Blocks until an application modal dialog is showns and returns it.
    127 AppModalDialog* WaitForAppModalDialog();
    128 
    129 // Performs a find in the page of the specified tab. Returns the number of
    130 // matches found.  |ordinal| is an optional parameter which is set to the index
    131 // of the current match. |selection_rect| is an optional parameter which is set
    132 // to the location of the current match.
    133 int FindInPage(content::WebContents* tab,
    134                const string16& search_string,
    135                bool forward,
    136                bool case_sensitive,
    137                int* ordinal,
    138                gfx::Rect* selection_rect);
    139 
    140 // Register |observer| for the given |type| and |source| and run
    141 // the message loop until the observer posts a quit task.
    142 void RegisterAndWait(content::NotificationObserver* observer,
    143                      int type,
    144                      const content::NotificationSource& source);
    145 
    146 // Blocks until |model| finishes loading.
    147 void WaitForBookmarkModelToLoad(BookmarkModel* model);
    148 void WaitForBookmarkModelToLoad(Profile* profile);
    149 
    150 // Blocks until |service| finishes loading.
    151 void WaitForTemplateURLServiceToLoad(TemplateURLService* service);
    152 
    153 // Blocks until the |history_service|'s history finishes loading.
    154 void WaitForHistoryToLoad(HistoryService* history_service);
    155 
    156 // Download the given file and waits for the download to complete.
    157 void DownloadURL(Browser* browser, const GURL& download_url);
    158 
    159 // Send the given text to the omnibox and wait until it's updated.
    160 void SendToOmniboxAndSubmit(LocationBar* location_bar,
    161                             const std::string& input);
    162 
    163 // Gets the first browser that is not in the specified set.
    164 Browser* GetBrowserNotInSet(std::set<Browser*> excluded_browsers);
    165 
    166 // A WindowedNotificationObserver hard-wired to observe
    167 // chrome::NOTIFICATION_TAB_ADDED.
    168 class WindowedTabAddedNotificationObserver
    169     : public content::WindowedNotificationObserver {
    170  public:
    171   // Register to listen for notifications of NOTIFICATION_TAB_ADDED from either
    172   // a specific source, or from all sources if |source| is
    173   // NotificationService::AllSources().
    174   explicit WindowedTabAddedNotificationObserver(
    175       const content::NotificationSource& source);
    176 
    177   // Returns the added tab, or NULL if no notification was observed yet.
    178   content::WebContents* GetTab() { return added_tab_; }
    179 
    180   virtual void Observe(int type,
    181                        const content::NotificationSource& source,
    182                        const content::NotificationDetails& details) OVERRIDE;
    183 
    184  private:
    185   content::WebContents* added_tab_;
    186 
    187   DISALLOW_COPY_AND_ASSIGN(WindowedTabAddedNotificationObserver);
    188 };
    189 
    190 // Similar to WindowedNotificationObserver but also provides a way of retrieving
    191 // the details associated with the notification.
    192 // Note that in order to use that class the details class should be copiable,
    193 // which is the case with most notifications.
    194 template <class U>
    195 class WindowedNotificationObserverWithDetails
    196     : public content::WindowedNotificationObserver {
    197  public:
    198   WindowedNotificationObserverWithDetails(
    199       int notification_type,
    200       const content::NotificationSource& source)
    201       : content::WindowedNotificationObserver(notification_type, source) {}
    202 
    203   // Fills |details| with the details of the notification received for |source|.
    204   bool GetDetailsFor(uintptr_t source, U* details) {
    205     typename std::map<uintptr_t, U>::const_iterator iter =
    206         details_.find(source);
    207     if (iter == details_.end())
    208       return false;
    209     *details = iter->second;
    210     return true;
    211   }
    212 
    213   virtual void Observe(int type,
    214                        const content::NotificationSource& source,
    215                        const content::NotificationDetails& details) OVERRIDE {
    216     const U* details_ptr = content::Details<U>(details).ptr();
    217     if (details_ptr)
    218       details_[source.map_key()] = *details_ptr;
    219     content::WindowedNotificationObserver::Observe(type, source, details);
    220   }
    221 
    222  private:
    223   std::map<uintptr_t, U> details_;
    224 
    225   DISALLOW_COPY_AND_ASSIGN(WindowedNotificationObserverWithDetails);
    226 };
    227 
    228 // Notification observer which waits for navigation events and blocks until
    229 // a specific URL is loaded. The URL must be an exact match.
    230 class UrlLoadObserver : public content::WindowedNotificationObserver {
    231  public:
    232   // Register to listen for notifications of the given type from either a
    233   // specific source, or from all sources if |source| is
    234   // NotificationService::AllSources().
    235   UrlLoadObserver(const GURL& url, const content::NotificationSource& source);
    236   virtual ~UrlLoadObserver();
    237 
    238   // content::NotificationObserver:
    239   virtual void Observe(int type,
    240                        const content::NotificationSource& source,
    241                        const content::NotificationDetails& details) OVERRIDE;
    242 
    243  private:
    244   GURL url_;
    245 
    246   DISALLOW_COPY_AND_ASSIGN(UrlLoadObserver);
    247 };
    248 
    249 // Convenience class for waiting for a new browser to be created.
    250 // Like WindowedNotificationObserver, this class provides a safe, non-racey
    251 // way to wait for a new browser to be created.
    252 class BrowserAddedObserver {
    253  public:
    254   BrowserAddedObserver();
    255   ~BrowserAddedObserver();
    256 
    257   // Wait for a new browser to be created, and return a pointer to it.
    258   Browser* WaitForSingleNewBrowser();
    259 
    260  private:
    261   content::WindowedNotificationObserver notification_observer_;
    262   std::set<Browser*> original_browsers_;
    263 
    264   DISALLOW_COPY_AND_ASSIGN(BrowserAddedObserver);
    265 };
    266 
    267 // Takes a snapshot of the given render widget, rendered at |page_size|. The
    268 // snapshot is set to |bitmap|. Returns true on success.
    269 bool TakeRenderWidgetSnapshot(content::RenderWidgetHost* rwh,
    270                               const gfx::Size& page_size,
    271                               SkBitmap* bitmap) WARN_UNUSED_RESULT;
    272 
    273 // Takes a snapshot of the entire page, according to the width and height
    274 // properties of the DOM's document. Returns true on success. DOMAutomation
    275 // must be enabled.
    276 bool TakeEntirePageSnapshot(content::RenderViewHost* rvh,
    277                             SkBitmap* bitmap) WARN_UNUSED_RESULT;
    278 
    279 #if defined(OS_WIN)
    280 // Saves a snapshot of the entire screen to a file named
    281 // ChromiumSnapshotYYYYMMDDHHMMSS.png to |directory|, returning true on success.
    282 // The path to the file produced is returned in |screenshot_path| if non-NULL.
    283 bool SaveScreenSnapshotToDirectory(const base::FilePath& directory,
    284                                    base::FilePath* screenshot_path);
    285 
    286 // Saves a snapshot of the entire screen as above to the current user's desktop.
    287 // The Chrome path provider must be registered prior to calling this function.
    288 bool SaveScreenSnapshotToDesktop(base::FilePath* screenshot_path);
    289 #endif
    290 
    291 // Configures the geolocation provider to always return the given position.
    292 void OverrideGeolocation(double latitude, double longitude);
    293 
    294 // Enumerates all history contents on the backend thread. Returns them in
    295 // descending order by time.
    296 class HistoryEnumerator {
    297  public:
    298   explicit HistoryEnumerator(Profile* profile);
    299   ~HistoryEnumerator();
    300 
    301   std::vector<GURL>& urls() { return urls_; }
    302 
    303  private:
    304   void HistoryQueryComplete(
    305       const base::Closure& quit_task,
    306       HistoryService::Handle request_handle,
    307       history::QueryResults* results);
    308 
    309   std::vector<GURL> urls_;
    310 
    311   CancelableRequestConsumer consumer_;
    312 
    313   DISALLOW_COPY_AND_ASSIGN(HistoryEnumerator);
    314 };
    315 
    316 }  // namespace ui_test_utils
    317 
    318 #endif  // CHROME_TEST_BASE_UI_TEST_UTILS_H_
    319