diff options
author | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-12 18:12:24 +0000 |
---|---|---|
committer | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-12 18:12:24 +0000 |
commit | ada3e82b82a0ebfb91db4a6e8c371e8162fde89f (patch) | |
tree | ebd9188a41f2d8954799f26c7feccb3108afebdc /chrome | |
parent | 79f16a133050196d2a78ef9478f8f59b4680981d (diff) | |
download | chromium_src-ada3e82b82a0ebfb91db4a6e8c371e8162fde89f.zip chromium_src-ada3e82b82a0ebfb91db4a6e8c371e8162fde89f.tar.gz chromium_src-ada3e82b82a0ebfb91db4a6e8c371e8162fde89f.tar.bz2 |
Revert 96556 - Let pyauto create an attached webdriver instance to manipulate web pages.
BUG=49379
TEST=none
Review URL: http://codereview.chromium.org/7523060
TBR=hnguyen
Review URL: http://codereview.chromium.org/7629019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96580 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.cc | 25 | ||||
-rw-r--r-- | chrome/browser/automation/testing_automation_provider.h | 8 | ||||
-rw-r--r-- | chrome/test/automation/automation_proxy_uitest.cc | 10 | ||||
-rw-r--r-- | chrome/test/automation/proxy_launcher.cc | 28 | ||||
-rw-r--r-- | chrome/test/automation/proxy_launcher.h | 16 | ||||
-rw-r--r-- | chrome/test/functional/PYAUTO_TESTS | 1 | ||||
-rw-r--r-- | chrome/test/functional/pyauto_webdriver.py | 33 | ||||
-rw-r--r-- | chrome/test/pyautolib/chrome_driver_factory.py | 62 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyauto.py | 62 | ||||
-rw-r--r-- | chrome/test/pyautolib/pyauto_paths.py | 57 | ||||
-rw-r--r-- | chrome/test/ui/ui_test.cc | 4 | ||||
-rw-r--r-- | chrome/test/webdriver/automation.cc | 109 | ||||
-rw-r--r-- | chrome/test/webdriver/automation.h | 22 | ||||
-rw-r--r-- | chrome/test/webdriver/commands/create_session.cc | 36 | ||||
-rw-r--r-- | chrome/test/webdriver/session.cc | 19 | ||||
-rw-r--r-- | chrome/test/webdriver/session.h | 8 |
16 files changed, 152 insertions, 348 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index a40364a..354a560 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -78,7 +78,6 @@ #include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h" #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" #include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" -#include "chrome/browser/ui/browser_init.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/find_bar/find_bar.h" #include "chrome/browser/ui/login/login_prompt.h" @@ -2214,8 +2213,6 @@ void TestingAutomationProvider::SendJSONRequest(int handle, &TestingAutomationProvider::GetChromeDriverAutomationVersion; handler_map["UpdateExtensionsNow"] = &TestingAutomationProvider::UpdateExtensionsNow; - handler_map["CreateNewAutomationProvider"] = - &TestingAutomationProvider::CreateNewAutomationProvider; #if defined(OS_CHROMEOS) handler_map["GetLoginInfo"] = &TestingAutomationProvider::GetLoginInfo; handler_map["ShowCreateAccountUI"] = @@ -6009,28 +6006,6 @@ void TestingAutomationProvider::GetChromeDriverAutomationVersion( AutomationJSONReply(this, reply_message).SendSuccess(&reply_dict); } -void TestingAutomationProvider::CreateNewAutomationProvider( - DictionaryValue* args, - IPC::Message* reply_message) { - AutomationJSONReply reply(this, reply_message); - std::string channel_id; - if (!args->GetString("channel_id", &channel_id)) { - reply.SendError("'channel_id' missing or invalid"); - return; - } - - // TODO(kkania): Remove this when crbug.com/91311 is fixed. - // Named server channels should ideally be created and closed on the file - // thread, within the IPC channel code. - base::ThreadRestrictions::ScopedAllowIO allow_io; - if (!BrowserInit::CreateAutomationProvider<TestingAutomationProvider>( - automation::kNamedInterfacePrefix + channel_id, profile_, 0)) { - reply.SendError("Failed to initialize channel: " + channel_id); - return; - } - reply.SendSuccess(NULL); -} - void TestingAutomationProvider::WaitForTabCountToBecome( int browser_handle, int target_tab_count, diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index fbd486c..5052447 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -1150,14 +1150,6 @@ class TestingAutomationProvider : public AutomationProvider, void UpdateExtensionsNow(base::DictionaryValue* args, IPC::Message* reply_message); - // Creates a new |TestingAutomationProvider| that opens a server channel - // for the given |channel_id|. - // The server channel will be available for connection when this returns. - // Example: - // input: { "channel_id": "testChannel123" } - void CreateNewAutomationProvider(base::DictionaryValue* args, - IPC::Message* reply_message); - #if defined(OS_CHROMEOS) // Login. void GetLoginInfo(base::DictionaryValue* args, IPC::Message* reply_message); diff --git a/chrome/test/automation/automation_proxy_uitest.cc b/chrome/test/automation/automation_proxy_uitest.cc index 665f4a2..924d987 100644 --- a/chrome/test/automation/automation_proxy_uitest.cc +++ b/chrome/test/automation/automation_proxy_uitest.cc @@ -63,13 +63,9 @@ class ExternalTabUITestMockLauncher : public ProxyLauncher { return *mock_; } - bool InitializeConnection( - const LaunchState& state, - bool wait_for_initial_loads) OVERRIDE WARN_UNUSED_RESULT { - bool launch_browser_and_server = - LaunchBrowserAndServer(state, wait_for_initial_loads); - EXPECT_TRUE(launch_browser_and_server); - return launch_browser_and_server; + void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads) { + ASSERT_TRUE(LaunchBrowserAndServer(state, wait_for_initial_loads)); } void TerminateConnection() { diff --git a/chrome/test/automation/proxy_launcher.cc b/chrome/test/automation/proxy_launcher.cc index c8d16a6..95f4d0d 100644 --- a/chrome/test/automation/proxy_launcher.cc +++ b/chrome/test/automation/proxy_launcher.cc @@ -519,22 +519,17 @@ AutomationProxy* NamedProxyLauncher::CreateAutomationProxy( return proxy; } -bool NamedProxyLauncher::InitializeConnection(const LaunchState& state, +void NamedProxyLauncher::InitializeConnection(const LaunchState& state, bool wait_for_initial_loads) { if (launch_browser_) { #if defined(OS_POSIX) // Because we are waiting on the existence of the testing file below, // make sure there isn't one already there before browser launch. - if (!file_util::Delete(FilePath(channel_id_), false)) { - LOG(ERROR) << "Failed to delete " << channel_id_; - return false; - } + EXPECT_TRUE(file_util::Delete(FilePath(channel_id_), false)); #endif - if (!LaunchBrowser(state)) { - LOG(ERROR) << "Failed to LaunchBrowser"; - return false; - } + // Set up IPC testing interface as a client. + ASSERT_TRUE(LaunchBrowser(state)); } // Wait for browser to be ready for connections. @@ -547,16 +542,9 @@ bool NamedProxyLauncher::InitializeConnection(const LaunchState& state, break; base::PlatformThread::Sleep(automation::kSleepTime); } - if (!channel_initialized) { - LOG(ERROR) << "Failed to wait for testing channel presence."; - return false; - } + EXPECT_TRUE(channel_initialized); - if (!ConnectToRunningBrowser(wait_for_initial_loads)) { - LOG(ERROR) << "Failed to ConnectToRunningBrowser"; - return false; - } - return true; + ASSERT_TRUE(ConnectToRunningBrowser(wait_for_initial_loads)); } void NamedProxyLauncher::TerminateConnection() { @@ -587,9 +575,9 @@ AutomationProxy* AnonymousProxyLauncher::CreateAutomationProxy( return proxy; } -bool AnonymousProxyLauncher::InitializeConnection(const LaunchState& state, +void AnonymousProxyLauncher::InitializeConnection(const LaunchState& state, bool wait_for_initial_loads) { - return LaunchBrowserAndServer(state, wait_for_initial_loads); + ASSERT_TRUE(LaunchBrowserAndServer(state, wait_for_initial_loads)); } void AnonymousProxyLauncher::TerminateConnection() { diff --git a/chrome/test/automation/proxy_launcher.h b/chrome/test/automation/proxy_launcher.h index 12beeb0..c878719 100644 --- a/chrome/test/automation/proxy_launcher.h +++ b/chrome/test/automation/proxy_launcher.h @@ -65,10 +65,8 @@ class ProxyLauncher { virtual ~ProxyLauncher(); // Launches the browser if needed and establishes a connection with it. - // Returns true on success. - virtual bool InitializeConnection( - const LaunchState& state, - bool wait_for_initial_loads) WARN_UNUSED_RESULT = 0; + virtual void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads) = 0; // Shuts down the browser if needed and destroys any // connections established by InitalizeConnection. @@ -290,9 +288,8 @@ class NamedProxyLauncher : public ProxyLauncher { bool launch_browser, bool disconnect_on_failure); virtual AutomationProxy* CreateAutomationProxy(int execution_timeout); - virtual bool InitializeConnection( - const LaunchState& state, - bool wait_for_initial_loads) OVERRIDE WARN_UNUSED_RESULT; + virtual void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads); virtual void TerminateConnection(); virtual std::string PrefixedChannelID() const; @@ -310,9 +307,8 @@ class AnonymousProxyLauncher : public ProxyLauncher { public: explicit AnonymousProxyLauncher(bool disconnect_on_failure); virtual AutomationProxy* CreateAutomationProxy(int execution_timeout); - virtual bool InitializeConnection( - const LaunchState& state, - bool wait_for_initial_loads) OVERRIDE WARN_UNUSED_RESULT; + virtual void InitializeConnection(const LaunchState& state, + bool wait_for_initial_loads); virtual void TerminateConnection(); virtual std::string PrefixedChannelID() const; diff --git a/chrome/test/functional/PYAUTO_TESTS b/chrome/test/functional/PYAUTO_TESTS index e4a0b67..25f688a 100644 --- a/chrome/test/functional/PYAUTO_TESTS +++ b/chrome/test/functional/PYAUTO_TESTS @@ -63,7 +63,6 @@ 'plugins_check', 'popups', 'prefs', - 'pyauto_webdriver', 'search_engines', 'shortcuts', 'special_tabs', diff --git a/chrome/test/functional/pyauto_webdriver.py b/chrome/test/functional/pyauto_webdriver.py deleted file mode 100644 index b72570c..0000000 --- a/chrome/test/functional/pyauto_webdriver.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -import pyauto_functional -import pyauto - - -class PyAutoWebDriverTest(pyauto.PyUITest): - """Tests PyAuto-WebDriver integration.""" - - def testTypeIntoTextBox(self): - """Type into a text input box and verify its value.""" - driver = self.NewWebDriver() - driver.get('about:blank') - driver.execute_script('document.body.innerHTML = "<input type=\'text\'>"') - input = driver.find_element_by_tag_name('input') - self.assertEquals('', input.get_attribute('value')) - input.send_keys('test') - self.assertEquals('test', input.get_attribute('value')) - - def testCanConnectToRestartedBrowser(self): - """Restart the browser and connect again with WebDriver.""" - driver = self.NewWebDriver() - self.RestartBrowser() - driver = self.NewWebDriver() - driver.get('about:blank') - self.assertEquals('about:blank', driver.title) - - -if __name__ == '__main__': - pyauto_functional.Main() diff --git a/chrome/test/pyautolib/chrome_driver_factory.py b/chrome/test/pyautolib/chrome_driver_factory.py deleted file mode 100644 index 3ea970d..0000000 --- a/chrome/test/pyautolib/chrome_driver_factory.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Factory that creates ChromeDriver instances for pyauto.""" - -import os -import random -import tempfile - -import pyauto_paths -from selenium import webdriver -from selenium.webdriver.chrome import service - - -class ChromeDriverFactory(object): - """"Factory that creates ChromeDriver instances for pyauto. - - Starts a single chromedriver server when necessary. Users should call 'Stop' - when no longer using the factory. - """ - - def __init__(self): - self._chromedriver_server = None - - def NewChromeDriver(self, pyauto): - """Creates a new remote WebDriver instance. - - This instance will connect to a new automation provider of an already - running Chrome. - Args: - pyauto: pyauto.PyUITest instance - - Returns: - selenium.webdriver.remote.webdriver.WebDriver instance - """ - self._StartServerIfNecessary() - channel_id = 'testing' + hex(random.getrandbits(20 * 4))[2:-1] - if not pyauto.IsWin(): - channel_id = os.path.join(tempfile.gettempdir(), channel_id) - pyauto.CreateNewAutomationProvider(channel_id) - return webdriver.Remote(self._chromedriver_server.service_url, - {'chrome.channel': channel_id}) - - def _StartServerIfNecessary(self): - """Starts the ChromeDriver server, if not already started.""" - if self._chromedriver_server is None: - exe = pyauto_paths.GetChromeDriverExe() - assert exe, 'Cannot find chromedriver exe. Did you build it?' - self._chromedriver_server = service.Service(exe) - self._chromedriver_server.start() - - def Stop(self): - """Stops the ChromeDriver server, if running.""" - if self._chromedriver_server is not None: - self._chromedriver_server.stop() - self._chromedriver_server = None - - def __del__(self): - self.Stop() - diff --git a/chrome/test/pyautolib/pyauto.py b/chrome/test/pyautolib/pyauto.py index 89ef512..329c9bf 100644 --- a/chrome/test/pyautolib/pyauto.py +++ b/chrome/test/pyautolib/pyauto.py @@ -46,17 +46,35 @@ import types import unittest import urllib -import pyauto_paths - def _LocateBinDirs(): """Setup a few dirs where we expect to find dependency libraries.""" - deps_dirs = [ - os.path.dirname(__file__), - pyauto_paths.GetThirdPartyDir(), - os.path.join(pyauto_paths.GetThirdPartyDir(), 'webdriver', 'python'), + script_dir = os.path.dirname(__file__) + chrome_src = os.path.join(script_dir, os.pardir, os.pardir, os.pardir) + + bin_dirs = { + 'linux2': [ os.path.join(chrome_src, 'out', 'Debug'), + os.path.join(chrome_src, 'sconsbuild', 'Debug'), + os.path.join(chrome_src, 'out', 'Release'), + os.path.join(chrome_src, 'sconsbuild', 'Release')], + 'linux3': [ os.path.join(chrome_src, 'out', 'Debug'), + os.path.join(chrome_src, 'sconsbuild', 'Debug'), + os.path.join(chrome_src, 'out', 'Release'), + os.path.join(chrome_src, 'sconsbuild', 'Release')], + 'darwin': [ os.path.join(chrome_src, 'xcodebuild', 'Debug'), + os.path.join(chrome_src, 'xcodebuild', 'Release')], + 'win32': [ os.path.join(chrome_src, 'chrome', 'Debug'), + os.path.join(chrome_src, 'build', 'Debug'), + os.path.join(chrome_src, 'chrome', 'Release'), + os.path.join(chrome_src, 'build', 'Release')], + 'cygwin': [ os.path.join(chrome_src, 'chrome', 'Debug'), + os.path.join(chrome_src, 'chrome', 'Release')], + } + deps_dirs = [ os.path.join(script_dir, os.pardir, + os.pardir, os.pardir, 'third_party'), + script_dir, ] - sys.path += map(os.path.normpath, pyauto_paths.GetBuildDirs() + deps_dirs) + sys.path += map(os.path.normpath, bin_dirs.get(sys.platform, []) + deps_dirs) _LocateBinDirs() @@ -87,7 +105,6 @@ from pyauto_errors import NTPThumbnailNotShownError import pyauto_utils import simplejson as json # found in third_party -_CHROME_DRIVER_FACTORY = None _HTTP_SERVER = None _REMOTE_PROXY = None _OPTIONS = None @@ -2813,31 +2830,6 @@ class PyUITest(pyautolib.PyUITestBase, unittest.TestCase): } return self._GetResultFromJSONRequest(cmd_dict) - def NewWebDriver(self): - """Returns a new remote WebDriver instance. - - Returns: - selenium.webdriver.remote.webdriver.WebDriver instance - """ - from chrome_driver_factory import ChromeDriverFactory - global _CHROME_DRIVER_FACTORY - if _CHROME_DRIVER_FACTORY is None: - _CHROME_DRIVER_FACTORY = ChromeDriverFactory() - return _CHROME_DRIVER_FACTORY.NewChromeDriver(self) - - def CreateNewAutomationProvider(self, channel_id): - """Creates a new automation provider. - - The provider will open a named channel in server mode. - Args: - channel_id: the channel_id to open the server channel with - """ - cmd_dict = { - 'command': 'CreateNewAutomationProvider', - 'channel_id': channel_id - } - self._GetResultFromJSONRequest(cmd_dict) - ## ChromeOS section def GetLoginInfo(self): @@ -3830,10 +3822,6 @@ class PyUITestSuite(pyautolib.PyUITestSuiteBase, unittest.TestSuite): if _HTTP_SERVER: self._StopHTTPServer() - global _CHROME_DRIVER_FACTORY - if _CHROME_DRIVER_FACTORY is not None: - _CHROME_DRIVER_FACTORY.Stop() - def _StartHTTPServer(self): """Start a local file server hosting data files over http://""" global _HTTP_SERVER diff --git a/chrome/test/pyautolib/pyauto_paths.py b/chrome/test/pyautolib/pyauto_paths.py deleted file mode 100644 index 5b9bb1e..0000000 --- a/chrome/test/pyautolib/pyauto_paths.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python -# Copyright (c) 2011 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Common paths for pyauto tests.""" - -import os -import sys - - -def GetSourceDir(): - """Returns src/ directory.""" - script_dir = os.path.abspath(os.path.dirname(__file__)) - return os.path.join(script_dir, os.pardir, os.pardir, os.pardir) - - -def GetThirdPartyDir(): - """Returns src/third_party directory.""" - return os.path.join(GetSourceDir(), 'third_party') - - -def GetBuildDirs(): - """Returns list of possible build directories.""" - build_dirs = { - 'linux2': [ os.path.join('out', 'Debug'), - os.path.join('sconsbuild', 'Debug'), - os.path.join('out', 'Release'), - os.path.join('sconsbuild', 'Release')], - 'linux3': [ os.path.join('out', 'Debug'), - os.path.join('sconsbuild', 'Debug'), - os.path.join('out', 'Release'), - os.path.join('sconsbuild', 'Release')], - 'darwin': [ os.path.join('xcodebuild', 'Debug'), - os.path.join('xcodebuild', 'Release')], - 'win32': [ os.path.join('chrome', 'Debug'), - os.path.join('build', 'Debug'), - os.path.join('chrome', 'Release'), - os.path.join('build', 'Release')], - 'cygwin': [ os.path.join('chrome', 'Debug'), - os.path.join('chrome', 'Release')], - } - src_dir = GetSourceDir() - return map(lambda dir: os.path.join(src_dir, dir), - build_dirs.get(sys.platform, [])) - - -def GetChromeDriverExe(): - """Returns path to ChromeDriver executable, or None if cannot be found.""" - exe_name = 'chromedriver' - if sys.platform == 'win32': - exe_name += '.exe' - for dir in GetBuildDirs(): - exe = os.path.join(dir, exe_name) - if os.path.exists(exe): - return exe - return None diff --git a/chrome/test/ui/ui_test.cc b/chrome/test/ui/ui_test.cc index 81f03eb..d02eb70 100644 --- a/chrome/test/ui/ui_test.cc +++ b/chrome/test/ui/ui_test.cc @@ -125,8 +125,8 @@ void UITestBase::SetUp() { test_start_time_ = Time::NowFromSystemTime(); SetLaunchSwitches(); - ASSERT_TRUE(launcher_->InitializeConnection(DefaultLaunchState(), - wait_for_initial_loads_)); + launcher_->InitializeConnection(DefaultLaunchState(), + wait_for_initial_loads_); } void UITestBase::TearDown() { diff --git a/chrome/test/webdriver/automation.cc b/chrome/test/webdriver/automation.cc index 6b2449eb..5ce1614 100644 --- a/chrome/test/webdriver/automation.cc +++ b/chrome/test/webdriver/automation.cc @@ -11,6 +11,7 @@ #include "base/base_paths.h" #include "base/basictypes.h" #include "base/callback.h" +#include "base/command_line.h" #include "base/environment.h" #include "base/file_path.h" #include "base/file_util.h" @@ -183,63 +184,64 @@ bool GetDefaultChromeExe(FilePath* browser_exe) { namespace webdriver { -Automation::BrowserOptions::BrowserOptions() - : cmdline(CommandLine::NO_PROGRAM) {} - -Automation::BrowserOptions::~BrowserOptions() {} - Automation::Automation() {} Automation::~Automation() {} -void Automation::Init(const BrowserOptions& options, Error** error) { - CommandLine cmdline = options.cmdline; - if (cmdline.GetProgram().empty()) { - FilePath browser_exe; - if (!GetDefaultChromeExe(&browser_exe)) { - *error = new Error(kUnknownError, "Could not find default Chrome binary"); - return; - } - cmdline.SetProgram(browser_exe); +void Automation::Init(const CommandLine& options, + const FilePath& user_data_dir, + Error** error) { + FilePath browser_exe; + if (!GetDefaultChromeExe(&browser_exe)) { + *error = new Error(kUnknownError, "Could not find default Chrome binary"); + return; } - if (!file_util::PathExists(cmdline.GetProgram())) { + + InitWithBrowserPath(browser_exe, user_data_dir, options, error); +} + +void Automation::InitWithBrowserPath(const FilePath& browser_exe, + const FilePath& user_data_dir, + const CommandLine& options, + Error** error) { + if (!file_util::PathExists(browser_exe)) { std::string message = base::StringPrintf( "Could not find Chrome binary at: %" PRFilePath, - cmdline.GetProgram().value().c_str()); + browser_exe.value().c_str()); *error = new Error(kUnknownError, message); return; } - std::string chrome_details = base::StringPrintf( - "Using Chrome binary at: %" PRFilePath, - cmdline.GetProgram().value().c_str()); - LOG(INFO) << chrome_details; - cmdline.AppendSwitch(switches::kDisableHangMonitor); - cmdline.AppendSwitch(switches::kDisablePromptOnRepost); - cmdline.AppendSwitch(switches::kDomAutomationController); - cmdline.AppendSwitch(switches::kFullMemoryCrashReport); - cmdline.AppendSwitch(switches::kNoDefaultBrowserCheck); - cmdline.AppendSwitch(switches::kNoFirstRun); + CommandLine command(browser_exe); + command.AppendSwitch(switches::kDisableHangMonitor); + command.AppendSwitch(switches::kDisablePromptOnRepost); + command.AppendSwitch(switches::kDomAutomationController); + command.AppendSwitch(switches::kFullMemoryCrashReport); + command.AppendSwitch(switches::kNoDefaultBrowserCheck); + command.AppendSwitch(switches::kNoFirstRun); + command.AppendSwitchASCII(switches::kTestType, "webdriver"); - if (options.user_data_dir.empty()) - cmdline.AppendSwitchASCII(switches::kHomePage, chrome::kAboutBlankURL); + if (user_data_dir.empty()) + command.AppendSwitchASCII(switches::kHomePage, chrome::kAboutBlankURL); - if (options.channel_id.empty()) { - launcher_.reset(new AnonymousProxyLauncher(false)); - } else { - launcher_.reset(new NamedProxyLauncher(options.channel_id, false, false)); - } + command.AppendArguments(options, false); + launcher_.reset(new AnonymousProxyLauncher(false)); ProxyLauncher::LaunchState launch_props = { false, // clear_profile - options.user_data_dir, // template_user_data + user_data_dir, // template_user_data base::Closure(), - cmdline, + command, true, // include_testing_id true // show_window }; - if (!launcher_->InitializeConnection(launch_props, true)) { - LOG(ERROR) << "Failed to initialize connection"; + + std::string chrome_details = base::StringPrintf( + "Using Chrome binary at: %" PRFilePath, + browser_exe.value().c_str()); + LOG(INFO) << chrome_details; + + if (!launcher_->LaunchBrowserAndServer(launch_props, true)) { *error = new Error( kUnknownError, "Unable to either launch or connect to Chrome. Please check that " @@ -251,20 +253,27 @@ void Automation::Init(const BrowserOptions& options, Error** error) { LOG(INFO) << "Chrome launched successfully. Version: " << automation()->server_version(); - chrome_details += ", version (" + automation()->server_version() + ")"; - int version = 0; - std::string error_msg; - if (!SendGetChromeDriverAutomationVersion( - automation(), &version, &error_msg)) { - *error = new Error(kUnknownError, error_msg + " " + chrome_details); - return; - } - if (version > automation::kChromeDriverAutomationVersion) { - *error = new Error( - kUnknownError, - "ChromeDriver is not compatible with this version of Chrome. " + - chrome_details); + bool has_automation_version = false; + *error = CompareVersion(730, 0, &has_automation_version); + if (*error) return; + + chrome_details += ", version (" + automation()->server_version() + ")"; + if (has_automation_version) { + int version = 0; + std::string error_msg; + if (!SendGetChromeDriverAutomationVersion( + automation(), &version, &error_msg)) { + *error = new Error(kUnknownError, error_msg + " " + chrome_details); + return; + } + if (version > automation::kChromeDriverAutomationVersion) { + *error = new Error( + kUnknownError, + "ChromeDriver is not compatible with this version of Chrome. " + + chrome_details); + return; + } } } diff --git a/chrome/test/webdriver/automation.h b/chrome/test/webdriver/automation.h index df00f4b..8732489 100644 --- a/chrome/test/webdriver/automation.h +++ b/chrome/test/webdriver/automation.h @@ -9,7 +9,6 @@ #include <string> #include <vector> -#include "base/command_line.h" #include "base/file_path.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" @@ -18,6 +17,8 @@ #include "ui/base/keycodes/keyboard_codes.h" class AutomationProxy; +class CommandLine; +class FilePath; class ProxyLauncher; struct WebKeyEvent; @@ -41,20 +42,19 @@ class FramePath; // by posting a task from NewRunnableMethod. class Automation { public: - struct BrowserOptions { - BrowserOptions(); - ~BrowserOptions(); - - CommandLine cmdline; - FilePath user_data_dir; - std::string channel_id; - }; - Automation(); virtual ~Automation(); + // Creates a browser, using the specified |browser_exe| and |user_data_dir|. + void InitWithBrowserPath(const FilePath& browser_exe, + const FilePath& user_data_dir, + const CommandLine& options, + Error** error); + // Start the system's default Chrome binary. - void Init(const BrowserOptions& options, Error** error); + void Init(const CommandLine& options, + const FilePath& user_data_dir, + Error** error); // Terminates this session and disconnects its automation proxy. After // invoking this method, the Automation can safely be deleted. diff --git a/chrome/test/webdriver/commands/create_session.cc b/chrome/test/webdriver/commands/create_session.cc index adc8d28..60b7809 100644 --- a/chrome/test/webdriver/commands/create_session.cc +++ b/chrome/test/webdriver/commands/create_session.cc @@ -73,11 +73,7 @@ void CreateSession::ExecutePost(Response* const response) { return; } - Automation::BrowserOptions browser_options; - FilePath::StringType path; - if (capabilities->GetStringWithoutPathExpansion("chrome.binary", &path)) - browser_options.cmdline = CommandLine(FilePath(path)); - + CommandLine command_line_options(CommandLine::NO_PROGRAM); ListValue* switches = NULL; const char* kCustomSwitchesKey = "chrome.switches"; if (capabilities->GetListWithoutPathExpansion(kCustomSwitchesKey, @@ -97,11 +93,11 @@ void CreateSession::ExecutePost(Response* const response) { kBadRequest, "Custom switch is not a string")); return; } - browser_options.cmdline.AppendSwitchNative( + command_line_options.AppendSwitchNative( switch_string.substr(0, separator_index), switch_string_native.substr(separator_index + 1)); } else { - browser_options.cmdline.AppendSwitch(switch_string); + command_line_options.AppendSwitch(switch_string); } } } else if (capabilities->HasKey(kCustomSwitchesKey)) { @@ -109,16 +105,14 @@ void CreateSession::ExecutePost(Response* const response) { kBadRequest, "Custom switches must be a list")); return; } - Value* verbose_value; if (capabilities->GetWithoutPathExpansion("chrome.verbose", &verbose_value)) { - bool verbose = false; - if (verbose_value->GetAsBoolean(&verbose)) { + bool verbose; + if (verbose_value->GetAsBoolean(&verbose) && verbose) { // Since logging is shared among sessions, if any session requests verbose // logging, verbose logging will be enabled for all sessions. It is not // possible to turn it off. - if (verbose) - logging::SetMinLogLevel(logging::LOG_INFO); + logging::SetMinLogLevel(logging::LOG_INFO); } else { response->SetError(new Error( kBadRequest, "verbose must be a boolean true or false")); @@ -126,8 +120,10 @@ void CreateSession::ExecutePost(Response* const response) { } } - capabilities->GetStringWithoutPathExpansion( - "chrome.channel", &browser_options.channel_id); + FilePath browser_exe; + FilePath::StringType path; + if (capabilities->GetStringWithoutPathExpansion("chrome.binary", &path)) + browser_exe = FilePath(path); ScopedTempDir temp_profile_dir; FilePath temp_user_data_dir; @@ -190,13 +186,13 @@ void CreateSession::ExecutePost(Response* const response) { return; } - Session::Options session_options; + Session::Options options; Error* error = NULL; error = GetBooleanCapability(capabilities, "chrome.nativeEvents", - &session_options.use_native_events); + &options.use_native_events); if (!error) { error = GetBooleanCapability(capabilities, "chrome.loadAsync", - &session_options.load_async); + &options.load_async); } if (error) { response->SetError(error); @@ -204,8 +200,10 @@ void CreateSession::ExecutePost(Response* const response) { } // Session manages its own liftime, so do not call delete. - Session* session = new Session(session_options); - error = session->Init(browser_options); + Session* session = new Session(options); + error = session->Init(browser_exe, + temp_user_data_dir, + command_line_options); if (error) { response->SetError(error); return; diff --git a/chrome/test/webdriver/session.cc b/chrome/test/webdriver/session.cc index bbfdc49..b43b432 100644 --- a/chrome/test/webdriver/session.cc +++ b/chrome/test/webdriver/session.cc @@ -77,7 +77,9 @@ Session::~Session() { SessionManager::GetInstance()->Remove(id_); } -Error* Session::Init(const Automation::BrowserOptions& options) { +Error* Session::Init(const FilePath& browser_exe, + const FilePath& user_data_dir, + const CommandLine& options) { if (!thread_.Start()) { delete this; return new Error(kUnknownError, "Cannot start session thread"); @@ -87,6 +89,8 @@ Error* Session::Init(const Automation::BrowserOptions& options) { RunSessionTask(NewRunnableMethod( this, &Session::InitOnSessionThread, + browser_exe, + user_data_dir, options, &error)); if (error) @@ -1120,11 +1124,18 @@ void Session::RunSessionTaskOnSessionThread(Task* task, done_event->Signal(); } - -void Session::InitOnSessionThread(const Automation::BrowserOptions& options, +void Session::InitOnSessionThread(const FilePath& browser_exe, + const FilePath& user_data_dir, + const CommandLine& options, Error** error) { automation_.reset(new Automation()); - automation_->Init(options, error); + if (browser_exe.empty()) { + automation_->Init(options, user_data_dir, error); + } else { + automation_->InitWithBrowserPath( + browser_exe, user_data_dir, options, error); + } + if (*error) return; diff --git a/chrome/test/webdriver/session.h b/chrome/test/webdriver/session.h index b1018f2..881263d 100644 --- a/chrome/test/webdriver/session.h +++ b/chrome/test/webdriver/session.h @@ -79,7 +79,9 @@ class Session { // It |user_data_dir| is empty, it will use a temporary dir. // Returns true on success. On failure, the session will delete // itself and return an error code. - Error* Init(const Automation::BrowserOptions& options); + Error* Init(const FilePath& browser_exe, + const FilePath& user_data_dir, + const CommandLine& options); // Should be called before executing a command. Performs necessary waits // and frame switching. @@ -327,7 +329,9 @@ class Session { void RunSessionTaskOnSessionThread( Task* task, base::WaitableEvent* done_event); - void InitOnSessionThread(const Automation::BrowserOptions& options, + void InitOnSessionThread(const FilePath& browser_exe, + const FilePath& user_data_dir, + const CommandLine& options, Error** error); void TerminateOnSessionThread(); |