summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-02 08:29:02 +0000
committerkkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-02 08:29:02 +0000
commit25a1de62bfc96c9e0a3ee31cda8149250fc55c8a (patch)
tree56e267edb6ae25e0194f15b315afd107b5fe83fa
parenta97b4b3ede0e2140f38ea7bccf65f1b5ff0b8acc (diff)
downloadchromium_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.py11
-rwxr-xr-xchrome/test/webdriver/chromedriver_tests.py28
-rw-r--r--chrome/test/webdriver/dispatch.cc50
-rw-r--r--chrome/test/webdriver/dispatch.h41
-rw-r--r--chrome/test/webdriver/dispatch_unittest.cc68
-rw-r--r--chrome/test/webdriver/server.cc142
-rw-r--r--chrome/test/webdriver/session_manager.cc12
-rw-r--r--chrome/test/webdriver/session_manager.h5
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, &parameters,
+ &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, &parameters,
+ &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);