1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef CHROME_TEST_WEBDRIVER_WEBDRIVER_SESSION_H_ 6#define CHROME_TEST_WEBDRIVER_WEBDRIVER_SESSION_H_ 7 8#include <map> 9#include <string> 10#include <vector> 11 12#include "base/callback_forward.h" 13#include "base/files/file_path.h" 14#include "base/files/scoped_temp_dir.h" 15#include "base/memory/scoped_ptr.h" 16#include "base/strings/string16.h" 17#include "base/threading/thread.h" 18#include "chrome/common/automation_constants.h" 19#include "chrome/test/automation/automation_json_requests.h" 20#include "chrome/test/webdriver/frame_path.h" 21#include "chrome/test/webdriver/webdriver_automation.h" 22#include "chrome/test/webdriver/webdriver_basic_types.h" 23#include "chrome/test/webdriver/webdriver_capabilities_parser.h" 24#include "chrome/test/webdriver/webdriver_element_id.h" 25#include "chrome/test/webdriver/webdriver_logging.h" 26 27namespace base { 28class DictionaryValue; 29class FilePath; 30class ListValue; 31class Value; 32class WaitableEvent; 33} 34 35namespace webdriver { 36 37class Error; 38class ValueParser; 39 40// A view ID and frame path combination that uniquely identifies a specific 41// frame within a session. 42struct FrameId { 43 FrameId(); 44 FrameId(const WebViewId& view_id, const FramePath& frame_path); 45 46 WebViewId view_id; 47 FramePath frame_path; 48}; 49 50enum StorageType { 51 kLocalStorageType = 0, 52 kSessionStorageType 53}; 54 55// Every connection made by WebDriver maps to a session object. 56// This object creates the chrome instance and keeps track of the 57// state necessary to control the chrome browser created. 58// A session manages its own lifetime. 59class Session { 60 public: 61 // Adds this |Session| to the |SessionManager|. The session manages its own 62 // lifetime. Call |Terminate|, not delete, if you need to quit. 63 Session(); 64 65 // Removes this |Session| from the |SessionManager|. 66 ~Session(); 67 68 // Initializes the session with the given capabilities. 69 Error* Init(const base::DictionaryValue* capabilities_dict); 70 71 // Should be called before executing a command. 72 Error* BeforeExecuteCommand(); 73 74 // Should be called after executing a command. 75 Error* AfterExecuteCommand(); 76 77 // Terminates this session and deletes itself. 78 void Terminate(); 79 80 // Executes the given |script| in the context of the given frame. 81 // The |script| should be in the form of a function body 82 // (e.g. "return arguments[0]"), where |args| is the list of arguments to 83 // pass to the function. The caller is responsible for the script result 84 // |value|, which is set only if there is no error. 85 Error* ExecuteScript(const FrameId& frame_id, 86 const std::string& script, 87 const base::ListValue* const args, 88 base::Value** value); 89 90 // Same as above, but uses the currently targeted window and frame. 91 Error* ExecuteScript(const std::string& script, 92 const base::ListValue* const args, 93 base::Value** value); 94 95 // Executes the given script in the context of the given frame and parses 96 // the value with the given parser. The script should be in the form of an 97 // anonymous function. |script_name| is only used when creating error 98 // messages. This function takes ownership of |args| and |parser|. 99 Error* ExecuteScriptAndParse(const FrameId& frame_id, 100 const std::string& anonymous_func_script, 101 const std::string& script_name, 102 const base::ListValue* args, 103 const ValueParser* parser); 104 105 // Executes given |script| in the context of the given frame. 106 // The |script| should be in the form of a function body 107 // (e.g. "return arguments[0]"), where |args| is the list of arguments to 108 // pass to the function. The caller is responsible for the script result 109 // |value|, which is set only if there is no error. 110 Error* ExecuteAsyncScript(const FrameId& frame_id, 111 const std::string& script, 112 const base::ListValue* const args, 113 base::Value** value); 114 115 // Send the given keys to the given element dictionary. This function takes 116 // ownership of |element|. 117 Error* SendKeys(const ElementId& element, const string16& keys); 118 // Send the given keys to the active element. 119 Error* SendKeys(const string16& keys); 120 121 // Sets the file paths to the file upload control under the given location. 122 Error* DragAndDropFilePaths( 123 const Point& location, 124 const std::vector<base::FilePath::StringType>& paths); 125 126 // Clicks the mouse at the given location using the given button. 127 Error* MouseMoveAndClick(const Point& location, 128 automation::MouseButton button); 129 Error* MouseMove(const Point& location); 130 Error* MouseDrag(const Point& start, const Point& end); 131 Error* MouseClick(automation::MouseButton button); 132 Error* MouseButtonDown(); 133 Error* MouseButtonUp(); 134 Error* MouseDoubleClick(); 135 136 Error* NavigateToURL(const std::string& url); 137 Error* GoForward(); 138 Error* GoBack(); 139 Error* Reload(); 140 Error* GetURL(std::string* url); 141 Error* GetTitle(std::string* tab_title); 142 Error* GetScreenShot(std::string* png); 143#if !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS)) 144 Error* HeapProfilerDump(const std::string& reason); 145#endif // !defined(NO_TCMALLOC) && (defined(OS_LINUX) || defined(OS_CHROMEOS)) 146 Error* GetCookies(const std::string& url, 147 scoped_ptr<base::ListValue>* cookies); 148 Error* DeleteCookie(const std::string& url, const std::string& cookie_name); 149 Error* SetCookie(const std::string& url, base::DictionaryValue* cookie_dict); 150 151 // Gets all the currently open views. 152 Error* GetViews(std::vector<WebViewInfo>* views); 153 154 // Switches the view used by default. |id_or_name| is either a view ID 155 // returned by |GetViews| or the name attribute of a DOM window. 156 // Only tabs are considered when searching by name. 157 Error* SwitchToView(const std::string& id_or_name); 158 159 // Switches the frame used by default. |name_or_id| is either the name or id 160 // of a frame element. 161 Error* SwitchToFrameWithNameOrId(const std::string& name_or_id); 162 163 // Switches the frame used by default. |index| is the zero-based frame index. 164 Error* SwitchToFrameWithIndex(int index); 165 166 // Switches to the frame identified by the given |element|. The element must 167 // be either an IFRAME or FRAME element. 168 Error* SwitchToFrameWithElement(const ElementId& element); 169 170 // Switches the target frame to the topmost frame. 171 void SwitchToTopFrame(); 172 173 // Switches the target frame to the topmost frame if the current frame is 174 // invalid. 175 Error* SwitchToTopFrameIfCurrentFrameInvalid(); 176 177 // Closes the current window. Returns true on success. 178 // Note: The session will be deleted if this closes the last window in the 179 // session. 180 Error* CloseWindow(); 181 182 // Gets the bounds for the specified window. 183 Error* GetWindowBounds(const WebViewId& window, Rect* bounds); 184 185 // Sets the bounds for the specified window. 186 Error* SetWindowBounds(const WebViewId& window, const Rect& bounds); 187 188 // Maximizes the specified window. 189 Error* MaximizeWindow(const WebViewId& window); 190 191 // Gets the message of the currently active JavaScript modal dialog. 192 Error* GetAlertMessage(std::string* text); 193 194 // Sets the prompt text to use when accepting or dismissing a JavaScript 195 // modal dialog. 196 Error* SetAlertPromptText(const std::string& alert_prompt_text); 197 198 // Accept or dismiss the currently active JavaScript modal dialog with the 199 // previously set alert prompt text. Then clears the saved alert prompt text. 200 Error* AcceptOrDismissAlert(bool accept); 201 202 // Gets the version of the running browser. 203 std::string GetBrowserVersion(); 204 205 // Gets whether the running browser's version is newer or equal to the given 206 // version. Returns true on successful comparison. For example, in the version 207 // 11.0.632.4, 632 is the build number and 4 is the patch number. 208 Error* CompareBrowserVersion(int build_no, 209 int patch_no, 210 bool* is_newer_or_equal); 211 212 // Finds a single element in the given frame, starting at the given 213 // |root_element|, using the given locator strategy. |locator| should be a 214 // constant from |LocatorType|. Returns an error code. If successful, 215 // |element| will be set as the found element. 216 Error* FindElement(const FrameId& frame_id, 217 const ElementId& root_element, 218 const std::string& locator, 219 const std::string& query, 220 ElementId* element); 221 222 // Same as above, but finds multiple elements. 223 Error* FindElements(const FrameId& frame_id, 224 const ElementId& root_element, 225 const std::string& locator, 226 const std::string& query, 227 std::vector<ElementId>* elements); 228 229 // Scroll the element into view and get its location relative to 230 // the client's viewport. 231 Error* GetElementLocationInView( 232 const ElementId& element, 233 Point* location); 234 235 // Scroll the element's region into view and get its location relative to 236 // the client's viewport. If |center| is true, the element will be centered 237 // if it is too big to fit in view. If |verify_clickable_at_middle| is true, 238 // an error will be returned if the element is not clickable in the middle 239 // of the given region. 240 Error* GetElementRegionInView( 241 const ElementId& element, 242 const Rect& region, 243 bool center, 244 bool verify_clickable_at_middle, 245 Point* location); 246 247 // Gets the size of the element from the given window and frame, even if 248 // its display is none. 249 Error* GetElementSize(const FrameId& frame_id, 250 const ElementId& element, 251 Size* size); 252 253 // Gets the size of the element's first client rect. If the element has 254 // no client rects, this will return an error. 255 Error* GetElementFirstClientRect(const FrameId& frame_id, 256 const ElementId& element, 257 Rect* rect); 258 259 // Gets the element's effective style for the given property. 260 Error* GetElementEffectiveStyle( 261 const FrameId& frame_id, 262 const ElementId& element, 263 const std::string& prop, 264 std::string* value); 265 266 // Gets the top and left element border widths for the given frame. 267 Error* GetElementBorder(const FrameId& frame_id, 268 const ElementId& element, 269 int* border_left, 270 int* border_top); 271 272 // Gets whether the element is currently displayed. 273 Error* IsElementDisplayed(const FrameId& frame_id, 274 const ElementId& element, 275 bool ignore_opacity, 276 bool* is_visible); 277 278 // Gets whether the element is currently enabled. 279 Error* IsElementEnabled(const FrameId& frame_id, 280 const ElementId& element, 281 bool* is_enabled); 282 283 // Gets whether the option element is currently selected. 284 Error* IsOptionElementSelected(const FrameId& frame_id, 285 const ElementId& element, 286 bool* is_selected); 287 288 // Set the selection state of the given option element. The option element 289 // must support multi selection if |selected| is false. 290 Error* SetOptionElementSelected(const FrameId& frame_id, 291 const ElementId& element, 292 bool selected); 293 294 // Toggles the option element's selection state. The option element should 295 // support multi selection. 296 Error* ToggleOptionElement(const FrameId& frame_id, 297 const ElementId& element); 298 299 // Gets the tag name of the given element. 300 Error* GetElementTagName(const FrameId& frame_id, 301 const ElementId& element, 302 std::string* tag_name); 303 304 // Gets the clickable location of the given element. It will be the center 305 // location of the element. If the element is not clickable, or if the 306 // location cannot be determined, an error will be returned. 307 Error* GetClickableLocation(const ElementId& element, 308 Point* location); 309 310 // Gets the attribute of the given element. If there are no errors, the 311 // function sets |value| and the caller takes ownership. 312 Error* GetAttribute(const ElementId& element, const std::string& key, 313 base::Value** value); 314 315 // Waits for all views to stop loading. Returns true on success. 316 Error* WaitForAllViewsToStopLoading(); 317 318 // Install extension at |path|. 319 Error* InstallExtension(const base::FilePath& path, std::string* extension_id); 320 321 Error* GetExtensionsInfo(base::ListValue* extension_ids); 322 323 Error* IsPageActionVisible(const WebViewId& tab_id, 324 const std::string& extension_id, 325 bool* is_visible); 326 327 Error* SetExtensionState(const std::string& extension_id, 328 bool enable); 329 330 Error* ClickExtensionButton(const std::string& extension_id, 331 bool browser_action); 332 333 Error* UninstallExtension(const std::string& extension_id); 334 335 // Sets the preference to the given value. This function takes ownership 336 // of |value|. If the preference is a user preference (instead of local 337 // state preference) |is_user_pref| should be true. 338 Error* SetPreference(const std::string& pref, 339 bool is_user_pref, 340 base::Value* value); 341 342 // Returns a copy of the current log entries. Caller is responsible for 343 // returned value. 344 base::ListValue* GetLog() const; 345 346 // Gets the browser connection state. 347 Error* GetBrowserConnectionState(bool* online); 348 349 // Gets the status of the application cache. 350 Error* GetAppCacheStatus(int* status); 351 352 // Sets an item in the HTML5 localStorage object. 353 Error* SetStorageItem(StorageType type, 354 const std::string& key, 355 const std::string& value); 356 357 // Gets the value of an item in the HTML5 localStorage object. 358 Error* GetStorageItem(StorageType type, 359 const std::string& key, 360 std::string* value); 361 362 // Removes an item from the HTML5 localStorage object. 363 Error* RemoveStorageItem(StorageType type, 364 const std::string& key, 365 std::string* value); 366 367 // Gets the total number of items in the HTML5 localStorage object. 368 Error* GetStorageSize(StorageType type, int* size); 369 370 // Removes all items in the HTML5 localStorage object. 371 Error* ClearStorage(StorageType type); 372 373 // Gets the keys of all items of the HTML5 localStorage object. If there are 374 // no errors, the function sets |keys| and the caller takes ownership. 375 Error* GetStorageKeys(StorageType type, base::ListValue** keys); 376 377 // Gets the current geolocation. 378 Error* GetGeolocation(scoped_ptr<base::DictionaryValue>* geolocation); 379 380 // Overrides the current geolocation. 381 Error* OverrideGeolocation(const base::DictionaryValue* geolocation); 382 383 const std::string& id() const; 384 385 const FrameId& current_target() const; 386 387 void set_async_script_timeout(int timeout_ms); 388 int async_script_timeout() const; 389 390 void set_implicit_wait(int timeout_ms); 391 int implicit_wait() const; 392 393 const Point& get_mouse_position() const; 394 395 const Logger& logger() const; 396 397 const base::FilePath& temp_dir() const; 398 399 const Capabilities& capabilities() const; 400 401 private: 402 void RunSessionTask(const base::Closure& task); 403 void RunClosureOnSessionThread( 404 const base::Closure& task, 405 base::WaitableEvent* done_event); 406 void InitOnSessionThread(const Automation::BrowserOptions& options, 407 int* build_no, 408 Error** error); 409 void TerminateOnSessionThread(); 410 411 // Executes the given |script| in the context of the given frame. 412 // Waits for script to finish and parses the response. 413 // The caller is responsible for the script result |value|. 414 Error* ExecuteScriptAndParseValue(const FrameId& frame_id, 415 const std::string& script, 416 base::Value** value); 417 void SendKeysOnSessionThread(const string16& keys, 418 bool release_modifiers, 419 Error** error); 420 Error* ProcessWebMouseEvents(const std::vector<WebMouseEvent>& events); 421 WebMouseEvent CreateWebMouseEvent(automation::MouseEventType type, 422 automation::MouseButton button, 423 const Point& point, 424 int click_count); 425 Error* SwitchToFrameWithJavaScriptLocatedFrame( 426 const std::string& script, 427 base::ListValue* args); 428 Error* FindElementsHelper(const FrameId& frame_id, 429 const ElementId& root_element, 430 const std::string& locator, 431 const std::string& query, 432 bool find_one, 433 std::vector<ElementId>* elements); 434 Error* ExecuteFindElementScriptAndParse(const FrameId& frame_id, 435 const ElementId& root_element, 436 const std::string& locator, 437 const std::string& query, 438 bool find_one, 439 std::vector<ElementId>* elements); 440 // Returns an error if the element is not clickable. 441 Error* VerifyElementIsClickable( 442 const FrameId& frame_id, 443 const ElementId& element, 444 const Point& location); 445 Error* GetElementRegionInViewHelper( 446 const FrameId& frame_id, 447 const ElementId& element, 448 const Rect& region, 449 bool center, 450 bool verify_clickable_at_middle, 451 Point* location); 452 Error* PostBrowserStartInit(); 453 Error* InitForWebsiteTesting(); 454 Error* SetPrefs(); 455 456 scoped_ptr<InMemoryLog> session_log_; 457 Logger logger_; 458 459 const std::string id_; 460 FrameId current_target_; 461 462 scoped_ptr<Automation> automation_; 463 base::Thread thread_; 464 465 // Timeout (in ms) for asynchronous script execution. 466 int async_script_timeout_; 467 468 // Time (in ms) of how long to wait while searching for a single element. 469 int implicit_wait_; 470 471 // Vector of the |ElementId|s for each frame of the current target frame 472 // path. The first refers to the first frame element in the root document. 473 // If the target frame is window.top, this will be empty. 474 std::vector<ElementId> frame_elements_; 475 476 // Last mouse position. Advanced APIs need this value. 477 Point mouse_position_; 478 479 // Chrome does not have an individual method for setting the prompt text 480 // of an alert. Instead, when the WebDriver client wants to set the text, 481 // we store it here and pass the text when the alert is accepted or 482 // dismissed. This text should only be used if |has_alert_prompt_text_| 483 // is true, so that the default prompt text is not overridden. 484 std::string alert_prompt_text_; 485 bool has_alert_prompt_text_; 486 487 // Temporary directory containing session data. 488 base::ScopedTempDir temp_dir_; 489 Capabilities capabilities_; 490 491 // Current state of all modifier keys. 492 int sticky_modifiers_; 493 494 // Chrome's build number. This is the 3rd number in Chrome's version string 495 // (e.g., 18.0.995.0 -> 995). Only valid after Chrome has started. 496 // See http://dev.chromium.org/releases/version-numbers. 497 int build_no_; 498 499 DISALLOW_COPY_AND_ASSIGN(Session); 500}; 501 502} // namespace webdriver 503 504#endif // CHROME_TEST_WEBDRIVER_WEBDRIVER_SESSION_H_ 505