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/ui/ui_test.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <signal.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_switches.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/files/file_enumerator.h"
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/scoped_temp_dir.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_file_value_serializer.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_split.h"
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_file_util.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/app/chrome_command_ids.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_impl.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/automation_messages.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/logging_chrome.h"
41558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/net/url_fixer_upper.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/automation_proxy.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/browser_proxy.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/proxy_launcher.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/tab_proxy.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/automation/window_proxy.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/chrome_process_util.h"
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/test_launcher_utils.h"
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/test_switches.h"
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/testing_profile.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gl/gl_implementation.h"
557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const wchar_t UITestBase::kFailedNoCrashService[] =
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"NOTE: This test is expected to fail if crash_service.exe is not "
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"running. Start it manually before running this test (see the build "
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"output directory).";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_LINUX)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"NOTE: This test is expected to fail if breakpad is not built in "
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"or if chromium is not running headless (try CHROME_HEADLESS=1).";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    L"NOTE: Crash service not ported to this platform!";
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UITestBase::UITestBase()
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : launch_arguments_(CommandLine::NO_PROGRAM),
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_errors_(0),
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_crashes_(0),
8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      homepage_(content::kAboutBlankURL),
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_for_initial_loads_(true),
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dom_automation_enabled_(false),
84868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      stats_collection_controller_enabled_(false),
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      show_window_(false),
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      clear_profile_(true),
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      include_testing_id_(true),
88a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      enable_file_cookies_(true) {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_APP, &browser_directory_);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
93a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)UITestBase::UITestBase(base::MessageLoop::Type msg_loop_type)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : launch_arguments_(CommandLine::NO_PROGRAM),
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_errors_(0),
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      expected_crashes_(0),
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      wait_for_initial_loads_(true),
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      dom_automation_enabled_(false),
99868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      stats_collection_controller_enabled_(false),
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      show_window_(false),
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      clear_profile_(true),
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      include_testing_id_(true),
103a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)      enable_file_cookies_(true) {
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_APP, &browser_directory_);
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)UITestBase::~UITestBase() {}
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::SetUp() {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tests that do a session restore (e.g. SessionRestoreUITest, StartupTest)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // call SetUp() multiple times because they restart the browser mid-test.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We don't want to reset the ProxyLauncher's state in those cases.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!launcher_.get())
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launcher_.reset(CreateProxyLauncher());
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launcher_->AssertAppNotRunning("Please close any other instances "
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 "of the app before testing.");
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_start_time_ = Time::NowFromSystemTime();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLaunchSwitches();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(launcher_->InitializeConnection(DefaultLaunchState(),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              wait_for_initial_loads_));
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::TearDown() {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (launcher_.get())
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launcher_->TerminateConnection();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CheckErrorsAndCrashes();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutomationProxy* UITestBase::automation() const {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return launcher_->automation();
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta UITestBase::action_timeout() {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return automation()->action_timeout();
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UITestBase::action_timeout_ms() {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return action_timeout().InMilliseconds();
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::set_action_timeout(base::TimeDelta timeout) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  automation()->set_action_timeout(timeout);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VLOG(1) << "Automation action timeout set to "
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << timeout.InMilliseconds() << " ms";
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::set_action_timeout_ms(int timeout) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  set_action_timeout(base::TimeDelta::FromMilliseconds(timeout));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyLauncher* UITestBase::CreateProxyLauncher() {
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new AnonymousProxyLauncher(false);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyLauncher::LaunchState UITestBase::DefaultLaunchState() {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath browser_executable =
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      browser_directory_.Append(GetExecutablePath());
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CommandLine command(browser_executable);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  command.AppendArguments(launch_arguments_, false);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure setup_profile_callback = base::Bind(&UITestBase::SetUpProfile,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                    base::Unretained(this));
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyLauncher::LaunchState state =
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      { clear_profile_, template_user_data_, setup_profile_callback,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command, include_testing_id_, show_window_ };
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return state;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::SetLaunchSwitches() {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All flags added here should also be added in ExtraChromeFlags() in
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // chrome/test/pyautolib/pyauto.py as well to take effect for all tests
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on chromeos.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Propagate commandline settings from test_launcher_utils.
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  test_launcher_utils::PrepareBrowserCommandLineForTests(&launch_arguments_);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kWaitForDebugger))
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launch_arguments_.AppendSwitch(switches::kWaitForDebugger);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We need cookies on file:// for things like the page cycler.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enable_file_cookies_)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launch_arguments_.AppendSwitch(switches::kEnableFileCookies);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dom_automation_enabled_)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launch_arguments_.AppendSwitch(switches::kDomAutomationController);
188868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (stats_collection_controller_enabled_)
189868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    launch_arguments_.AppendSwitch(switches::kStatsCollectionController);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Allow off-store extension installs.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launch_arguments_.AppendSwitchASCII(
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      switches::kEasyOffStoreExtensionInstall, "1");
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!homepage_.empty()) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Pass |homepage_| both as an arg (so that it opens on startup) and to the
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // homepage switch (so that the homepage is set).
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!launch_arguments_.HasSwitch(switches::kHomePage))
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      launch_arguments_.AppendSwitchASCII(switches::kHomePage, homepage_);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (launch_arguments_.GetArgs().empty() &&
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        !launch_arguments_.HasSwitch(switches::kRestoreLastSession)) {
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      launch_arguments_.AppendArg(homepage_);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!test_name_.empty())
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launch_arguments_.AppendSwitchASCII(switches::kTestName, test_name_);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::SetUpProfile() {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::LaunchBrowser() {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  LaunchBrowser(launch_arguments_, clear_profile_);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::LaunchBrowserAndServer() {
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(launcher_->LaunchBrowserAndServer(DefaultLaunchState(),
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                wait_for_initial_loads_));
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::ConnectToRunningBrowser() {
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(launcher_->ConnectToRunningBrowser(wait_for_initial_loads_));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::CloseBrowserAndServer() {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (launcher_.get())
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    launcher_->CloseBrowserAndServer();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::LaunchBrowser(const CommandLine& arguments,
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               bool clear_profile) {
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ProxyLauncher::LaunchState state = DefaultLaunchState();
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  state.clear_profile = clear_profile;
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(launcher_->LaunchBrowser(state));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::QuitBrowser() {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launcher_->QuitBrowser();
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<TabProxy> UITestBase::GetActiveTab(int window_index) {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GE(window_index, 0);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int window_count = -1;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to use EXPECT rather than ASSERT here because ASSERT_* only works
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in functions that return void.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (window_count == -1)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_GT(window_count, window_index);
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserProxy> window_proxy(automation()->
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetBrowserWindow(window_index));
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window_proxy.get());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window_proxy.get())
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_tab_index = -1;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window_proxy->GetActiveTabIndex(&active_tab_index));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (active_tab_index == -1)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return window_proxy->GetTab(active_tab_index);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<TabProxy> UITestBase::GetActiveTab() {
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserProxy> window_proxy(automation()->
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetBrowserWindow(0));
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window_proxy.get());
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window_proxy.get())
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> tab_proxy = window_proxy->GetActiveTab();
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tab_proxy.get());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return tab_proxy;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::NavigateToURL(const GURL& url) {
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToURL(url, 0, GetActiveTabIndex(0));
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::NavigateToURL(const GURL& url, int window_index) {
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToURL(url, window_index, GetActiveTabIndex(window_index));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::NavigateToURL(const GURL& url, int window_index, int
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_index) {
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NavigateToURLBlockUntilNavigationsComplete(url, 1, window_index, tab_index);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::NavigateToURLBlockUntilNavigationsComplete(
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, int number_of_navigations) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> tab_proxy(GetActiveTab());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_proxy.get());
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tab_proxy->NavigateToURLBlockUntilNavigationsComplete(
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                url, number_of_navigations)) << url.spec();
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::NavigateToURLBlockUntilNavigationsComplete(
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url, int number_of_navigations, int window_index,
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tab_index) {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserProxy> window =
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation()->GetBrowserWindow(window_index);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(window.get());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> tab_proxy(window->GetTab(tab_index));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab_proxy.get());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS,
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            tab_proxy->NavigateToURLBlockUntilNavigationsComplete(
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                url, number_of_navigations)) << url.spec();
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL UITestBase::GetActiveTabURL(int window_index) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> tab_proxy(GetActiveTab(window_index));
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tab_proxy.get());
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!tab_proxy.get())
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GURL();
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url;
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = tab_proxy->GetCurrentURL(&url);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(success);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!success)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return GURL();
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::wstring UITestBase::GetActiveTabTitle(int window_index) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring title;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> tab_proxy(GetActiveTab(window_index));
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tab_proxy.get());
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!tab_proxy.get())
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return title;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tab_proxy->GetTabTitle(&title));
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return title;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UITestBase::GetActiveTabIndex(int window_index) {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserProxy> window_proxy(automation()->
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetBrowserWindow(window_index));
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window_proxy.get());
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window_proxy.get())
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return -1;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int active_tab_index = -1;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window_proxy->GetActiveTabIndex(&active_tab_index));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return active_tab_index;
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UITestBase::GetTabCount() {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GetTabCount(0);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UITestBase::GetTabCount(int window_index) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<BrowserProxy> window(
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      automation()->GetBrowserWindow(window_index));
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window.get());
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!window.get())
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return 0;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result = 0;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(window->GetTabCount(&result));
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::WaitUntilTabCount(int tab_count) {
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxIntervals = 10;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kDelay = TestTimeouts::action_timeout() / kMaxIntervals;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxIntervals; ++i) {
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (GetTabCount() == tab_count)
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(kDelay);
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE() << "Timeout reached in WaitUntilTabCount";
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType* UITestBase::GetExecutablePath() {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (launch_arguments_.HasSwitch(switches::kEnableChromiumBranding))
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return chrome::kBrowserProcessExecutablePathChromium;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return chrome::kBrowserProcessExecutablePath;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UITestBase::CloseBrowser(BrowserProxy* browser,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              bool* application_closed) const {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(application_closed);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!browser->is_valid() || !browser->handle())
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = true;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ChromeProcessList processes = GetRunningChromeProcesses(
394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      browser_process_id());
395c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool succeeded = automation()->Send(new AutomationMsg_CloseBrowser(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser->handle(), &result, application_closed));
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!succeeded)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (*application_closed) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int exit_code = -1;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(launcher_->WaitForBrowserProcessToQuit(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TestTimeouts::action_max_timeout(), &exit_code));
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, exit_code);  // Expect a clean shutown.
407c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    // Ensure no child processes are left dangling.
408c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    TerminateAllChromeProcesses(processes);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int UITestBase::GetCrashCount() const {
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath crash_dump_path;
416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path);
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int files_found = 0;
419868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  base::FileEnumerator en(crash_dump_path, false, base::FileEnumerator::FILES);
420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  while (!en.Next().empty()) {
421868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (en.GetInfo().GetLastModifiedTime() > test_start_time_)
422c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      files_found++;
423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(OS_WIN)
426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Each crash creates two dump files on Windows.
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return files_found / 2;
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#else
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return files_found;
430868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string UITestBase::CheckErrorsAndCrashes() const {
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure that we didn't encounter any assertion failures
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::AssertionList assertions;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  logging::GetFatalAssertions(&assertions);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If there were errors, get all the error strings for display.
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring failures =
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      L"The following error(s) occurred in the application during this test:";
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (assertions.size() > expected_errors_) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    logging::AssertionList::const_iterator iter = assertions.begin();
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (; iter != assertions.end(); ++iter) {
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      failures += L"\n\n";
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      failures += *iter;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_errors_, assertions.size()) << failures;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int actual_crashes = GetCrashCount();
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring error_msg =
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      L"Encountered an unexpected crash in the program during this test.";
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expected_crashes_ > 0 && actual_crashes == 0) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_msg += L"  ";
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_msg += kFailedNoCrashService;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_crashes_, actual_crashes) << error_msg;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::wstring wide_result;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expected_errors_ != assertions.size()) {
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wide_result += failures;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wide_result += L"\n\n";
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (expected_crashes_ != actual_crashes)
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    wide_result += error_msg;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string(wide_result.begin(), wide_result.end());
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UITestBase::SetBrowserDirectory(const base::FilePath& dir) {
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  browser_directory_ = dir;
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::AppendBrowserLaunchSwitch(const char* name) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launch_arguments_.AppendSwitch(name);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITestBase::AppendBrowserLaunchSwitch(const char* name,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const char* value) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launch_arguments_.AppendSwitchASCII(name, value);
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool UITestBase::BeginTracing(const std::string& category_patterns) {
485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return automation()->BeginTracing(category_patterns);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string UITestBase::EndTracing() {
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string json_trace_output;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!automation()->EndTracing(&json_trace_output))
491c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return std::string();
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return json_trace_output;
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// UITest methods
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITest::SetUp() {
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pass the test case name to chrome.exe on the command line to help with
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // parsing Purify output.
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const testing::TestInfo* const test_info =
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      testing::UnitTest::GetInstance()->current_test_info();
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (test_info) {
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set_test_name(test_info->test_case_name() + std::string(".") +
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  test_info->name());
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UITestBase::SetUp();
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformTest::SetUp();
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITest::TearDown() {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UITestBase::TearDown();
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformTest::TearDown();
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ProxyLauncher* UITest::CreateProxyLauncher() {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make the AutomationProxy disconnect the channel on the first error,
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // so that we avoid spending a lot of time in timeouts. The browser is likely
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hosed if we hit those errors.
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new AnonymousProxyLauncher(true);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UITest::GetBrowserProcessCount(int* count) {
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *count = 0;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!automation()->WaitForProcessLauncherThreadToGoIdle())
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *count = GetRunningChromeProcesses(browser_process_id()).size();
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static DictionaryValue* LoadDictionaryValueFromPath(
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath& path) {
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (path.empty())
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JSONFileValueSerializer serializer(path);
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<Value> root_value(serializer.Deserialize(NULL, NULL));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_value.get() || root_value->GetType() != Value::TYPE_DICTIONARY)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return static_cast<DictionaryValue*>(root_value.release());
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* UITest::GetLocalState() {
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath local_state_path;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::FILE_LOCAL_STATE, &local_state_path);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LoadDictionaryValueFromPath(local_state_path);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DictionaryValue* UITest::GetDefaultProfilePreferences() {
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath path;
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PathService::Get(chrome::DIR_USER_DATA, &path);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  path = path.AppendASCII(TestingProfile::kTestUserProfileDir);
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return LoadDictionaryValueFromPath(path.Append(chrome::kPreferencesFilename));
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITest::WaitForFinish(const std::string &name,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string &id,
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const GURL &url,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& test_complete_cookie,
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const std::string& expected_cookie_value,
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           const base::TimeDelta wait_time) {
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The webpage being tested has javascript which sets a cookie
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // which signals completion of the test.  The cookie name is
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a concatenation of the test name and the test id.  This allows
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // us to run multiple tests within a single webpage and test
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that they all c
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_name = name;
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_name.append(".");
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_name.append(id);
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_name.append(".");
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  cookie_name.append(test_complete_cookie);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TabProxy> tab(GetActiveTab());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(tab.get());
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_value = WaitUntilCookieNonEmpty(tab.get(), url,
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     cookie_name.c_str(),
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     wait_time);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(expected_cookie_value, cookie_value);
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UITest::WaitUntilJavaScriptCondition(TabProxy* tab,
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const std::wstring& frame_xpath,
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          const std::wstring& jscript,
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          base::TimeDelta timeout) {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kDelay = TimeDelta::FromMilliseconds(250);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxDelays = timeout / kDelay;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Wait until the test signals it has completed.
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxDelays; ++i) {
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool done_value = false;
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool success = tab->ExecuteAndExtractBool(frame_xpath, jscript,
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              &done_value);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(success);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!success)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (done_value)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(kDelay);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE() << "Timeout reached in WaitUntilJavaScriptCondition";
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UITest::WaitUntilCookieValue(TabProxy* tab,
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const GURL& url,
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const char* cookie_name,
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  base::TimeDelta timeout,
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  const char* expected_value) {
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kDelay = TimeDelta::FromMilliseconds(250);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxDelays = timeout / kDelay;
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string cookie_value;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxDelays; ++i) {
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(tab->GetCookieByName(url, cookie_name, &cookie_value));
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cookie_value == expected_value)
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(kDelay);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE() << "Timeout reached in WaitUntilCookieValue";
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string UITest::WaitUntilCookieNonEmpty(TabProxy* tab,
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const GURL& url,
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            const char* cookie_name,
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            base::TimeDelta timeout) {
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kDelay = TimeDelta::FromMilliseconds(250);
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kMaxDelays = timeout / kDelay;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kMaxDelays; ++i) {
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::string cookie_value;
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(tab->GetCookieByName(url, cookie_name, &cookie_value));
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!cookie_value.empty())
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return cookie_value;
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(kDelay);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE() << "Timeout reached in WaitUntilCookieNonEmpty";
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string();
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool UITest::WaitForFindWindowVisibilityChange(BrowserProxy* browser,
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bool wait_for_open) {
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const int kCycles = 10;
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta kDelay = TestTimeouts::action_timeout() / kCycles;
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < kCycles; i++) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool visible = false;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!browser->IsFindWindowFullyVisible(&visible))
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;  // Some error.
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (visible == wait_for_open)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;  // Find window visibility change complete.
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Give it a chance to catch up.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::PlatformThread::Sleep(kDelay);
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ADD_FAILURE() << "Timeout reached in WaitForFindWindowVisibilityChange";
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void UITest::TerminateBrowser() {
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  launcher_->TerminateBrowser();
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure the UMA metrics say we didn't crash.
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> local_prefs(GetLocalState());
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool exited_cleanly;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(local_prefs.get());
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(local_prefs->GetBoolean(prefs::kStabilityExitedCleanly,
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &exited_cleanly));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(exited_cleanly);
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // And that session end was successful.
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool session_end_completed;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(local_prefs->GetBoolean(prefs::kStabilitySessionEndCompleted,
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &session_end_completed));
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(session_end_completed);
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure session restore says we didn't crash.
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<DictionaryValue> profile_prefs(GetDefaultProfilePreferences());
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(profile_prefs.get());
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string exit_type;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(profile_prefs->GetString(prefs::kSessionExitedCleanly,
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        &exit_type));
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(ProfileImpl::kPrefExitTypeNormal, exit_type);
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
692