ui_test_utils.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_reader.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/message_loop.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/time.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_controller.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_service_factory.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service_test_util.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/thumbnails/render_widget_snapshot_taker.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_iterator.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_list.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_navigator.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_notification_details.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/find_bar/find_tab_helper.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/location_bar.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_view.h"
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_notification_types.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/bookmark_load_observer.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/dom_operation_notification_details.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_item.h"
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/download_manager.h"
58b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/public/browser/geolocation_provider.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_controller.h"
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/navigation_entry.h"
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h"
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_observer.h"
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/geoposition.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/download_test_observer.h"
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_navigation_observer.h"
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/test_utils.h"
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/test/python_utils.h"
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkColor.h"
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/snapshot/test/snapshot_desktop.h"
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_AURA)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ash/shell.h"
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/aura/root_window.h"
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DomOperationNotificationDetails;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NativeWebKeyboardEvent;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationEntry;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::OpenURLParams;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderWidgetHost;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::Referrer;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui_test_utils {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FindInPageNotificationObserver : public content::NotificationObserver {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit FindInPageNotificationObserver(WebContents* parent_tab)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : active_match_ordinal_(-1),
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        number_of_matches_(0) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FindTabHelper* find_tab_helper =
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FindTabHelper::FromWebContents(parent_tab);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current_find_request_id_ = find_tab_helper->current_find_request_id();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    registrar_.Add(this, chrome::NOTIFICATION_FIND_RESULT_AVAILABLE,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   content::Source<WebContents>(parent_tab));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_ = new content::MessageLoopRunner;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Run();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_match_ordinal() const { return active_match_ordinal_; }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int number_of_matches() const { return number_of_matches_; }
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect selection_rect() const { return selection_rect_; }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Observe(int type, const content::NotificationSource& source,
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const content::NotificationDetails& details) OVERRIDE {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == chrome::NOTIFICATION_FIND_RESULT_AVAILABLE) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Details<FindNotificationDetails> find_details(details);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (find_details->request_id() == current_find_request_id_) {
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // We get multiple responses and one of those will contain the ordinal.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // This message comes to us before the final update is sent.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (find_details->active_match_ordinal() > -1) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          active_match_ordinal_ = find_details->active_match_ordinal();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          selection_rect_ = find_details->selection_rect();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (find_details->final_update()) {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          number_of_matches_ = find_details->number_of_matches();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          message_loop_runner_->Quit();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          DVLOG(1) << "Ignoring, since we only care about the final message";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We will at some point (before final update) be notified of the ordinal and
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we need to preserve it so we can send it later.
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_match_ordinal_;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int number_of_matches_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect selection_rect_;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The id of the current find request, obtained from WebContents. Allows us
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to monitor when the search completes.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int current_find_request_id_;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FindInPageNotificationObserver);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kSnapshotBaseName[] = "ChromiumSnapshot";
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kSnapshotExtension[] = ".png";
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetSnapshotFileName(const base::FilePath& snapshot_directory) {
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time::Exploded the_time;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::Time::Now().LocalExplode(&the_time);
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string filename(base::StringPrintf("%s%04d%02d%02d%02d%02d%02d%s",
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSnapshotBaseName, the_time.year, the_time.month, the_time.day_of_month,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      the_time.hour, the_time.minute, the_time.second, kSnapshotExtension));
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath snapshot_file = snapshot_directory.AppendASCII(filename);
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (file_util::PathExists(snapshot_file)) {
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int index = 0;
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::string suffix;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath trial_file;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    do {
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      suffix = base::StringPrintf(" (%d)", ++index);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      trial_file = snapshot_file.InsertBeforeExtensionASCII(suffix);
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } while (file_util::PathExists(trial_file));
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    snapshot_file = trial_file;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return snapshot_file;
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetCurrentTabTitle(const Browser* browser, string16* title) {
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WebContents* web_contents =
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser->tab_strip_model()->GetActiveWebContents();
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!web_contents)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationEntry* last_entry = web_contents->GetController().GetActiveEntry();
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!last_entry)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
190c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  title->assign(last_entry->GetTitleForDisplay(std::string()));
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitForNavigations(NavigationController* controller,
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        int number_of_navigations) {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestNavigationObserver observer(
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::Source<NavigationController>(controller),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      number_of_navigations);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::RunLoop run_loop;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.WaitForObservation(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::GetQuitTaskForRunLoop(&run_loop));
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* WaitForBrowserNotInSet(std::set<Browser*> excluded_browsers) {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* new_browser = GetBrowserNotInSet(excluded_browsers);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (new_browser == NULL) {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserAddedObserver observer;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    new_browser = observer.WaitForSingleNewBrowser();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The new browser should never be in |excluded_browsers|.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(!ContainsKey(excluded_browsers, new_browser));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new_browser;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* OpenURLOffTheRecord(Profile* profile, const GURL& url) {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::OpenURLOffTheRecord(profile, url, chrome::HOST_DESKTOP_TYPE_NATIVE);
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser = chrome::FindTabbedBrowser(
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile->GetOffTheRecordProfile(),
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::HOST_DESKTOP_TYPE_NATIVE);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForNavigations(
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &browser->tab_strip_model()->GetActiveWebContents()->GetController(),
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      1);
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return browser;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigateToURL(chrome::NavigateParams* params) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestNavigationObserver observer(
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::NotificationService::AllSources(), 1);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome::Navigate(params);
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::RunLoop run_loop;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.WaitForObservation(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)),
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::GetQuitTaskForRunLoop(&run_loop));
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigateToURL(Browser* browser, const GURL& url) {
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToURLWithDisposition(browser, url, CURRENT_TAB,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               BROWSER_TEST_WAIT_FOR_NAVIGATION);
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Navigates the specified tab (via |disposition|) of |browser| to |url|,
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// blocking until the |number_of_navigations| specified complete.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |disposition| indicates what tab the download occurs in, and
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |browser_test_flags| controls what to wait for before continuing.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void NavigateToURLWithDispositionBlockUntilNavigationsComplete(
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Browser* browser,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int number_of_navigations,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WindowOpenDisposition disposition,
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int browser_test_flags) {
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabStripModel* tab_strip = browser->tab_strip_model();
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (disposition == CURRENT_TAB && tab_strip->GetActiveWebContents())
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      content::WaitForLoadStop(tab_strip->GetActiveWebContents());
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController* controller =
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      tab_strip->GetActiveWebContents() ?
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &tab_strip->GetActiveWebContents()->GetController() : NULL;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::TestNavigationObserver same_tab_observer(
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(controller),
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      number_of_navigations);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::set<Browser*> initial_browsers;
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next())
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    initial_browsers.insert(*it);
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver tab_added_observer(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_TAB_ADDED,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->OpenURL(OpenURLParams(
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url, Referrer(), disposition, content::PAGE_TRANSITION_TYPED, false));
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser_test_flags & BROWSER_TEST_WAIT_FOR_BROWSER)
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser = WaitForBrowserNotInSet(initial_browsers);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser_test_flags & BROWSER_TEST_WAIT_FOR_TAB)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_added_observer.Wait();
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!(browser_test_flags & BROWSER_TEST_WAIT_FOR_NAVIGATION)) {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Some other flag caused the wait prior to this.
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WebContents* web_contents = NULL;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (disposition == NEW_BACKGROUND_TAB) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We've opened up a new tab, but not selected it.
2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TabStripModel* tab_strip = browser->tab_strip_model();
2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_contents = tab_strip->GetWebContentsAt(tab_strip->active_index() + 1);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(web_contents != NULL)
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << " Unable to wait for navigation to \"" << url.spec()
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << "\" because the new tab is not available yet";
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!web_contents)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if ((disposition == CURRENT_TAB) ||
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (disposition == NEW_FOREGROUND_TAB) ||
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (disposition == SINGLETON_TAB)) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The currently selected tab is the right one.
2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    web_contents = browser->tab_strip_model()->GetActiveWebContents();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (disposition == CURRENT_TAB) {
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::RunLoop run_loop;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    same_tab_observer.WaitForObservation(
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)),
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::GetQuitTaskForRunLoop(&run_loop));
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (web_contents) {
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NavigationController* controller = &web_contents->GetController();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    WaitForNavigations(controller, number_of_navigations);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(NULL != web_contents) << " Unable to wait for navigation to \""
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    << url.spec() << "\""
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    << " because we can't get the tab contents";
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigateToURLWithDisposition(Browser* browser,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const GURL& url,
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  WindowOpenDisposition disposition,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  int browser_test_flags) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToURLWithDispositionBlockUntilNavigationsComplete(
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url,
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      1,
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      disposition,
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser_test_flags);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NavigateToURLBlockUntilNavigationsComplete(Browser* browser,
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                const GURL& url,
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                int number_of_navigations) {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToURLWithDispositionBlockUntilNavigationsComplete(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      number_of_navigations,
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CURRENT_TAB,
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      BROWSER_TEST_WAIT_FOR_NAVIGATION);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::FilePath GetTestFilePath(const base::FilePath& dir,
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               const base::FilePath& file) {
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_TEST_DATA, &path);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return path.Append(dir).Append(file);
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)GURL GetTestUrl(const base::FilePath& dir, const base::FilePath& file) {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return net::FilePathToFileURL(GetTestFilePath(dir, file));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool GetRelativeBuildDirectory(base::FilePath* build_dir) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This function is used to find the build directory so TestServer can serve
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // built files (nexes, etc).  TestServer expects a path relative to the source
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // root.
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath exe_dir =
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      CommandLine::ForCurrentProcess()->GetProgram().DirName();
3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath src_dir;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We must first generate absolute paths to SRC and EXE and from there
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // generate a relative path.
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!exe_dir.IsAbsolute())
360c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    exe_dir = base::MakeAbsoluteFilePath(exe_dir);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!src_dir.IsAbsolute())
362c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    src_dir = base::MakeAbsoluteFilePath(src_dir);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!exe_dir.IsAbsolute())
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!src_dir.IsAbsolute())
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t match, exe_size, src_size;
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<base::FilePath::StringType> src_parts, exe_parts;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Determine point at which src and exe diverge.
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exe_dir.GetComponents(&exe_parts);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  src_dir.GetComponents(&src_parts);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  exe_size = exe_parts.size();
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  src_size = src_parts.size();
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (match = 0; match < exe_size && match < src_size; ++match) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (exe_parts[match] != src_parts[match])
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a relative path.
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  *build_dir = base::FilePath();
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t tmp_itr = match; tmp_itr < src_size; ++tmp_itr)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *build_dir = build_dir->Append(FILE_PATH_LITERAL(".."));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; match < exe_size; ++match)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *build_dir = build_dir->Append(exe_parts[match]);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppModalDialog* WaitForAppModalDialog() {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver observer(
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer.Wait();
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return content::Source<AppModalDialog>(observer.source()).ptr();
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int FindInPage(WebContents* tab, const string16& search_string,
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               bool forward, bool match_case, int* ordinal,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               gfx::Rect* selection_rect) {
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindTabHelper* find_tab_helper = FindTabHelper::FromWebContents(tab);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  find_tab_helper->StartFinding(search_string, forward, match_case);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FindInPageNotificationObserver observer(tab);
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ordinal)
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *ordinal = observer.active_match_ordinal();
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selection_rect)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *selection_rect = observer.selection_rect();
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return observer.number_of_matches();
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RegisterAndWait(content::NotificationObserver* observer,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     int type,
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     const content::NotificationSource& source) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::NotificationRegistrar registrar;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  registrar.Add(observer, type, source);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RunMessageLoop();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitForBookmarkModelToLoad(BookmarkModel* model) {
420b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  if (model->loaded())
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::RunLoop run_loop;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkLoadObserver observer(content::GetQuitTaskForRunLoop(&run_loop));
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model->AddObserver(&observer);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::RunThisRunLoop(&run_loop);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  model->RemoveObserver(&observer);
427b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  ASSERT_TRUE(model->loaded());
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void WaitForBookmarkModelToLoad(Profile* profile) {
4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  WaitForBookmarkModelToLoad(BookmarkModelFactory::GetForProfile(profile));
4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitForTemplateURLServiceToLoad(TemplateURLService* service) {
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (service->loaded())
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service->Load();
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLServiceTestUtil::BlockTillServiceProcessesRequests();
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(service->loaded());
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WaitForHistoryToLoad(HistoryService* history_service) {
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver history_loaded_observer(
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_HISTORY_LOADED,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!history_service->BackendLoaded())
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history_loaded_observer.Wait();
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DownloadURL(Browser* browser, const GURL& download_url) {
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::ScopedTempDir downloads_directory;
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(downloads_directory.CreateUniqueTempDir());
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser->profile()->GetPrefs()->SetFilePath(
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      prefs::kDownloadDefaultDirectory, downloads_directory.path());
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::DownloadManager* download_manager =
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::BrowserContext::GetDownloadManager(browser->profile());
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<content::DownloadTestObserver> observer(
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new content::DownloadTestObserverTerminal(
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          download_manager, 1,
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser, download_url);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  observer->WaitForFinished();
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SendToOmniboxAndSubmit(LocationBar* location_bar,
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const std::string& input) {
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  OmniboxView* omnibox = location_bar->GetLocationEntry();
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  omnibox->model()->OnSetFocus(false);
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  omnibox->SetUserText(ASCIIToUTF16(input));
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  location_bar->AcceptInput();
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (!omnibox->model()->autocomplete_controller()->done()) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WindowedNotificationObserver observer(
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        chrome::NOTIFICATION_AUTOCOMPLETE_CONTROLLER_RESULT_READY,
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::NotificationService::AllSources());
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    observer.Wait();
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* GetBrowserNotInSet(std::set<Browser*> excluded_browsers) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next()) {
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (excluded_browsers.find(*it) == excluded_browsers.end())
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return *it;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WindowedTabAddedNotificationObserver::WindowedTabAddedNotificationObserver(
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : WindowedNotificationObserver(chrome::NOTIFICATION_TAB_ADDED, source),
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      added_tab_(NULL) {
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void WindowedTabAddedNotificationObserver::Observe(
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  added_tab_ = content::Details<WebContents>(details).ptr();
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::WindowedNotificationObserver::Observe(type, source, details);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UrlLoadObserver::UrlLoadObserver(const GURL& url,
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const content::NotificationSource& source)
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : WindowedNotificationObserver(content::NOTIFICATION_LOAD_STOP, source),
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_(url) {
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UrlLoadObserver::~UrlLoadObserver() {}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UrlLoadObserver::Observe(
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigationController* controller =
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::Source<NavigationController>(source).ptr();
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (controller->GetWebContents()->GetURL() != url_)
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  WindowedNotificationObserver::Observe(type, source, details);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserAddedObserver::BrowserAddedObserver()
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : notification_observer_(
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          chrome::NOTIFICATION_BROWSER_OPENED,
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          content::NotificationService::AllSources()) {
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (chrome::BrowserIterator it; !it.done(); it.Next())
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    original_browsers_.insert(*it);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserAddedObserver::~BrowserAddedObserver() {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Browser* BrowserAddedObserver::WaitForSingleNewBrowser() {
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_observer_.Wait();
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Ensure that only a single new browser has appeared.
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(original_browsers_.size() + 1, chrome::GetTotalBrowserCount());
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetBrowserNotInSet(original_browsers_);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Coordinates taking snapshots of a |RenderWidget|.
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SnapshotTaker {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SnapshotTaker() : bitmap_(NULL) {}
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh,
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const gfx::Size& page_size,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const gfx::Size& desired_size,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                SkBitmap* bitmap) WARN_UNUSED_RESULT {
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bitmap_ = bitmap;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snapshot_taken_ = false;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_browser_process->GetRenderWidgetSnapshotTaker()->AskForSnapshot(
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        rwh,
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&SnapshotTaker::OnSnapshotTaken, base::Unretained(this)),
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        page_size,
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        desired_size);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_ = new content::MessageLoopRunner;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Run();
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return snapshot_taken_;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool TakeEntirePageSnapshot(RenderViewHost* rvh,
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SkBitmap* bitmap) WARN_UNUSED_RESULT {
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const char* script =
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "window.domAutomationController.send("
5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "    JSON.stringify([document.width, document.height]))";
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string json;
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!content::ExecuteScriptAndExtractString(rvh, script, &json))
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Parse the JSON.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<int> dimensions;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<Value> value(
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::JSONReader::Read(json, base::JSON_ALLOW_TRAILING_COMMAS));
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!value->IsType(Value::TYPE_LIST))
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ListValue* list = static_cast<ListValue*>(value.get());
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int width, height;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!list->GetInteger(0, &width) || !list->GetInteger(1, &height))
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Take the snapshot.
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gfx::Size page_size(width, height);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TakeRenderWidgetSnapshot(rvh, page_size, page_size, bitmap);
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called when the RenderWidgetSnapshotTaker has taken the snapshot.
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnSnapshotTaken(const SkBitmap& bitmap) {
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *bitmap_ = bitmap;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    snapshot_taken_ = true;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    message_loop_runner_->Quit();
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkBitmap* bitmap_;
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Whether the snapshot was actually taken and received by this SnapshotTaker.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This will be false if the test times out.
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool snapshot_taken_;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SnapshotTaker);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TakeRenderWidgetSnapshot(RenderWidgetHost* rwh,
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              const gfx::Size& page_size,
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              SkBitmap* bitmap) {
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bitmap);
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SnapshotTaker taker;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return taker.TakeRenderWidgetSnapshot(rwh, page_size, page_size, bitmap);
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TakeEntirePageSnapshot(RenderViewHost* rvh, SkBitmap* bitmap) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bitmap);
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SnapshotTaker taker;
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return taker.TakeEntirePageSnapshot(rvh, bitmap);
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN)
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SaveScreenSnapshotToDirectory(const base::FilePath& directory,
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath* screenshot_path) {
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool succeeded = false;
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath out_path(GetSnapshotFileName(directory));
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  MONITORINFO monitor_info = {};
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  monitor_info.cbSize = sizeof(monitor_info);
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  HMONITOR main_monitor = MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY);
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (GetMonitorInfo(main_monitor, &monitor_info)) {
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RECT& rect = monitor_info.rcMonitor;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    std::vector<unsigned char> png_data;
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    gfx::Rect bounds(
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        gfx::Size(rect.right - rect.left, rect.bottom - rect.top));
634c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (ui::GrabDesktopSnapshot(bounds, &png_data) &&
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        png_data.size() <= INT_MAX) {
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int bytes = static_cast<int>(png_data.size());
6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      int written = file_util::WriteFile(
6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          out_path, reinterpret_cast<char*>(&png_data[0]), bytes);
6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      succeeded = (written == bytes);
6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (succeeded && screenshot_path != NULL)
6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *screenshot_path = out_path;
6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return succeeded;
6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool SaveScreenSnapshotToDesktop(base::FilePath* screenshot_path) {
6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath desktop;
6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return PathService::Get(base::DIR_USER_DESKTOP, &desktop) &&
6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      SaveScreenSnapshotToDirectory(desktop, screenshot_path);
6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(OS_WIN)
6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void OverrideGeolocation(double latitude, double longitude) {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  content::Geoposition position;
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position.latitude = latitude;
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position.longitude = longitude;
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position.altitude = 0.;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position.accuracy = 0.;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  position.timestamp = base::Time::Now();
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> runner =
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new content::MessageLoopRunner;
667b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
668b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  content::GeolocationProvider::OverrideLocationForTesting(
669b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      position, runner->QuitClosure());
670b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  runner->Run();
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryEnumerator::HistoryEnumerator(Profile* profile) {
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<content::MessageLoopRunner> message_loop_runner =
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new content::MessageLoopRunner;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryService* hs = HistoryServiceFactory::GetForProfile(
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile, Profile::EXPLICIT_ACCESS);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  hs->QueryHistory(
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      string16(),
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::QueryOptions(),
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &consumer_,
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::Bind(&HistoryEnumerator::HistoryQueryComplete,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 base::Unretained(this), message_loop_runner->QuitClosure()));
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  message_loop_runner->Run();
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HistoryEnumerator::~HistoryEnumerator() {}
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HistoryEnumerator::HistoryQueryComplete(
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Closure& quit_task,
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HistoryService::Handle request_handle,
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::QueryResults* results) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < results->size(); ++i)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    urls_.push_back((*results)[i].url());
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quit_task.Run();
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui_test_utils
701