• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
GetTab()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:
WindowedNotificationObserverWithDetails(int notification_type,const content::NotificationSource & source)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|.
GetDetailsFor(uintptr_t source,U * details)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 
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)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 
urls()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