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 LocationBar;
     32 class Profile;
     33 class SkBitmap;
     34 class TemplateURLService;
     35 
     36 namespace base {
     37 class FilePath;
     38 }
     39 
     40 namespace chrome {
     41 struct NavigateParams;
     42 }
     43 
     44 namespace content {
     45 class MessageLoopRunner;
     46 class RenderViewHost;
     47 class RenderWidgetHost;
     48 class WebContents;
     49 }
     50 
     51 namespace gfx {
     52 class Rect;
     53 class Size;
     54 }
     55 
     56 // A collections of functions designed for use with InProcessBrowserTest.
     57 namespace ui_test_utils {
     58 
     59 // Flags to indicate what to wait for in a navigation test.
     60 // They can be ORed together.
     61 // The order in which the waits happen when more than one is selected, is:
     62 //    Browser
     63 //    Tab
     64 //    Navigation
     65 enum BrowserTestWaitFlags {
     66   BROWSER_TEST_NONE = 0,                      // Don't wait for anything.
     67   BROWSER_TEST_WAIT_FOR_BROWSER = 1 << 0,     // Wait for a new browser.
     68   BROWSER_TEST_WAIT_FOR_TAB = 1 << 1,         // Wait for a new tab.
     69   BROWSER_TEST_WAIT_FOR_NAVIGATION = 1 << 2,  // Wait for navigation to finish.
     70 
     71   BROWSER_TEST_MASK = BROWSER_TEST_WAIT_FOR_BROWSER |
     72                       BROWSER_TEST_WAIT_FOR_TAB |
     73                       BROWSER_TEST_WAIT_FOR_NAVIGATION
     74 };
     75 
     76 // Puts the current tab title in |title|. Returns true on success.
     77 bool GetCurrentTabTitle(const Browser* browser, base::string16* title);
     78 
     79 // Opens |url| in an incognito browser window with the incognito profile of
     80 // |profile|, blocking until the navigation finishes. This will create a new
     81 // browser if a browser with the incognito profile does not exist. Returns the
     82 // incognito window Browser.
     83 Browser* OpenURLOffTheRecord(Profile* profile, const GURL& url);
     84 
     85 // Performs the provided navigation process, blocking until the navigation
     86 // finishes. May change the params in some cases (i.e. if the navigation
     87 // opens a new browser window). Uses chrome::Navigate.
     88 void NavigateToURL(chrome::NavigateParams* params);
     89 
     90 // Navigates the selected tab of |browser| to |url|, blocking until the
     91 // navigation finishes. Simulates a POST and uses chrome::Navigate.
     92 void NavigateToURLWithPost(Browser* browser, const GURL& url);
     93 
     94 // Navigates the selected tab of |browser| to |url|, blocking until the
     95 // navigation finishes. Uses Browser::OpenURL --> chrome::Navigate.
     96 void NavigateToURL(Browser* browser, const GURL& url);
     97 
     98 // Navigates the specified tab of |browser| to |url|, blocking until the
     99 // navigation finishes.
    100 // |disposition| indicates what tab the navigation occurs in, and
    101 // |browser_test_flags| controls what to wait for before continuing.
    102 void NavigateToURLWithDisposition(Browser* browser,
    103                                   const GURL& url,
    104                                   WindowOpenDisposition disposition,
    105                                   int browser_test_flags);
    106 
    107 // Navigates the selected tab of |browser| to |url|, blocking until the
    108 // number of navigations specified complete.
    109 void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
    110                                                 const GURL& url,
    111                                                 int number_of_navigations);
    112 
    113 // Generate the file path for testing a particular test.
    114 // The file for the tests is all located in
    115 // test_root_directory/dir/<file>
    116 // The returned path is base::FilePath format.
    117 base::FilePath GetTestFilePath(const base::FilePath& dir,
    118                                const base::FilePath& file);
    119 
    120 // Generate the URL for testing a particular test.
    121 // HTML for the tests is all located in
    122 // test_root_directory/dir/<file>
    123 // The returned path is GURL format.
    124 GURL GetTestUrl(const base::FilePath& dir, const base::FilePath& file);
    125 
    126 // Generate the path of the build directory, relative to the source root.
    127 bool GetRelativeBuildDirectory(base::FilePath* build_dir);
    128 
    129 // Blocks until an application modal dialog is showns and returns it.
    130 AppModalDialog* WaitForAppModalDialog();
    131 
    132 // Performs a find in the page of the specified tab. Returns the number of
    133 // matches found.  |ordinal| is an optional parameter which is set to the index
    134 // of the current match. |selection_rect| is an optional parameter which is set
    135 // to the location of the current match.
    136 int FindInPage(content::WebContents* tab,
    137                const base::string16& search_string,
    138                bool forward,
    139                bool case_sensitive,
    140                int* ordinal,
    141                gfx::Rect* selection_rect);
    142 
    143 // Blocks until |service| finishes loading.
    144 void WaitForTemplateURLServiceToLoad(TemplateURLService* service);
    145 
    146 // Blocks until the |history_service|'s history finishes loading.
    147 void WaitForHistoryToLoad(HistoryService* history_service);
    148 
    149 // Download the given file and waits for the download to complete.
    150 void DownloadURL(Browser* browser, const GURL& download_url);
    151 
    152 // Send the given text to the omnibox and wait until it's updated.
    153 void SendToOmniboxAndSubmit(LocationBar* location_bar,
    154                             const std::string& input);
    155 
    156 // Gets the first browser that is not in the specified set.
    157 Browser* GetBrowserNotInSet(std::set<Browser*> excluded_browsers);
    158 
    159 // Gets the size and value of the cookie string for |url| in the given tab.
    160 // Can be called from any thread.
    161 void GetCookies(const GURL& url,
    162                 content::WebContents* contents,
    163                 int* value_size,
    164                 std::string* value);
    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 entire page, according to the width and height
    268 // properties of the DOM's document. Returns true on success. DOMAutomation
    269 // must be enabled.
    270 bool TakeEntirePageSnapshot(content::RenderViewHost* rvh,
    271                             SkBitmap* bitmap) WARN_UNUSED_RESULT;
    272 
    273 #if defined(OS_WIN)
    274 // Saves a snapshot of the entire screen to a file named
    275 // ChromiumSnapshotYYYYMMDDHHMMSS.png to |directory|, returning true on success.
    276 // The path to the file produced is returned in |screenshot_path| if non-NULL.
    277 bool SaveScreenSnapshotToDirectory(const base::FilePath& directory,
    278                                    base::FilePath* screenshot_path);
    279 
    280 // Saves a snapshot of the entire screen as above to the current user's desktop.
    281 // The Chrome path provider must be registered prior to calling this function.
    282 bool SaveScreenSnapshotToDesktop(base::FilePath* screenshot_path);
    283 #endif
    284 
    285 // Configures the geolocation provider to always return the given position.
    286 void OverrideGeolocation(double latitude, double longitude);
    287 
    288 // Enumerates all history contents on the backend thread. Returns them in
    289 // descending order by time.
    290 class HistoryEnumerator {
    291  public:
    292   explicit HistoryEnumerator(Profile* profile);
    293   ~HistoryEnumerator();
    294 
    295   std::vector<GURL>& urls() { return urls_; }
    296 
    297  private:
    298   void HistoryQueryComplete(
    299       const base::Closure& quit_task,
    300       history::QueryResults* results);
    301 
    302   std::vector<GURL> urls_;
    303 
    304   base::CancelableTaskTracker tracker_;
    305 
    306   DISALLOW_COPY_AND_ASSIGN(HistoryEnumerator);
    307 };
    308 
    309 }  // namespace ui_test_utils
    310 
    311 #endif  // CHROME_TEST_BASE_UI_TEST_UTILS_H_
    312