diff options
author | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-02 08:29:02 +0000 |
---|---|---|
committer | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-02 08:29:02 +0000 |
commit | 25a1de62bfc96c9e0a3ee31cda8149250fc55c8a (patch) | |
tree | 56e267edb6ae25e0194f15b315afd107b5fe83fa | |
parent | a97b4b3ede0e2140f38ea7bccf65f1b5ff0b8acc (diff) | |
download | chromium_src-25a1de62bfc96c9e0a3ee31cda8149250fc55c8a.zip chromium_src-25a1de62bfc96c9e0a3ee31cda8149250fc55c8a.tar.gz chromium_src-25a1de62bfc96c9e0a3ee31cda8149250fc55c8a.tar.bz2 |
Adding a command line switch for configuring the chromedriver to respond to commands sent relative to a path other than "/". This is a work-around for clients that have hard-coded logic expecting all of the WebDriver command handlers to be relative to "/wd/hub" (which is the path used by WebDriver's server jar).
BUG=none
TEST=none
Patch by jleyba@chromium.org
Original review at http://codereview.chromium.org/6592086
Review URL: http://codereview.chromium.org/6598090
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@76517 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/test/webdriver/chromedriver_launcher.py | 11 | ||||
-rwxr-xr-x | chrome/test/webdriver/chromedriver_tests.py | 28 | ||||
-rw-r--r-- | chrome/test/webdriver/dispatch.cc | 50 | ||||
-rw-r--r-- | chrome/test/webdriver/dispatch.h | 41 | ||||
-rw-r--r-- | chrome/test/webdriver/dispatch_unittest.cc | 68 | ||||
-rw-r--r-- | chrome/test/webdriver/server.cc | 142 | ||||
-rw-r--r-- | chrome/test/webdriver/session_manager.cc | 12 | ||||
-rw-r--r-- | chrome/test/webdriver/session_manager.h | 5 |
8 files changed, 261 insertions, 96 deletions
diff --git a/chrome/test/webdriver/chromedriver_launcher.py b/chrome/test/webdriver/chromedriver_launcher.py index 97b309a..3390674 100644 --- a/chrome/test/webdriver/chromedriver_launcher.py +++ b/chrome/test/webdriver/chromedriver_launcher.py @@ -22,17 +22,19 @@ import urllib2 class ChromeDriverLauncher: """Launches and kills the ChromeDriver process.""" - def __init__(self, exe_path=None, root_path=None, port=None): + def __init__(self, exe_path=None, root_path=None, port=None, url_base=None): """Initializes a new launcher. Args: exe_path: path to the ChromeDriver executable root_path: base path from which ChromeDriver webserver will serve files port: port that ChromeDriver will listen on + url_base: base URL which ChromeDriver webserver will listen from """ self._exe_path = exe_path self._root_path = root_path self._port = port + self._url_base = url_base if self._exe_path is None: self._exe_path = ChromeDriverLauncher.LocateExe() if self._exe_path is None: @@ -129,6 +131,8 @@ class ChromeDriverLauncher: chromedriver_args = [self._exe_path, '--root=%s' % self._root_path] if self._port is not None: chromedriver_args += ['--port=%d' % self._port] + if self._url_base is not None: + chromedriver_args += ['--url-base=%s' % self._url_base] proc = subprocess.Popen(chromedriver_args, stdout=subprocess.PIPE) if proc is None: @@ -189,7 +193,10 @@ class ChromeDriverLauncher: self._process = None def GetURL(self): - return 'http://localhost:' + str(self._port) + url = 'http://localhost:' + str(self._port) + if self._url_base: + url += self._url_base + return url def GetPort(self): return self._port diff --git a/chrome/test/webdriver/chromedriver_tests.py b/chrome/test/webdriver/chromedriver_tests.py index e0c36ff..c7d7b20 100755 --- a/chrome/test/webdriver/chromedriver_tests.py +++ b/chrome/test/webdriver/chromedriver_tests.py @@ -251,6 +251,34 @@ class MouseTest(unittest.TestCase): self.assertTrue(self._driver.execute_script('return window.success')) +class UrlBaseTest(unittest.TestCase): + """Tests that the server can be configured for a different URL base.""" + + def setUp(self): + self._launcher = ChromeDriverLauncher(url_base='/wd/hub') + + def tearDown(self): + self._launcher.Kill() + + def testCreatingSessionShouldRedirectToCorrectURL(self): + request_url = self._launcher.GetURL() + '/session' + response = SendRequest(request_url, method='POST', data='{}') + self.assertEquals(200, response.code) + self.session_url = response.geturl() # TODO(jleyba): verify this URL? + + data = json.loads(response.read()) + self.assertTrue(isinstance(data, dict)) + self.assertEquals(0, data['status']) + + url_parts = urlparse.urlparse(self.session_url)[2].split('/') + self.assertEquals(5, len(url_parts)) + self.assertEquals('', url_parts[0]) + self.assertEquals('wd', url_parts[1]) + self.assertEquals('hub', url_parts[2]) + self.assertEquals('session', url_parts[3]) + self.assertEquals(data['sessionId'], url_parts[4]) + + if __name__ == '__main__': unittest.main(module='chromedriver_tests', testRunner=GTestTextTestRunner(verbosity=1)) diff --git a/chrome/test/webdriver/dispatch.cc b/chrome/test/webdriver/dispatch.cc index 26b9738..b4075fc 100644 --- a/chrome/test/webdriver/dispatch.cc +++ b/chrome/test/webdriver/dispatch.cc @@ -8,10 +8,12 @@ #include <string> #include <vector> +#include "base/format_macros.h" #include "base/logging.h" #include "base/message_loop_proxy.h" #include "base/string_split.h" #include "base/string_util.h" +#include "base/stringprintf.h" #include "base/synchronization/waitable_event.h" #include "base/threading/thread.h" #include "chrome/test/webdriver/http_response.h" @@ -48,6 +50,36 @@ void DispatchCommand(Command* const command, } } +void Shutdown(struct mg_connection* connection, + const struct mg_request_info* request_info, + void* user_data) { + base::WaitableEvent* shutdown_event = + reinterpret_cast<base::WaitableEvent*>(user_data); + mg_printf(connection, "HTTP/1.1 200 OK\r\n\r\n"); + shutdown_event->Signal(); +} + +void SendNotImplementedError(struct mg_connection* connection, + const struct mg_request_info* request_info, + void* user_data) { + // Send a well-formed WebDriver JSON error response to ensure clients + // handle it correctly. + std::string body = base::StringPrintf( + "{\"status\":%d,\"value\":{\"message\":" + "\"Command has not been implemented yet: %s %s\"}}", + kUnknownCommand, request_info->request_method, request_info->uri); + + std::string header = base::StringPrintf( + "HTTP/1.1 501 Not Implemented\r\n" + "Content-Type:application/json\r\n" + "Content-Length:%" PRIuS "\r\n" + "\r\n", body.length()); + + LOG(ERROR) << header << body; + mg_write(connection, header.data(), header.length()); + mg_write(connection, body.data(), body.length()); +} + } // namespace namespace internal { @@ -163,6 +195,9 @@ bool ParseRequestInfo(const struct mg_request_info* const request_info, *method = "POST"; std::string uri(request_info->uri); + SessionManager* manager = SessionManager::GetInstance(); + uri = uri.substr(manager->url_base().length()); + base::SplitString(uri, '/', path_segments); if (*method == "POST" && request_info->post_data_len > 0) { @@ -209,4 +244,19 @@ void DispatchHelper(Command* command_ptr, } // namespace internal +Dispatcher::Dispatcher(struct mg_context* context, const std::string& root) + : context_(context), root_(root) {} + +Dispatcher::~Dispatcher() {} + +void Dispatcher::AddShutdown(const std::string& pattern, + base::WaitableEvent* shutdown_event) { + mg_set_uri_callback(context_, (root_ + pattern).c_str(), &Shutdown, NULL); +} + +void Dispatcher::SetNotImplemented(const std::string& pattern) { + mg_set_uri_callback(context_, (root_ + pattern).c_str(), + &SendNotImplementedError, NULL); +} + } // namespace webdriver diff --git a/chrome/test/webdriver/dispatch.h b/chrome/test/webdriver/dispatch.h index c119e9c..b3ee57c 100644 --- a/chrome/test/webdriver/dispatch.h +++ b/chrome/test/webdriver/dispatch.h @@ -8,11 +8,16 @@ #include <string> #include <vector> +#include "base/basictypes.h" #include "chrome/test/webdriver/commands/response.h" #include "third_party/mongoose/mongoose.h" class DictionaryValue; +namespace base { +class WaitableEvent; +} + namespace webdriver { class Command; @@ -74,6 +79,42 @@ void Dispatch(struct mg_connection* connection, response); } +class Dispatcher { + public: + // Creates a new dispatcher that will register all URL callbacks with the + // given |context|. Each callback's pattern will be prefixed with the provided + // |root|. + Dispatcher(struct mg_context* context, const std::string& root); + ~Dispatcher(); + + // Registers a callback for a WebDriver command using the given URL |pattern|. + // The |CommandType| must be a subtype of |webdriver::Command|. + template<typename CommandType> + void Add(const std::string& pattern); + + // Registers a callback that will shutdown the server. When any HTTP request + // is received at this URL |pattern|, the |shutdown_event| will be signaled. + void AddShutdown(const std::string& pattern, + base::WaitableEvent* shutdown_event); + + // Registers a callback that will always respond with a + // "HTTP/1.1 501 Not Implemented" message. + void SetNotImplemented(const std::string& pattern); + + private: + struct mg_context* context_; + const std::string root_; + + DISALLOW_COPY_AND_ASSIGN(Dispatcher); +}; + + +template <typename CommandType> +void Dispatcher::Add(const std::string& pattern) { + mg_set_uri_callback(context_, (root_ + pattern).c_str(), + &Dispatch<CommandType>, NULL); +} + } // namespace webdriver #endif // CHROME_TEST_WEBDRIVER_DISPATCH_H_ diff --git a/chrome/test/webdriver/dispatch_unittest.cc b/chrome/test/webdriver/dispatch_unittest.cc index 6da3288..e84dd11 100644 --- a/chrome/test/webdriver/dispatch_unittest.cc +++ b/chrome/test/webdriver/dispatch_unittest.cc @@ -3,14 +3,16 @@ // found in the LICENSE file. #include "base/format_macros.h" +#include "base/json/json_reader.h" #include "base/scoped_ptr.h" #include "base/stringprintf.h" #include "base/values.h" -#include "base/json/json_reader.h" +#include "chrome/test/webdriver/commands/response.h" #include "chrome/test/webdriver/dispatch.h" #include "chrome/test/webdriver/http_response.h" -#include "chrome/test/webdriver/commands/response.h" +#include "chrome/test/webdriver/session_manager.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/mongoose/mongoose.h" namespace webdriver { @@ -151,4 +153,66 @@ TEST(DispatchTest, ReturnsCommandResponseAsJson) { EXPECT_EQ("foobar", value); } +class ParseRequestInfoTest : public testing::Test { + public: + static char kGet[]; + static char kTestPath[]; + + ParseRequestInfoTest() {} + virtual ~ParseRequestInfoTest() {} + + virtual void TearDown() { + SessionManager::GetInstance()->set_url_base(""); + } + + private: + DISALLOW_COPY_AND_ASSIGN(ParseRequestInfoTest); +}; + +char ParseRequestInfoTest::kGet[] = "GET"; +char ParseRequestInfoTest::kTestPath[] = "/foo/bar/baz"; + +TEST_F(ParseRequestInfoTest, ParseRequestWithEmptyUrlBase) { + struct mg_request_info request_info; + request_info.request_method = kGet; + request_info.uri = kTestPath; + + std::string method; + std::vector<std::string> path_segments; + DictionaryValue* parameters; + Response response; + + SessionManager::GetInstance()->set_url_base(""); + EXPECT_TRUE(internal::ParseRequestInfo(&request_info, &method, + &path_segments, ¶meters, + &response)); + EXPECT_EQ("GET", method); + ASSERT_EQ(4u, path_segments.size()); + EXPECT_EQ("", path_segments[0]); + EXPECT_EQ("foo", path_segments[1]); + EXPECT_EQ("bar", path_segments[2]); + EXPECT_EQ("baz", path_segments[3]); +} + +TEST_F(ParseRequestInfoTest, ParseRequestStripsNonEmptyUrlBaseFromPath) { + struct mg_request_info request_info; + request_info.request_method = kGet; + request_info.uri = kTestPath; + + std::string method; + std::vector<std::string> path_segments; + DictionaryValue* parameters; + Response response; + + SessionManager::GetInstance()->set_url_base("/foo"); + EXPECT_TRUE(internal::ParseRequestInfo(&request_info, &method, + &path_segments, ¶meters, + &response)); + EXPECT_EQ("GET", method); + ASSERT_EQ(3u, path_segments.size()); + EXPECT_EQ("", path_segments[0]); + EXPECT_EQ("bar", path_segments[1]); + EXPECT_EQ("baz", path_segments[2]); +} + } // namespace webdriver diff --git a/chrome/test/webdriver/server.cc b/chrome/test/webdriver/server.cc index ce68dd6..fede212 100644 --- a/chrome/test/webdriver/server.cc +++ b/chrome/test/webdriver/server.cc @@ -16,13 +16,11 @@ #include "base/command_line.h" #include "base/file_path.h" #include "base/file_util.h" -#include "base/format_macros.h" #include "base/logging.h" #include "base/string_number_conversions.h" #include "base/scoped_ptr.h" #include "base/string_split.h" #include "base/string_util.h" -#include "base/stringprintf.h" #include "base/synchronization/waitable_event.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" @@ -75,107 +73,66 @@ signal_handler(int sig_num) { namespace webdriver { -void Shutdown(struct mg_connection* connection, - const struct mg_request_info* request_info, - void* user_data) { - base::WaitableEvent* shutdown_event = - reinterpret_cast<base::WaitableEvent*>(user_data); - mg_printf(connection, "HTTP/1.1 200 OK\r\n\r\n"); - shutdown_event->Signal(); -} - -void SendNotImplementedError(struct mg_connection* connection, - const struct mg_request_info* request_info, - void* user_data) { - // Send a well-formed WebDriver JSON error response to ensure clients - // handle it correctly. - std::string body = base::StringPrintf( - "{\"status\":%d,\"value\":{\"message\":" - "\"Command has not been implemented yet: %s %s\"}}", - kUnknownCommand, request_info->request_method, request_info->uri); - - std::string header = base::StringPrintf( - "HTTP/1.1 501 Not Implemented\r\n" - "Content-Type:application/json\r\n" - "Content-Length:%" PRIuS "\r\n" - "\r\n", body.length()); - - LOG(ERROR) << header << body; - mg_write(connection, header.data(), header.length()); - mg_write(connection, body.data(), body.length()); -} - - -template <typename CommandType> -void SetCallback(struct mg_context* ctx, const char* pattern) { - mg_set_uri_callback(ctx, pattern, &Dispatch<CommandType>, NULL); -} - -void SetNotImplemented(struct mg_context* ctx, const char* pattern) { - mg_set_uri_callback(ctx, pattern, &SendNotImplementedError, NULL); -} - -void InitCallbacks(struct mg_context* ctx, +void InitCallbacks(struct mg_context* ctx, Dispatcher* dispatcher, base::WaitableEvent* shutdown_event) { - mg_set_uri_callback(ctx, "/shutdown", &Shutdown, shutdown_event); - - SetCallback<CreateSession>(ctx, "/session"); - SetCallback<BackCommand>(ctx, "/session/*/back"); - SetCallback<ExecuteCommand>(ctx, "/session/*/execute"); - SetCallback<ForwardCommand>(ctx, "/session/*/forward"); - SetCallback<SwitchFrameCommand>(ctx, "/session/*/frame"); - SetCallback<RefreshCommand>(ctx, "/session/*/refresh"); - SetCallback<SourceCommand>(ctx, "/session/*/source"); - SetCallback<SpeedCommand>(ctx, "/session/*/speed"); - SetCallback<TitleCommand>(ctx, "/session/*/title"); - SetCallback<URLCommand>(ctx, "/session/*/url"); - SetCallback<WindowCommand>(ctx, "/session/*/window"); - SetCallback<WindowHandleCommand>(ctx, "/session/*/window_handle"); - SetCallback<WindowHandlesCommand>(ctx, "/session/*/window_handles"); - SetCallback<ImplicitWaitCommand>(ctx, "/session/*/timeouts/implicit_wait"); + dispatcher->AddShutdown("/shutdown", shutdown_event); + + dispatcher->Add<CreateSession>( "/session"); + dispatcher->Add<BackCommand>( "/session/*/back"); + dispatcher->Add<ExecuteCommand>( "/session/*/execute"); + dispatcher->Add<ForwardCommand>( "/session/*/forward"); + dispatcher->Add<SwitchFrameCommand>( "/session/*/frame"); + dispatcher->Add<RefreshCommand>( "/session/*/refresh"); + dispatcher->Add<SourceCommand>( "/session/*/source"); + dispatcher->Add<SpeedCommand>( "/session/*/speed"); + dispatcher->Add<TitleCommand>( "/session/*/title"); + dispatcher->Add<URLCommand>( "/session/*/url"); + dispatcher->Add<WindowCommand>( "/session/*/window"); + dispatcher->Add<WindowHandleCommand>( "/session/*/window_handle"); + dispatcher->Add<WindowHandlesCommand>("/session/*/window_handles"); + dispatcher->Add<ImplicitWaitCommand>( "/session/*/timeouts/implicit_wait"); // Cookie functions. - SetCallback<CookieCommand>(ctx, "/session/*/cookie"); - SetCallback<NamedCookieCommand>(ctx, "/session/*/cookie/*"); + dispatcher->Add<CookieCommand>( "/session/*/cookie"); + dispatcher->Add<NamedCookieCommand>("/session/*/cookie/*"); // WebElement commands - SetCallback<FindOneElementCommand>(ctx, "/session/*/element"); - SetCallback<FindManyElementsCommand>(ctx, "/session/*/elements"); - SetCallback<ActiveElementCommand>(ctx, "/session/*/element/active"); - SetCallback<FindOneElementCommand>(ctx, "/session/*/element/*/element"); - SetCallback<FindManyElementsCommand>(ctx, "/session/*/elements/*/elements"); - SetCallback<ElementAttributeCommand>(ctx, - "/session/*/element/*/attribute/*"); - SetCallback<ElementCssCommand>(ctx, "/session/*/element/*/css/*"); - SetCallback<ElementClearCommand>(ctx, "/session/*/element/*/clear"); - SetCallback<ElementDisplayedCommand>(ctx, "/session/*/element/*/displayed"); - SetCallback<ElementEnabledCommand>(ctx, "/session/*/element/*/enabled"); - SetCallback<ElementEqualsCommand>(ctx, "/session/*/element/*/equals/*"); - SetCallback<ElementLocationCommand>(ctx, "/session/*/element/*/location"); - SetCallback<ElementLocationInViewCommand>(ctx, + dispatcher->Add<FindOneElementCommand>( "/session/*/element"); + dispatcher->Add<FindManyElementsCommand>("/session/*/elements"); + dispatcher->Add<ActiveElementCommand>( "/session/*/element/active"); + dispatcher->Add<FindOneElementCommand>( "/session/*/element/*/element"); + dispatcher->Add<FindManyElementsCommand>("/session/*/elements/*/elements"); + dispatcher->Add<ElementAttributeCommand>("/session/*/element/*/attribute/*"); + dispatcher->Add<ElementCssCommand>( "/session/*/element/*/css/*"); + dispatcher->Add<ElementClearCommand>( "/session/*/element/*/clear"); + dispatcher->Add<ElementDisplayedCommand>("/session/*/element/*/displayed"); + dispatcher->Add<ElementEnabledCommand>( "/session/*/element/*/enabled"); + dispatcher->Add<ElementEqualsCommand>( "/session/*/element/*/equals/*"); + dispatcher->Add<ElementLocationCommand>( "/session/*/element/*/location"); + dispatcher->Add<ElementLocationInViewCommand>( "/session/*/element/*/location_in_view"); - SetCallback<ElementNameCommand>(ctx, "/session/*/element/*/name"); - SetCallback<ElementSelectedCommand>(ctx, "/session/*/element/*/selected"); - SetCallback<ElementSizeCommand>(ctx, "/session/*/element/*/size"); - SetCallback<ElementSubmitCommand>(ctx, "/session/*/element/*/submit"); - SetCallback<ElementTextCommand>(ctx, "/session/*/element/*/text"); - SetCallback<ElementToggleCommand>(ctx, "/session/*/element/*/toggle"); - SetCallback<ElementValueCommand>(ctx, "/session/*/element/*/value"); + dispatcher->Add<ElementNameCommand>( "/session/*/element/*/name"); + dispatcher->Add<ElementSelectedCommand>("/session/*/element/*/selected"); + dispatcher->Add<ElementSizeCommand>( "/session/*/element/*/size"); + dispatcher->Add<ElementSubmitCommand>( "/session/*/element/*/submit"); + dispatcher->Add<ElementTextCommand>( "/session/*/element/*/text"); + dispatcher->Add<ElementToggleCommand>( "/session/*/element/*/toggle"); + dispatcher->Add<ElementValueCommand>( "/session/*/element/*/value"); // Mouse Commands - SetCallback<ClickCommand>(ctx, "/session/*/element/*/click"); - SetCallback<DragCommand>(ctx, "/session/*/element/*/drag"); - SetCallback<HoverCommand>(ctx, "/session/*/element/*/hover"); + dispatcher->Add<ClickCommand>("/session/*/element/*/click"); + dispatcher->Add<DragCommand>( "/session/*/element/*/drag"); + dispatcher->Add<HoverCommand>("/session/*/element/*/hover"); // Commands that have not been implemented yet. We list these out explicitly // so that tests that attempt to use them fail with a meaningful error. - SetNotImplemented(ctx, "/session/*/execute_async"); - SetNotImplemented(ctx, "/session/*/timeouts/async_script"); - SetNotImplemented(ctx, "/session/*/screenshot"); + dispatcher->SetNotImplemented("/session/*/execute_async"); + dispatcher->SetNotImplemented("/session/*/timeouts/async_script"); + dispatcher->SetNotImplemented("/session/*/screenshot"); // Since the /session/* is a wild card that would match the above URIs, this // line MUST be the last registered URI with the server. - SetCallback<SessionWithID>(ctx, "/session/*"); + dispatcher->Add<SessionWithID>("/session/*"); } } // namespace webdriver @@ -224,6 +181,7 @@ int main(int argc, char *argv[]) { std::string port = "9515"; std::string root; FilePath chrome_dir; + std::string url_base; if (cmd_line->HasSwitch("port")) port = cmd_line->GetSwitchValueASCII("port"); // By default, mongoose serves files from the current working directory. The @@ -232,9 +190,12 @@ int main(int argc, char *argv[]) { root = cmd_line->GetSwitchValueASCII("root"); if (cmd_line->HasSwitch("chrome-dir")) chrome_dir = cmd_line->GetSwitchValuePath("chrome-dir"); + if (cmd_line->HasSwitch("url-base")) + url_base = cmd_line->GetSwitchValueASCII("url-base"); webdriver::SessionManager* manager = webdriver::SessionManager::GetInstance(); manager->set_port(port); + manager->set_url_base(url_base); if (!chrome_dir.empty()) { if (!file_util::DirectoryExists(chrome_dir)) { std::cout << "Given Chrome directory is inaccessible or does not exist: " @@ -261,7 +222,8 @@ int main(int argc, char *argv[]) { #endif } - webdriver::InitCallbacks(ctx, &shutdown_event); + webdriver::Dispatcher dispatcher(ctx, url_base); + webdriver::InitCallbacks(ctx, &dispatcher, &shutdown_event); // The tests depend on parsing the first line ChromeDriver outputs, // so all other logging should happen after this. diff --git a/chrome/test/webdriver/session_manager.cc b/chrome/test/webdriver/session_manager.cc index 9df08c9..f37611b 100644 --- a/chrome/test/webdriver/session_manager.cc +++ b/chrome/test/webdriver/session_manager.cc @@ -27,7 +27,7 @@ std::string SessionManager::GetAddress() { if (hostname.empty()) { hostname = "localhost"; } - return hostname + ":" + port_; + return hostname + ":" + port_ + url_base_; } void SessionManager::Add(Session* session) { @@ -69,6 +69,14 @@ void SessionManager::set_port(const std::string& port) { port_ = port; } +void SessionManager::set_url_base(const std::string& url_base) { + url_base_ = url_base; +} + +std::string SessionManager::url_base() const { + return url_base_; +} + void SessionManager::set_chrome_dir(const FilePath& chrome_dir) { chrome_dir_ = chrome_dir; } @@ -77,7 +85,7 @@ FilePath SessionManager::chrome_dir() const { return chrome_dir_; } -SessionManager::SessionManager() : port_("") {} +SessionManager::SessionManager() : port_(""), url_base_("") {} SessionManager::~SessionManager() {} diff --git a/chrome/test/webdriver/session_manager.h b/chrome/test/webdriver/session_manager.h index cec37d9..a99d989 100644 --- a/chrome/test/webdriver/session_manager.h +++ b/chrome/test/webdriver/session_manager.h @@ -34,6 +34,10 @@ class SessionManager { Session* GetSession(const std::string& id) const; void set_port(const std::string& port); + + void set_url_base(const std::string& url_base); + std::string url_base() const; + void set_chrome_dir(const FilePath& chrome_dir); FilePath chrome_dir() const; @@ -45,6 +49,7 @@ class SessionManager { std::map<std::string, Session*> map_; mutable base::Lock map_lock_; std::string port_; + std::string url_base_; FilePath chrome_dir_; DISALLOW_COPY_AND_ASSIGN(SessionManager); |