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 #include "chrome/test/base/ui_test_utils.h"
6
7 #if defined(OS_WIN)
8 #include <windows.h>
9 #endif
10
11 #include "base/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/callback.h"
14 #include "base/command_line.h"
15 #include "base/files/file_path.h"
16 #include "base/files/file_util.h"
17 #include "base/json/json_reader.h"
18 #include "base/memory/ref_counted.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/path_service.h"
21 #include "base/prefs/pref_service.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/test/test_timeouts.h"
25 #include "base/time/time.h"
26 #include "base/values.h"
27 #include "chrome/browser/autocomplete/autocomplete_controller.h"
28 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
29 #include "chrome/browser/browser_process.h"
30 #include "chrome/browser/chrome_notification_types.h"
31 #include "chrome/browser/extensions/extension_action.h"
32 #include "chrome/browser/history/history_service_factory.h"
33 #include "chrome/browser/profiles/profile.h"
34 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
35 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
36 #include "chrome/browser/ui/browser.h"
37 #include "chrome/browser/ui/browser_commands.h"
38 #include "chrome/browser/ui/browser_finder.h"
39 #include "chrome/browser/ui/browser_iterator.h"
40 #include "chrome/browser/ui/browser_list.h"
41 #include "chrome/browser/ui/browser_navigator.h"
42 #include "chrome/browser/ui/browser_window.h"
43 #include "chrome/browser/ui/find_bar/find_notification_details.h"
44 #include "chrome/browser/ui/find_bar/find_tab_helper.h"
45 #include "chrome/browser/ui/host_desktop.h"
46 #include "chrome/browser/ui/location_bar/location_bar.h"
47 #include "chrome/browser/ui/omnibox/omnibox_view.h"
48 #include "chrome/browser/ui/tabs/tab_strip_model.h"
49 #include "chrome/common/chrome_paths.h"
50 #include "chrome/common/pref_names.h"
51 #include "chrome/test/base/find_in_page_observer.h"
52 #include "components/bookmarks/browser/bookmark_model.h"
53 #include "components/search_engines/template_url_service.h"
54 #include "content/public/browser/dom_operation_notification_details.h"
55 #include "content/public/browser/download_item.h"
56 #include "content/public/browser/download_manager.h"
57 #include "content/public/browser/geolocation_provider.h"
58 #include "content/public/browser/navigation_controller.h"
59 #include "content/public/browser/navigation_entry.h"
60 #include "content/public/browser/notification_service.h"
61 #include "content/public/browser/render_process_host.h"
62 #include "content/public/browser/render_view_host.h"
63 #include "content/public/browser/web_contents.h"
64 #include "content/public/browser/web_contents_observer.h"
65 #include "content/public/common/geoposition.h"
66 #include "content/public/test/browser_test_utils.h"
67 #include "content/public/test/download_test_observer.h"
68 #include "content/public/test/test_navigation_observer.h"
69 #include "content/public/test/test_utils.h"
70 #include "net/base/filename_util.h"
71 #include "net/cookies/cookie_constants.h"
72 #include "net/cookies/cookie_monster.h"
73 #include "net/cookies/cookie_store.h"
74 #include "net/test/python_utils.h"
75 #include "net/url_request/url_request_context.h"
76 #include "net/url_request/url_request_context_getter.h"
77 #include "third_party/skia/include/core/SkBitmap.h"
78 #include "third_party/skia/include/core/SkColor.h"
79 #include "ui/gfx/size.h"
80 #include "ui/snapshot/test/snapshot_desktop.h"
81
82 #if defined(USE_AURA)
83 #include "ash/shell.h"
84 #include "ui/aura/window_event_dispatcher.h"
85 #endif
86
87 using content::DomOperationNotificationDetails;
88 using content::NativeWebKeyboardEvent;
89 using content::NavigationController;
90 using content::NavigationEntry;
91 using content::OpenURLParams;
92 using content::RenderViewHost;
93 using content::RenderWidgetHost;
94 using content::Referrer;
95 using content::WebContents;
96
97 namespace ui_test_utils {
98
99 namespace {
100
101 #if defined(OS_WIN)
102 const char kSnapshotBaseName[] = "ChromiumSnapshot";
103 const char kSnapshotExtension[] = ".png";
104
GetSnapshotFileName(const base::FilePath & snapshot_directory)105 base::FilePath GetSnapshotFileName(const base::FilePath& snapshot_directory) {
106 base::Time::Exploded the_time;
107
108 base::Time::Now().LocalExplode(&the_time);
109 std::string filename(base::StringPrintf("%s%04d%02d%02d%02d%02d%02d%s",
110 kSnapshotBaseName, the_time.year, the_time.month, the_time.day_of_month,
111 the_time.hour, the_time.minute, the_time.second, kSnapshotExtension));
112
113 base::FilePath snapshot_file = snapshot_directory.AppendASCII(filename);
114 if (base::PathExists(snapshot_file)) {
115 int index = 0;
116 std::string suffix;
117 base::FilePath trial_file;
118 do {
119 suffix = base::StringPrintf(" (%d)", ++index);
120 trial_file = snapshot_file.InsertBeforeExtensionASCII(suffix);
121 } while (base::PathExists(trial_file));
122 snapshot_file = trial_file;
123 }
124 return snapshot_file;
125 }
126 #endif // defined(OS_WIN)
127
WaitForBrowserNotInSet(std::set<Browser * > excluded_browsers)128 Browser* WaitForBrowserNotInSet(std::set<Browser*> excluded_browsers) {
129 Browser* new_browser = GetBrowserNotInSet(excluded_browsers);
130 if (new_browser == NULL) {
131 BrowserAddedObserver observer;
132 new_browser = observer.WaitForSingleNewBrowser();
133 // The new browser should never be in |excluded_browsers|.
134 DCHECK(!ContainsKey(excluded_browsers, new_browser));
135 }
136 return new_browser;
137 }
138
139 } // namespace
140
GetCurrentTabTitle(const Browser * browser,base::string16 * title)141 bool GetCurrentTabTitle(const Browser* browser, base::string16* title) {
142 WebContents* web_contents =
143 browser->tab_strip_model()->GetActiveWebContents();
144 if (!web_contents)
145 return false;
146 NavigationEntry* last_entry = web_contents->GetController().GetActiveEntry();
147 if (!last_entry)
148 return false;
149 title->assign(last_entry->GetTitleForDisplay(std::string()));
150 return true;
151 }
152
OpenURLOffTheRecord(Profile * profile,const GURL & url)153 Browser* OpenURLOffTheRecord(Profile* profile, const GURL& url) {
154 chrome::HostDesktopType active_desktop = chrome::GetActiveDesktop();
155 chrome::OpenURLOffTheRecord(profile, url, active_desktop);
156 Browser* browser = chrome::FindTabbedBrowser(
157 profile->GetOffTheRecordProfile(), false, active_desktop);
158 content::TestNavigationObserver observer(
159 browser->tab_strip_model()->GetActiveWebContents());
160 observer.Wait();
161 return browser;
162 }
163
NavigateToURL(chrome::NavigateParams * params)164 void NavigateToURL(chrome::NavigateParams* params) {
165 chrome::Navigate(params);
166 content::WaitForLoadStop(params->target_contents);
167 }
168
169
NavigateToURLWithPost(Browser * browser,const GURL & url)170 void NavigateToURLWithPost(Browser* browser, const GURL& url) {
171 chrome::NavigateParams params(browser, url,
172 ui::PAGE_TRANSITION_FORM_SUBMIT);
173 params.uses_post = true;
174 NavigateToURL(¶ms);
175 }
176
NavigateToURL(Browser * browser,const GURL & url)177 void NavigateToURL(Browser* browser, const GURL& url) {
178 NavigateToURLWithDisposition(browser, url, CURRENT_TAB,
179 BROWSER_TEST_WAIT_FOR_NAVIGATION);
180 }
181
182 // Navigates the specified tab (via |disposition|) of |browser| to |url|,
183 // blocking until the |number_of_navigations| specified complete.
184 // |disposition| indicates what tab the download occurs in, and
185 // |browser_test_flags| controls what to wait for before continuing.
NavigateToURLWithDispositionBlockUntilNavigationsComplete(Browser * browser,const GURL & url,int number_of_navigations,WindowOpenDisposition disposition,int browser_test_flags)186 static void NavigateToURLWithDispositionBlockUntilNavigationsComplete(
187 Browser* browser,
188 const GURL& url,
189 int number_of_navigations,
190 WindowOpenDisposition disposition,
191 int browser_test_flags) {
192 TabStripModel* tab_strip = browser->tab_strip_model();
193 if (disposition == CURRENT_TAB && tab_strip->GetActiveWebContents())
194 content::WaitForLoadStop(tab_strip->GetActiveWebContents());
195 content::TestNavigationObserver same_tab_observer(
196 tab_strip->GetActiveWebContents(),
197 number_of_navigations);
198
199 std::set<Browser*> initial_browsers;
200 for (chrome::BrowserIterator it; !it.done(); it.Next())
201 initial_browsers.insert(*it);
202
203 content::WindowedNotificationObserver tab_added_observer(
204 chrome::NOTIFICATION_TAB_ADDED,
205 content::NotificationService::AllSources());
206
207 browser->OpenURL(OpenURLParams(
208 url, Referrer(), disposition, ui::PAGE_TRANSITION_TYPED, false));
209 if (browser_test_flags & BROWSER_TEST_WAIT_FOR_BROWSER)
210 browser = WaitForBrowserNotInSet(initial_browsers);
211 if (browser_test_flags & BROWSER_TEST_WAIT_FOR_TAB)
212 tab_added_observer.Wait();
213 if (!(browser_test_flags & BROWSER_TEST_WAIT_FOR_NAVIGATION)) {
214 // Some other flag caused the wait prior to this.
215 return;
216 }
217 WebContents* web_contents = NULL;
218 if (disposition == NEW_BACKGROUND_TAB) {
219 // We've opened up a new tab, but not selected it.
220 TabStripModel* tab_strip = browser->tab_strip_model();
221 web_contents = tab_strip->GetWebContentsAt(tab_strip->active_index() + 1);
222 EXPECT_TRUE(web_contents != NULL)
223 << " Unable to wait for navigation to \"" << url.spec()
224 << "\" because the new tab is not available yet";
225 if (!web_contents)
226 return;
227 } else if ((disposition == CURRENT_TAB) ||
228 (disposition == NEW_FOREGROUND_TAB) ||
229 (disposition == SINGLETON_TAB)) {
230 // The currently selected tab is the right one.
231 web_contents = browser->tab_strip_model()->GetActiveWebContents();
232 }
233 if (disposition == CURRENT_TAB) {
234 same_tab_observer.Wait();
235 return;
236 } else if (web_contents) {
237 content::TestNavigationObserver observer(web_contents,
238 number_of_navigations);
239 observer.Wait();
240 return;
241 }
242 EXPECT_TRUE(NULL != web_contents) << " Unable to wait for navigation to \""
243 << url.spec() << "\""
244 << " because we can't get the tab contents";
245 }
246
NavigateToURLWithDisposition(Browser * browser,const GURL & url,WindowOpenDisposition disposition,int browser_test_flags)247 void NavigateToURLWithDisposition(Browser* browser,
248 const GURL& url,
249 WindowOpenDisposition disposition,
250 int browser_test_flags) {
251 NavigateToURLWithDispositionBlockUntilNavigationsComplete(
252 browser,
253 url,
254 1,
255 disposition,
256 browser_test_flags);
257 }
258
NavigateToURLBlockUntilNavigationsComplete(Browser * browser,const GURL & url,int number_of_navigations)259 void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
260 const GURL& url,
261 int number_of_navigations) {
262 NavigateToURLWithDispositionBlockUntilNavigationsComplete(
263 browser,
264 url,
265 number_of_navigations,
266 CURRENT_TAB,
267 BROWSER_TEST_WAIT_FOR_NAVIGATION);
268 }
269
GetTestFilePath(const base::FilePath & dir,const base::FilePath & file)270 base::FilePath GetTestFilePath(const base::FilePath& dir,
271 const base::FilePath& file) {
272 base::FilePath path;
273 PathService::Get(chrome::DIR_TEST_DATA, &path);
274 return path.Append(dir).Append(file);
275 }
276
GetTestUrl(const base::FilePath & dir,const base::FilePath & file)277 GURL GetTestUrl(const base::FilePath& dir, const base::FilePath& file) {
278 return net::FilePathToFileURL(GetTestFilePath(dir, file));
279 }
280
GetRelativeBuildDirectory(base::FilePath * build_dir)281 bool GetRelativeBuildDirectory(base::FilePath* build_dir) {
282 // This function is used to find the build directory so TestServer can serve
283 // built files (nexes, etc). TestServer expects a path relative to the source
284 // root.
285 base::FilePath exe_dir =
286 CommandLine::ForCurrentProcess()->GetProgram().DirName();
287 base::FilePath src_dir;
288 if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
289 return false;
290
291 // We must first generate absolute paths to SRC and EXE and from there
292 // generate a relative path.
293 if (!exe_dir.IsAbsolute())
294 exe_dir = base::MakeAbsoluteFilePath(exe_dir);
295 if (!src_dir.IsAbsolute())
296 src_dir = base::MakeAbsoluteFilePath(src_dir);
297 if (!exe_dir.IsAbsolute())
298 return false;
299 if (!src_dir.IsAbsolute())
300 return false;
301
302 size_t match, exe_size, src_size;
303 std::vector<base::FilePath::StringType> src_parts, exe_parts;
304
305 // Determine point at which src and exe diverge.
306 exe_dir.GetComponents(&exe_parts);
307 src_dir.GetComponents(&src_parts);
308 exe_size = exe_parts.size();
309 src_size = src_parts.size();
310 for (match = 0; match < exe_size && match < src_size; ++match) {
311 if (exe_parts[match] != src_parts[match])
312 break;
313 }
314
315 // Create a relative path.
316 *build_dir = base::FilePath();
317 for (size_t tmp_itr = match; tmp_itr < src_size; ++tmp_itr)
318 *build_dir = build_dir->Append(FILE_PATH_LITERAL(".."));
319 for (; match < exe_size; ++match)
320 *build_dir = build_dir->Append(exe_parts[match]);
321 return true;
322 }
323
WaitForAppModalDialog()324 AppModalDialog* WaitForAppModalDialog() {
325 AppModalDialogQueue* dialog_queue = AppModalDialogQueue::GetInstance();
326 if (dialog_queue->HasActiveDialog())
327 return dialog_queue->active_dialog();
328
329 content::WindowedNotificationObserver observer(
330 chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
331 content::NotificationService::AllSources());
332 observer.Wait();
333 return content::Source<AppModalDialog>(observer.source()).ptr();
334 }
335
FindInPage(WebContents * tab,const base::string16 & search_string,bool forward,bool match_case,int * ordinal,gfx::Rect * selection_rect)336 int FindInPage(WebContents* tab,
337 const base::string16& search_string,
338 bool forward,
339 bool match_case,
340 int* ordinal,
341 gfx::Rect* selection_rect) {
342 FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(tab);
343 find_tab_helper->StartFinding(search_string, forward, match_case);
344 FindInPageNotificationObserver observer(tab);
345 observer.Wait();
346 if (ordinal)
347 *ordinal = observer.active_match_ordinal();
348 if (selection_rect)
349 *selection_rect = observer.selection_rect();
350 return observer.number_of_matches();
351 }
352
WaitForTemplateURLServiceToLoad(TemplateURLService * service)353 void WaitForTemplateURLServiceToLoad(TemplateURLService* service) {
354 if (service->loaded())
355 return;
356 scoped_refptr<content::MessageLoopRunner> message_loop_runner =
357 new content::MessageLoopRunner;
358 scoped_ptr<TemplateURLService::Subscription> subscription =
359 service->RegisterOnLoadedCallback(
360 message_loop_runner->QuitClosure());
361 service->Load();
362 message_loop_runner->Run();
363
364 ASSERT_TRUE(service->loaded());
365 }
366
WaitForHistoryToLoad(HistoryService * history_service)367 void WaitForHistoryToLoad(HistoryService* history_service) {
368 content::WindowedNotificationObserver history_loaded_observer(
369 chrome::NOTIFICATION_HISTORY_LOADED,
370 content::NotificationService::AllSources());
371 if (!history_service->BackendLoaded())
372 history_loaded_observer.Wait();
373 }
374
DownloadURL(Browser * browser,const GURL & download_url)375 void DownloadURL(Browser* browser, const GURL& download_url) {
376 base::ScopedTempDir downloads_directory;
377 ASSERT_TRUE(downloads_directory.CreateUniqueTempDir());
378 browser->profile()->GetPrefs()->SetFilePath(
379 prefs::kDownloadDefaultDirectory, downloads_directory.path());
380
381 content::DownloadManager* download_manager =
382 content::BrowserContext::GetDownloadManager(browser->profile());
383 scoped_ptr<content::DownloadTestObserver> observer(
384 new content::DownloadTestObserverTerminal(
385 download_manager, 1,
386 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
387
388 ui_test_utils::NavigateToURL(browser, download_url);
389 observer->WaitForFinished();
390 }
391
SendToOmniboxAndSubmit(LocationBar * location_bar,const std::string & input)392 void SendToOmniboxAndSubmit(LocationBar* location_bar,
393 const std::string& input) {
394 OmniboxView* omnibox = location_bar->GetOmniboxView();
395 omnibox->model()->OnSetFocus(false);
396 omnibox->SetUserText(base::ASCIIToUTF16(input));
397 location_bar->AcceptInput();
398 while (!omnibox->model()->autocomplete_controller()->done()) {
399 content::WindowedNotificationObserver observer(
400 chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
401 content::NotificationService::AllSources());
402 observer.Wait();
403 }
404 }
405
GetBrowserNotInSet(std::set<Browser * > excluded_browsers)406 Browser* GetBrowserNotInSet(std::set<Browser*> excluded_browsers) {
407 for (chrome::BrowserIterator it; !it.done(); it.Next()) {
408 if (excluded_browsers.find(*it) == excluded_browsers.end())
409 return *it;
410 }
411 return NULL;
412 }
413
414 namespace {
415
GetCookiesCallback(base::WaitableEvent * event,std::string * cookies,const std::string & cookie_line)416 void GetCookiesCallback(base::WaitableEvent* event,
417 std::string* cookies,
418 const std::string& cookie_line) {
419 *cookies = cookie_line;
420 event->Signal();
421 }
422
GetCookiesOnIOThread(const GURL & url,const scoped_refptr<net::URLRequestContextGetter> & context_getter,base::WaitableEvent * event,std::string * cookies)423 void GetCookiesOnIOThread(
424 const GURL& url,
425 const scoped_refptr<net::URLRequestContextGetter>& context_getter,
426 base::WaitableEvent* event,
427 std::string* cookies) {
428 context_getter->GetURLRequestContext()->cookie_store()->
429 GetCookiesWithOptionsAsync(
430 url, net::CookieOptions(),
431 base::Bind(&GetCookiesCallback, event, cookies));
432 }
433
434 } // namespace
435
GetCookies(const GURL & url,WebContents * contents,int * value_size,std::string * value)436 void GetCookies(const GURL& url,
437 WebContents* contents,
438 int* value_size,
439 std::string* value) {
440 *value_size = -1;
441 if (url.is_valid() && contents) {
442 scoped_refptr<net::URLRequestContextGetter> context_getter =
443 contents->GetBrowserContext()->GetRequestContextForRenderProcess(
444 contents->GetRenderProcessHost()->GetID());
445 base::WaitableEvent event(true /* manual reset */,
446 false /* not initially signaled */);
447 CHECK(content::BrowserThread::PostTask(
448 content::BrowserThread::IO, FROM_HERE,
449 base::Bind(&GetCookiesOnIOThread, url, context_getter, &event, value)));
450 event.Wait();
451
452 *value_size = static_cast<int>(value->size());
453 }
454 }
455
WindowedTabAddedNotificationObserver(const content::NotificationSource & source)456 WindowedTabAddedNotificationObserver::WindowedTabAddedNotificationObserver(
457 const content::NotificationSource& source)
458 : WindowedNotificationObserver(chrome::NOTIFICATION_TAB_ADDED, source),
459 added_tab_(NULL) {
460 }
461
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)462 void WindowedTabAddedNotificationObserver::Observe(
463 int type,
464 const content::NotificationSource& source,
465 const content::NotificationDetails& details) {
466 added_tab_ = content::Details<WebContents>(details).ptr();
467 content::WindowedNotificationObserver::Observe(type, source, details);
468 }
469
UrlLoadObserver(const GURL & url,const content::NotificationSource & source)470 UrlLoadObserver::UrlLoadObserver(const GURL& url,
471 const content::NotificationSource& source)
472 : WindowedNotificationObserver(content::NOTIFICATION_LOAD_STOP, source),
473 url_(url) {
474 }
475
~UrlLoadObserver()476 UrlLoadObserver::~UrlLoadObserver() {}
477
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)478 void UrlLoadObserver::Observe(
479 int type,
480 const content::NotificationSource& source,
481 const content::NotificationDetails& details) {
482 NavigationController* controller =
483 content::Source<NavigationController>(source).ptr();
484 if (controller->GetWebContents()->GetURL() != url_)
485 return;
486
487 WindowedNotificationObserver::Observe(type, source, details);
488 }
489
BrowserAddedObserver()490 BrowserAddedObserver::BrowserAddedObserver()
491 : notification_observer_(
492 chrome::NOTIFICATION_BROWSER_OPENED,
493 content::NotificationService::AllSources()) {
494 for (chrome::BrowserIterator it; !it.done(); it.Next())
495 original_browsers_.insert(*it);
496 }
497
~BrowserAddedObserver()498 BrowserAddedObserver::~BrowserAddedObserver() {
499 }
500
WaitForSingleNewBrowser()501 Browser* BrowserAddedObserver::WaitForSingleNewBrowser() {
502 notification_observer_.Wait();
503 // Ensure that only a single new browser has appeared.
504 EXPECT_EQ(original_browsers_.size() + 1, chrome::GetTotalBrowserCount());
505 return GetBrowserNotInSet(original_browsers_);
506 }
507
508 #if defined(OS_WIN)
509
SaveScreenSnapshotToDirectory(const base::FilePath & directory,base::FilePath * screenshot_path)510 bool SaveScreenSnapshotToDirectory(const base::FilePath& directory,
511 base::FilePath* screenshot_path) {
512 bool succeeded = false;
513 base::FilePath out_path(GetSnapshotFileName(directory));
514
515 MONITORINFO monitor_info = {};
516 monitor_info.cbSize = sizeof(monitor_info);
517 HMONITOR main_monitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);
518 if (GetMonitorInfo(main_monitor, &monitor_info)) {
519 RECT& rect = monitor_info.rcMonitor;
520
521 std::vector<unsigned char> png_data;
522 gfx::Rect bounds(
523 gfx::Size(rect.right - rect.left, rect.bottom - rect.top));
524 if (ui::GrabDesktopSnapshot(bounds, &png_data) &&
525 png_data.size() <= INT_MAX) {
526 int bytes = static_cast<int>(png_data.size());
527 int written = base::WriteFile(
528 out_path, reinterpret_cast<char*>(&png_data[0]), bytes);
529 succeeded = (written == bytes);
530 }
531 }
532
533 if (succeeded && screenshot_path != NULL)
534 *screenshot_path = out_path;
535
536 return succeeded;
537 }
538
SaveScreenSnapshotToDesktop(base::FilePath * screenshot_path)539 bool SaveScreenSnapshotToDesktop(base::FilePath* screenshot_path) {
540 base::FilePath desktop;
541
542 return PathService::Get(base::DIR_USER_DESKTOP, &desktop) &&
543 SaveScreenSnapshotToDirectory(desktop, screenshot_path);
544 }
545
546 #endif // defined(OS_WIN)
547
OverrideGeolocation(double latitude,double longitude)548 void OverrideGeolocation(double latitude, double longitude) {
549 content::Geoposition position;
550 position.latitude = latitude;
551 position.longitude = longitude;
552 position.altitude = 0.;
553 position.accuracy = 0.;
554 position.timestamp = base::Time::Now();
555 content::GeolocationProvider::GetInstance()->OverrideLocationForTesting(
556 position);
557 }
558
HistoryEnumerator(Profile * profile)559 HistoryEnumerator::HistoryEnumerator(Profile* profile) {
560 scoped_refptr<content::MessageLoopRunner> message_loop_runner =
561 new content::MessageLoopRunner;
562
563 HistoryService* hs = HistoryServiceFactory::GetForProfile(
564 profile, Profile::EXPLICIT_ACCESS);
565 hs->QueryHistory(base::string16(),
566 history::QueryOptions(),
567 base::Bind(&HistoryEnumerator::HistoryQueryComplete,
568 base::Unretained(this),
569 message_loop_runner->QuitClosure()),
570 &tracker_);
571 message_loop_runner->Run();
572 }
573
~HistoryEnumerator()574 HistoryEnumerator::~HistoryEnumerator() {}
575
HistoryQueryComplete(const base::Closure & quit_task,history::QueryResults * results)576 void HistoryEnumerator::HistoryQueryComplete(
577 const base::Closure& quit_task,
578 history::QueryResults* results) {
579 for (size_t i = 0; i < results->size(); ++i)
580 urls_.push_back((*results)[i].url());
581 quit_task.Run();
582 }
583
584 } // namespace ui_test_utils
585