diff options
| author | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-28 02:12:42 +0000 |
|---|---|---|
| committer | kkania@chromium.org <kkania@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-28 02:12:42 +0000 |
| commit | 2f2186cf42eac670305acf001a41d5780440b932 (patch) | |
| tree | cb1794b571c42290e84d16747d6dd9b97f780759 | |
| parent | b3e21e72aade511ae617f668891b2294d2bff20e (diff) | |
| download | chromium_src-2f2186cf42eac670305acf001a41d5780440b932.zip chromium_src-2f2186cf42eac670305acf001a41d5780440b932.tar.gz chromium_src-2f2186cf42eac670305acf001a41d5780440b932.tar.bz2 | |
Implement the webdriver window sizing commands.
BUG=107630
TEST=none
Review URL: http://codereview.chromium.org/9288051
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@119555 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 453 insertions, 29 deletions
diff --git a/chrome/browser/automation/automation_provider_json.cc b/chrome/browser/automation/automation_provider_json.cc index 1c1e3bd..c43ad04 100644 --- a/chrome/browser/automation/automation_provider_json.cc +++ b/chrome/browser/automation/automation_provider_json.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -42,14 +42,14 @@ void AutomationJSONReply::SendSuccess(const Value* value) { } void AutomationJSONReply::SendError(const std::string& error_message) { - SendErrorInternal(Error(error_message)); + SendError(Error(error_message)); } void AutomationJSONReply::SendErrorCode(ErrorCode code) { - SendErrorInternal(Error(code)); + SendError(Error(code)); } -void AutomationJSONReply::SendErrorInternal(const Error& error) { +void AutomationJSONReply::SendError(const Error& error) { DCHECK(message_) << "Resending reply for JSON automation request"; base::DictionaryValue dict; diff --git a/chrome/browser/automation/automation_provider_json.h b/chrome/browser/automation/automation_provider_json.h index 9ca6e906..10e9077 100644 --- a/chrome/browser/automation/automation_provider_json.h +++ b/chrome/browser/automation/automation_provider_json.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -55,9 +55,10 @@ class AutomationJSONReply { // associated error message. void SendErrorCode(automation::ErrorCode code); - private: - void SendErrorInternal(const automation::Error& error); + // Send an automation error. + void SendError(const automation::Error& error); + private: AutomationProvider* provider_; IPC::Message* message_; }; diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index ed0f89b..d883808 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -120,6 +120,7 @@ #include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_view_host.h" +#include "content/browser/renderer_host/render_widget_host_view.h" #include "content/browser/tab_contents/interstitial_page.h" #include "content/public/browser/browser_child_process_host_iterator.h" #include "content/public/browser/child_process_data.h" @@ -2354,6 +2355,8 @@ void TestingAutomationProvider::SendJSONRequest(int handle, &TestingAutomationProvider::DoesAutomationObjectExist; handler_map["CloseTab"] = &TestingAutomationProvider::CloseTabJSON; + handler_map["SetViewBounds"] = + &TestingAutomationProvider::SetViewBounds; handler_map["WebkitMouseMove"] = &TestingAutomationProvider::WebkitMouseMove; handler_map["WebkitMouseClick"] = @@ -6308,7 +6311,8 @@ void TestingAutomationProvider::ExecuteJavascriptJSON( std::string error; RenderViewHost* render_view; if (!GetRenderViewFromJSONArgs(args, profile(), &render_view, &error)) { - AutomationJSONReply(this, reply_message).SendError(error); + AutomationJSONReply(this, reply_message).SendError( + Error(automation::kInvalidId, error)); return; } if (!args->GetString("frame_xpath", &frame_xpath)) { @@ -6598,6 +6602,28 @@ void TestingAutomationProvider::CloseTabJSON( reply.SendSuccess(NULL); } +void TestingAutomationProvider::SetViewBounds( + base::DictionaryValue* args, + IPC::Message* reply_message) { + AutomationJSONReply reply(this, reply_message); + int x, y, width, height; + if (!args->GetInteger("bounds.x", &x) || + !args->GetInteger("bounds.y", &y) || + !args->GetInteger("bounds.width", &width) || + !args->GetInteger("bounds.height", &height)) { + reply.SendError("Missing or invalid 'bounds'"); + return; + } + Browser* browser; + std::string error; + if (!GetBrowserFromJSONArgs(args, &browser, &error)) { + reply.SendError(Error(automation::kInvalidId, error)); + return; + } + browser->window()->SetBounds(gfx::Rect(x, y, width, height)); + reply.SendSuccess(NULL); +} + void TestingAutomationProvider::ActivateTabJSON( DictionaryValue* args, IPC::Message* reply_message) { diff --git a/chrome/browser/automation/testing_automation_provider.h b/chrome/browser/automation/testing_automation_provider.h index e6f9092..1b712e8 100644 --- a/chrome/browser/automation/testing_automation_provider.h +++ b/chrome/browser/automation/testing_automation_provider.h @@ -1096,6 +1096,21 @@ class TestingAutomationProvider : public AutomationProvider, // output: none void CloseTabJSON(base::DictionaryValue* args, IPC::Message* reply_message); + // Sets the specified web view bounds. + // The single |auto_id| must be given to specify the view. + // This method currently is only supported for tabs. + // Example: + // input: { "auto_id": { "type": 0, "id": "awoein" }, + // "bounds": { + // "x": 100, + // "y": 200, + // "width": 500, + // "height": 800 + // } + // } + // output: none + void SetViewBounds(base::DictionaryValue* args, IPC::Message* reply_message); + // Sends the WebKit events for a mouse click at a given coordinate. // The pair |windex| and |tab_index| or the single |auto_id| must be given // to specify the render view. diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 8cb9734..756e9ea 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1024,6 +1024,8 @@ 'test/webdriver/commands/webdriver_command.h', 'test/webdriver/commands/webelement_commands.cc', 'test/webdriver/commands/webelement_commands.h', + 'test/webdriver/commands/window_commands.cc', + 'test/webdriver/commands/window_commands.h', 'test/webdriver/frame_path.cc', 'test/webdriver/frame_path.h', 'test/webdriver/http_response.cc', diff --git a/chrome/common/automation_constants.cc b/chrome/common/automation_constants.cc index 0fbb0de..1b8d32d 100644 --- a/chrome/common/automation_constants.cc +++ b/chrome/common/automation_constants.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -32,6 +32,8 @@ const char* DefaultMessageForErrorCode(ErrorCode code) { return "No JavaScript modal dialog is open"; case kBlockedByModalDialog: return "Command blocked by an open modal dialog"; + case kInvalidId: + return "ID is invalid or does not refer to an existing object"; default: return "<unknown>"; } diff --git a/chrome/common/automation_constants.h b/chrome/common/automation_constants.h index ffb5754..bd4ec01 100644 --- a/chrome/common/automation_constants.h +++ b/chrome/common/automation_constants.h @@ -85,6 +85,8 @@ enum ErrorCode { // An open modal dialog blocked the operation. The operation may have // partially completed. kBlockedByModalDialog = 2, + // An ID was supplied that is invalid or does not refer to an existing object. + kInvalidId = 3, }; // Represents an automation error. Each error has a code and an error message. diff --git a/chrome/test/automation/automation_json_requests.cc b/chrome/test/automation/automation_json_requests.cc index a9e349c..af122f6 100644 --- a/chrome/test/automation/automation_json_requests.cc +++ b/chrome/test/automation/automation_json_requests.cc @@ -674,6 +674,26 @@ bool SendDragAndDropFilePathsJSONRequest( return SendAutomationJSONRequest(sender, dict, &reply_dict, error); } +bool SendSetViewBoundsJSONRequest( + AutomationMessageSender* sender, + const WebViewId& id, + int x, + int y, + int width, + int height, + automation::Error* error) { + DictionaryValue dict; + dict.SetString("command", "SetViewBounds"); + id.UpdateDictionary(&dict, "auto_id"); + dict.SetInteger("bounds.x", x); + dict.SetInteger("bounds.y", y); + dict.SetInteger("bounds.width", width); + dict.SetInteger("bounds.height", height); + + DictionaryValue reply_dict; + return SendAutomationJSONRequest(sender, dict, &reply_dict, error); +} + bool SendGetAppModalDialogMessageJSONRequest( AutomationMessageSender* sender, std::string* message, diff --git a/chrome/test/automation/automation_json_requests.h b/chrome/test/automation/automation_json_requests.h index 5d35400..1f71ccb 100644 --- a/chrome/test/automation/automation_json_requests.h +++ b/chrome/test/automation/automation_json_requests.h @@ -404,6 +404,16 @@ bool SendDragAndDropFilePathsJSONRequest( const std::vector<FilePath::StringType>& paths, automation::Error* error) WARN_UNUSED_RESULT; +// Requests to set the given view's bounds. Returns true on success. +bool SendSetViewBoundsJSONRequest( + AutomationMessageSender* sender, + const WebViewId& id, + int x, + int y, + int width, + int height, + automation::Error* error) WARN_UNUSED_RESULT; + // Requests to get the active JavaScript modal dialog's message. Returns true // on success. bool SendGetAppModalDialogMessageJSONRequest( diff --git a/chrome/test/webdriver/commands/chrome_commands.cc b/chrome/test/webdriver/commands/chrome_commands.cc index dca46ae..d12e071 100644 --- a/chrome/test/webdriver/commands/chrome_commands.cc +++ b/chrome/test/webdriver/commands/chrome_commands.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -246,7 +246,7 @@ void ViewsCommand::ExecuteGet(Response* const response) { for (size_t i = 0; i < views.size(); ++i) { DictionaryValue* dict = new DictionaryValue(); AutomationId id = views[i].view_id.GetId(); - dict->SetString("handle", JsonStringify(id.ToValue())); + dict->SetString("handle", WebViewIdToString(WebViewId::ForView(id))); dict->SetInteger("type", id.type()); if (!views[i].extension_id.empty()) dict->SetString("extension_id", views[i].extension_id); diff --git a/chrome/test/webdriver/commands/window_commands.cc b/chrome/test/webdriver/commands/window_commands.cc new file mode 100644 index 0000000..e799dd3 --- /dev/null +++ b/chrome/test/webdriver/commands/window_commands.cc @@ -0,0 +1,161 @@ +// Copyright (c) 2012 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. + +#include "chrome/test/webdriver/commands/window_commands.h" + +#include "base/values.h" +#include "chrome/test/webdriver/commands/response.h" +#include "chrome/test/webdriver/webdriver_error.h" +#include "chrome/test/webdriver/webdriver_session.h" +#include "chrome/test/webdriver/webdriver_util.h" + +using base::Value; + +namespace webdriver { + +namespace { + +bool GetWindowId(const std::string& window_id_string, + const WebViewId& current_id, + WebViewId* window_id, + Response* const response) { + if (window_id_string == "current") { + *window_id = current_id; + } else if (!StringToWebViewId(window_id_string, window_id)) { + response->SetError( + new Error(kBadRequest, "Invalid window ID")); + return false; + } + return true; +} + +} + +WindowSizeCommand::WindowSizeCommand( + const std::vector<std::string>& path_segments, + const base::DictionaryValue* parameters) + : WebDriverCommand(path_segments, parameters) { +} + +WindowSizeCommand::~WindowSizeCommand() { +} + +bool WindowSizeCommand::DoesGet() { + return true; +} + +bool WindowSizeCommand::DoesPost() { + return true; +} + +void WindowSizeCommand::ExecuteGet(Response* const response) { + // Path segment: "/session/$sessionId/window/$windowHandle/size" + WebViewId window_id; + WebViewId current_id = session_->current_target().view_id; + if (!GetWindowId(GetPathVariable(4), current_id, &window_id, response)) + return; + + Rect bounds; + Error* error = session_->GetWindowBounds(window_id, &bounds); + if (error) { + response->SetError(error); + return; + } + base::DictionaryValue* size = new base::DictionaryValue(); + size->SetInteger("width", bounds.width()); + size->SetInteger("height", bounds.height()); + response->SetValue(size); +} + +void WindowSizeCommand::ExecutePost(Response* const response) { + // Path segment: "/session/$sessionId/window/$windowHandle/size" + WebViewId window_id; + WebViewId current_id = session_->current_target().view_id; + if (!GetWindowId(GetPathVariable(4), current_id, &window_id, response)) + return; + + int width, height; + if (!GetIntegerParameter("width", &width) || + !GetIntegerParameter("height", &height)) { + response->SetError(new Error( + kBadRequest, + "Missing or invalid 'width' or 'height' parameters")); + return; + } + Rect bounds; + Error* error = session_->GetWindowBounds(window_id, &bounds); + if (!error) { + bounds = Rect(bounds.origin(), Size(width, height)); + error = session_->SetWindowBounds(window_id, bounds); + } + if (error) { + response->SetError(error); + return; + } +} + +WindowPositionCommand::WindowPositionCommand( + const std::vector<std::string>& path_segments, + const base::DictionaryValue* parameters) + : WebDriverCommand(path_segments, parameters) { +} + +WindowPositionCommand::~WindowPositionCommand() { +} + +bool WindowPositionCommand::DoesGet() { + return true; +} + +bool WindowPositionCommand::DoesPost() { + return true; +} + +void WindowPositionCommand::ExecuteGet(Response* const response) { + // Path segment: "/session/$sessionId/window/$windowHandle/position" + WebViewId window_id; + WebViewId current_id = session_->current_target().view_id; + if (!GetWindowId(GetPathVariable(4), current_id, &window_id, response)) + return; + + Rect bounds; + Error* error = session_->GetWindowBounds(window_id, &bounds); + if (error) { + response->SetError(error); + return; + } + base::DictionaryValue* size = new base::DictionaryValue(); + size->SetInteger("x", bounds.x()); + size->SetInteger("y", bounds.y()); + response->SetValue(size); +} + +void WindowPositionCommand::ExecutePost(Response* const response) { + // Path segment: "/session/$sessionId/window/$windowHandle/size" + WebViewId window_id; + WebViewId current_id = session_->current_target().view_id; + if (!GetWindowId(GetPathVariable(4), current_id, &window_id, response)) + return; + + int x, y; + if (!GetIntegerParameter("x", &x) || + !GetIntegerParameter("y", &y)) { + response->SetError(new Error( + kBadRequest, + "Missing or invalid 'x' or 'y' parameters")); + return; + } + Rect bounds; + Error* error = session_->GetWindowBounds(window_id, &bounds); + if (!error) { + bounds = Rect(Point(x, y), bounds.size()); + error = session_->SetWindowBounds(window_id, bounds); + } + if (error) { + response->SetError(error); + return; + } +} + +} // namespace webdriver diff --git a/chrome/test/webdriver/commands/window_commands.h b/chrome/test/webdriver/commands/window_commands.h new file mode 100644 index 0000000..d5df95d --- /dev/null +++ b/chrome/test/webdriver/commands/window_commands.h @@ -0,0 +1,53 @@ +// Copyright (c) 2012 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. + +#ifndef CHROME_TEST_WEBDRIVER_COMMANDS_WINDOW_COMMANDS_H_ +#define CHROME_TEST_WEBDRIVER_COMMANDS_WINDOW_COMMANDS_H_ + +#include <string> +#include <vector> + +#include "chrome/test/webdriver/commands/webdriver_command.h" + +namespace base { +class DictionaryValue; +} + +namespace webdriver { + +class Response; + +class WindowSizeCommand : public WebDriverCommand { + public: + WindowSizeCommand(const std::vector<std::string>& path_segments, + const base::DictionaryValue* parameters); + virtual ~WindowSizeCommand(); + + virtual bool DoesGet() OVERRIDE; + virtual bool DoesPost() OVERRIDE; + virtual void ExecuteGet(Response* const response) OVERRIDE; + virtual void ExecutePost(Response* const response) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(WindowSizeCommand); +}; + +class WindowPositionCommand : public WebDriverCommand { + public: + WindowPositionCommand(const std::vector<std::string>& path_segments, + const base::DictionaryValue* parameters); + virtual ~WindowPositionCommand(); + + virtual bool DoesGet() OVERRIDE; + virtual bool DoesPost() OVERRIDE; + virtual void ExecuteGet(Response* const response) OVERRIDE; + virtual void ExecutePost(Response* const response) OVERRIDE; + + private: + DISALLOW_COPY_AND_ASSIGN(WindowPositionCommand); +}; + +} // namespace webdriver + +#endif // CHROME_TEST_WEBDRIVER_COMMANDS_WINDOW_COMMANDS_H_ diff --git a/chrome/test/webdriver/test/chromedriver_tests.py b/chrome/test/webdriver/test/chromedriver_tests.py index 1e7d359..7802589 100644 --- a/chrome/test/webdriver/test/chromedriver_tests.py +++ b/chrome/test/webdriver/test/chromedriver_tests.py @@ -36,6 +36,7 @@ try: except ImportError: import json +from selenium.common.exceptions import NoSuchWindowException from selenium.common.exceptions import WebDriverException from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.desired_capabilities import DesiredCapabilities @@ -921,6 +922,7 @@ class FrameSwitchingTest(ChromeDriverTest): self.assertEquals(str(i), driver.current_url.split('?')[-1]) driver.switch_to_default_content() + class AlertTest(ChromeDriverTest): def testAlertOnLoadDoesNotHang(self): @@ -982,6 +984,66 @@ class AlertTest(ChromeDriverTest): driver.execute_async_script('arguments[0](); window.alert("ok")') driver.switch_to_alert().accept() + +class WindowTest(ChromeDriverTest): + def testSizeAndPosition(self): + driver = self.GetNewDriver() + + # TODO(kkania): Update the python bindings and get rid of these. + driver.command_executor._commands.update({ + 'getSize': ('GET', '/session/$sessionId/window/$windowHandle/size'), + 'setSize': ('POST', '/session/$sessionId/window/$windowHandle/size'), + 'getPos': ('GET', '/session/$sessionId/window/$windowHandle/position'), + 'setPos': ('POST', '/session/$sessionId/window/$windowHandle/position') + }) + def getSize(window='current'): + return driver.execute('getSize', {'windowHandle': window})['value'] + def setSize(width, height, window='current'): + params = { 'windowHandle': window, + 'width': width, + 'height': height + } + return driver.execute('setSize', params) + def getPosition(window='current'): + return driver.execute('getPos', {'windowHandle': window})['value'] + def setPosition(x, y, window='current'): + params = { 'windowHandle': window, + 'x': x, + 'y': y + } + return driver.execute('setPos', params) + + # Test size. + size = getSize() + setSize(size['width'], size['height']) + self.assertEquals(size, getSize()) + setSize(800, 600) + self.assertEquals(800, getSize()['width']) + self.assertEquals(600, getSize()['height']) + # Test position. + pos = getPosition() + setPosition(pos['x'], pos['y']) + self.assertEquals(pos, getPosition()) + setPosition(100, 200) + self.assertEquals(100, getPosition()['x']) + self.assertEquals(200, getPosition()['y']) + # Test specifying window handle. + driver.execute_script( + 'window.open("about:blank", "name", "height=200, width=200")') + windows = driver.window_handles + self.assertEquals(2, len(windows)) + setSize(400, 300, windows[1]) + self.assertEquals(400, getSize(windows[1])['width']) + self.assertEquals(300, getSize(windows[1])['height']) + self.assertNotEquals(getSize(windows[1]), getSize(windows[0])) + # Test specifying invalid handle. + invalid_handle = 'f1-120' + self.assertRaises(WebDriverException, setSize, 400, 300, invalid_handle) + self.assertRaises(NoSuchWindowException, getSize, invalid_handle) + self.assertRaises(NoSuchWindowException, setPosition, 1, 1, invalid_handle) + self.assertRaises(NoSuchWindowException, getPosition, invalid_handle) + + class ExtensionTest(ChromeDriverTest): INFOBAR_BROWSER_ACTION_EXTENSION = test_paths.TEST_DATA_PATH + \ diff --git a/chrome/test/webdriver/webdriver_automation.cc b/chrome/test/webdriver/webdriver_automation.cc index efc5f00..f8ea88a 100644 --- a/chrome/test/webdriver/webdriver_automation.cc +++ b/chrome/test/webdriver/webdriver_automation.cc @@ -713,6 +713,16 @@ void Automation::CloseView(const WebViewId& view_id, Error** error) { *error = Error::FromAutomationError(auto_error); } +void Automation::SetViewBounds(const WebViewId& view_id, + const Rect& bounds, + Error** error) { + automation::Error auto_error; + if (!SendSetViewBoundsJSONRequest( + automation(), view_id, bounds.x(), bounds.y(), + bounds.width(), bounds.height(), &auto_error)) + *error = Error::FromAutomationError(auto_error); +} + void Automation::GetAppModalDialogMessage(std::string* message, Error** error) { *error = CheckAlertsSupported(); if (*error) diff --git a/chrome/test/webdriver/webdriver_automation.h b/chrome/test/webdriver/webdriver_automation.h index 76e46f5..f205527 100644 --- a/chrome/test/webdriver/webdriver_automation.h +++ b/chrome/test/webdriver/webdriver_automation.h @@ -37,6 +37,7 @@ namespace webdriver { class Error; class FramePath; class Point; +class Rect; // Creates and controls the Chrome instance. // This class should be created and accessed on a single thread. @@ -169,6 +170,12 @@ class Automation { // Closes the given view. void CloseView(const WebViewId& view_id, Error** error); + // Sets the bounds for the given view. The position should be in screen + // coordinates, while the size should be the desired size of the view. + void SetViewBounds(const WebViewId& view_id, + const Rect& bounds, + Error** error); + // Gets the active JavaScript modal dialog's message. void GetAppModalDialogMessage(std::string* message, Error** error); diff --git a/chrome/test/webdriver/webdriver_error.cc b/chrome/test/webdriver/webdriver_error.cc index 0884e10..102f14d 100644 --- a/chrome/test/webdriver/webdriver_error.cc +++ b/chrome/test/webdriver/webdriver_error.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -62,6 +62,8 @@ Error* Error::FromAutomationError(const automation::Error& error) { case automation::kBlockedByModalDialog: code = kUnexpectedAlertOpen; break; + case automation::kInvalidId: + code = kNoSuchWindow; default: break; } diff --git a/chrome/test/webdriver/webdriver_server.cc b/chrome/test/webdriver/webdriver_server.cc index a2f2b45..4b6e005 100644 --- a/chrome/test/webdriver/webdriver_server.cc +++ b/chrome/test/webdriver/webdriver_server.cc @@ -53,6 +53,7 @@ #include "chrome/test/webdriver/commands/title_command.h" #include "chrome/test/webdriver/commands/url_command.h" #include "chrome/test/webdriver/commands/webelement_commands.h" +#include "chrome/test/webdriver/commands/window_commands.h" #include "chrome/test/webdriver/webdriver_dispatch.h" #include "chrome/test/webdriver/webdriver_logging.h" #include "chrome/test/webdriver/webdriver_session_manager.h" @@ -140,6 +141,9 @@ void InitCallbacks(Dispatcher* dispatcher, dispatcher->Add<WindowCommand>( "/session/*/window"); dispatcher->Add<WindowHandleCommand>( "/session/*/window_handle"); dispatcher->Add<WindowHandlesCommand>("/session/*/window_handles"); + dispatcher->Add<WindowSizeCommand>( "/session/*/window/*/size"); + dispatcher->Add<WindowPositionCommand>( + "/session/*/window/*/position"); dispatcher->Add<SetAsyncScriptTimeoutCommand>( "/session/*/timeouts/async_script"); dispatcher->Add<ImplicitWaitCommand>( "/session/*/timeouts/implicit_wait"); diff --git a/chrome/test/webdriver/webdriver_session.cc b/chrome/test/webdriver/webdriver_session.cc index 03a090b8..d924009 100644 --- a/chrome/test/webdriver/webdriver_session.cc +++ b/chrome/test/webdriver/webdriver_session.cc @@ -773,6 +773,37 @@ Error* Session::CloseWindow() { return error; } +Error* Session::GetWindowBounds(const WebViewId& window, Rect* bounds) { + const char* kGetWindowBoundsScript = + "function() {" + " return {" + " 'left': window.screenX," + " 'top': window.screenY," + " 'width': window.outerWidth," + " 'height': window.outerHeight" + " }" + "}"; + return ExecuteScriptAndParse( + FrameId(window, FramePath()), + kGetWindowBoundsScript, + "getWindowBoundsScript", + new ListValue(), + CreateDirectValueParser(bounds)); +} + +Error* Session::SetWindowBounds( + const WebViewId& window, + const Rect& bounds) { + Error* error = NULL; + RunSessionTask(base::Bind( + &Automation::SetViewBounds, + base::Unretained(automation_.get()), + window, + bounds, + &error)); + return error; +} + Error* Session::GetAlertMessage(std::string* text) { Error* error = NULL; RunSessionTask(base::Bind( diff --git a/chrome/test/webdriver/webdriver_session.h b/chrome/test/webdriver/webdriver_session.h index f039edc..a6c2c83 100644 --- a/chrome/test/webdriver/webdriver_session.h +++ b/chrome/test/webdriver/webdriver_session.h @@ -174,6 +174,12 @@ class Session { // session. Error* CloseWindow(); + // Gets the bounds for the specified window. + Error* GetWindowBounds(const WebViewId& window, Rect* bounds); + + // Sets the bounds for the specified window. + Error* SetWindowBounds(const WebViewId& window, const Rect& bounds); + // Gets the message of the currently active JavaScript modal dialog. Error* GetAlertMessage(std::string* text); diff --git a/chrome/test/webdriver/webdriver_util.cc b/chrome/test/webdriver/webdriver_util.cc index 1347284..bab42b8 100644 --- a/chrome/test/webdriver/webdriver_util.cc +++ b/chrome/test/webdriver/webdriver_util.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -12,6 +12,7 @@ #include "base/rand_util.h" #include "base/stringprintf.h" #include "base/string_number_conversions.h" +#include "base/string_split.h" #include "base/third_party/icu/icu_utf.h" #include "chrome/common/automation_id.h" #include "chrome/test/automation/automation_json_requests.h" @@ -121,31 +122,37 @@ const char* GetJsonTypeName(Value::Type type) { return "unknown"; } +std::string AutomationIdToString(const AutomationId& id) { + return base::StringPrintf("%d-%s", id.type(), id.id().c_str()); +} + bool StringToAutomationId(const std::string& string_id, AutomationId* id) { - scoped_ptr<Value> value(base::JSONReader::Read(string_id, false)); - std::string error_msg; - return value.get() && AutomationId::FromValue(value.get(), id, &error_msg); + std::vector<std::string> split_id; + base::SplitString(string_id, '-', &split_id); + if (split_id.size() != 2) + return false; + int type; + if (!base::StringToInt(split_id[0], &type)) + return false; + *id = AutomationId(static_cast<AutomationId::Type>(type), split_id[1]); + return true; } std::string WebViewIdToString(const WebViewId& view_id) { - DictionaryValue* dict = view_id.GetId().ToValue(); - if (view_id.old_style()) - dict->SetBoolean("old_style", true); - return JsonStringify(dict); + return base::StringPrintf( + "%s%s", + view_id.old_style() ? "t" : "f", + AutomationIdToString(view_id.GetId()).c_str()); } bool StringToWebViewId(const std::string& string_id, WebViewId* view_id) { - scoped_ptr<Value> value(base::JSONReader::Read(string_id, false)); + if (string_id.empty() || (string_id[0] != 'f' && string_id[0] != 't')) + return false; + bool old_style = string_id[0] == 't'; AutomationId id; - std::string error_msg; - DictionaryValue* dict; - if (!value.get() || !AutomationId::FromValue(value.get(), &id, &error_msg) || - !value->GetAsDictionary(&dict)) + if (!StringToAutomationId(string_id.substr(1), &id)) return false; - bool old_style = false; - dict->GetBoolean("old_style", &old_style); - if (old_style) { int tab_id; if (!base::StringToInt(id.id(), &tab_id)) diff --git a/chrome/test/webdriver/webdriver_util.h b/chrome/test/webdriver/webdriver_util.h index 628623b..2628e0e 100644 --- a/chrome/test/webdriver/webdriver_util.h +++ b/chrome/test/webdriver/webdriver_util.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -34,6 +34,9 @@ std::string JsonStringifyForDisplay(const base::Value* value); // Returns the string representation of the given type, for display purposes. const char* GetJsonTypeName(base::Value::Type type); +// Converts the automation ID to a string. +std::string AutomationIdToString(const AutomationId& id); + // Converts the string to an automation ID and returns true on success. bool StringToAutomationId(const std::string& string_id, AutomationId* id); |
