12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/element_commands.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <list> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <vector> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/callback.h" 11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/files/file_path.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_split.h" 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/platform_thread.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/basic_types.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/chrome.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/js.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/ui_events.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/web_view.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/element_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/session.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/util.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/webdriver/atoms.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status SendKeysToElement( 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const ListValue* key_list) { 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_displayed = false; 363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool is_focused = false; 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeTicks start_time = base::TimeTicks::Now(); 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) while (true) { 39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = IsElementDisplayed( 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session, web_view, element_id, true, &is_displayed); 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (is_displayed) 44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) status = IsElementFocused(session, web_view, element_id, &is_focused); 463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (status.IsError()) 473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return status; 483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (is_focused) 493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) break; 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (base::TimeTicks::Now() - start_time >= session->implicit_wait) { 51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kElementNotVisible); 52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(100)); 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_enabled = false; 57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = IsElementEnabled(session, web_view, element_id, &is_enabled); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_enabled) 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kInvalidElementState); 623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!is_focused) { 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::ListValue args; 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) args.Append(CreateElement(element_id)); 663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<base::Value> result; 673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) status = web_view->CallFunction( 683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) session->GetCurrentFrameId(), kFocusScript, args, &result); 693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (status.IsError()) 703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return status; 713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SendKeysOnWindow(web_view, key_list, true, &session->sticky_modifiers); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 76d3868032626d59662ff73b372b5d584c1d144c53Ben MurdochStatus ExecuteTouchSingleTapAtom( 77d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Session* session, 78d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch WebView* web_view, 79d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const std::string& element_id, 80d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch const base::DictionaryValue& params, 81d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch scoped_ptr<base::Value>* value) { 82d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch base::ListValue args; 83d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch args.Append(CreateElement(element_id)); 84d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return web_view->CallFunction( 85d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch session->GetCurrentFrameId(), 86d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch webdriver::atoms::asString(webdriver::atoms::TOUCH_SINGLE_TAP), 87d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch args, 88d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch value); 89d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch} 90d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteElementCommand( 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ElementCommand& command, 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string id; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (params.GetString("id", &id) || params.GetString("element", &id)) 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return command.Run(session, web_view, id, params, value); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "element identifier must be a string"); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteFindChildElement( 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int interval_ms, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return FindElement( 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interval_ms, true, &element_id, session, web_view, params, value); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteFindChildElements( 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int interval_ms, 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return FindElement( 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interval_ms, false, &element_id, session, web_view, params, value); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteHoverOverElement( 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebPoint location; 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetElementClickableLocation( 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session, web_view, element_id, &location); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MouseEvent move_event( 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kMovedMouseEventType, kNoneMouseButton, location.x, location.y, 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session->sticky_modifiers, 0); 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<MouseEvent> events; 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) events.push_back(move_event); 144ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status = web_view->DispatchMouseEvents(events, session->GetCurrentFrameId()); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsOk()) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->mouse_position = location; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteClickElement( 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string tag_name; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = GetElementTagName(session, web_view, element_id, &tag_name); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (tag_name == "option") { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_toggleable; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = IsOptionElementTogglable( 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session, web_view, element_id, &is_toggleable); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_toggleable) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ToggleOptionElement(session, web_view, element_id); 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SetOptionElementSelected(session, web_view, element_id, true); 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebPoint location; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = GetElementClickableLocation( 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session, web_view, element_id, &location); 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<MouseEvent> events; 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) events.push_back( 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MouseEvent(kMovedMouseEventType, kNoneMouseButton, 180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) location.x, location.y, session->sticky_modifiers, 0)); 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) events.push_back( 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MouseEvent(kPressedMouseEventType, kLeftMouseButton, 183c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) location.x, location.y, session->sticky_modifiers, 1)); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) events.push_back( 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MouseEvent(kReleasedMouseEventType, kLeftMouseButton, 186c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) location.x, location.y, session->sticky_modifiers, 1)); 187ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch status = 188ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch web_view->DispatchMouseEvents(events, session->GetCurrentFrameId()); 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsOk()) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->mouse_position = location; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status ExecuteTouchSingleTap( 196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Session* session, 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebView* web_view, 198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& element_id, 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::DictionaryValue& params, 200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::Value>* value) { 201d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch // Fall back to javascript atom for pre-m30 Chrome. 202d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (session->chrome->GetBuildNo() < 1576) 203d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return ExecuteTouchSingleTapAtom( 204d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch session, web_view, element_id, params, value); 205d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 206d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch WebPoint location; 207d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch Status status = GetElementClickableLocation( 208d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch session, web_view, element_id, &location); 209d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch if (status.IsError()) 210d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return status; 211d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch 212d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch std::list<TouchEvent> events; 213d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch events.push_back( 214d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch TouchEvent(kTouchStart, location.x, location.y)); 215d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch events.push_back( 216d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch TouchEvent(kTouchEnd, location.x, location.y)); 217d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch return web_view->DispatchTouchEvents(events); 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteClearElement( 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value> result; 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::CLEAR), 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, &result); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteSendKeysToElement( 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::ListValue* key_list; 242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!params.GetList("value", &key_list)) 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "'value' must be a list"); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_input = false; 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Status status = IsElementAttributeEqualToIgnoreCase( 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session, web_view, element_id, "tagName", "input", &is_input); 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_file = false; 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) status = IsElementAttributeEqualToIgnoreCase( 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session, web_view, element_id, "type", "file", &is_file); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (is_input && is_file) { 256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Compress array into a single string. 257c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath::StringType paths_string; 258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < key_list->GetSize(); ++i) { 259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath::StringType path_part; 260c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!key_list->GetString(i, &path_part)) 261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "'value' is invalid"); 262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) paths_string.append(path_part); 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 265c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Separate the string into separate paths, delimited by '\n'. 266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<base::FilePath::StringType> path_strings; 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::SplitString(paths_string, '\n', &path_strings); 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::vector<base::FilePath> paths; 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < path_strings.size(); ++i) 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) paths.push_back(base::FilePath(path_strings[i])); 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool multiple = false; 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) status = IsElementAttributeEqualToIgnoreCase( 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session, web_view, element_id, "multiple", "true", &multiple); 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 277c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!multiple && paths.size() > 1) 278c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "the element can not hold multiple files"); 279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<base::DictionaryValue> element(CreateElement(element_id)); 281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return web_view->SetFileInputFiles( 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session->GetCurrentFrameId(), *element, paths); 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return SendKeysToElement(session, web_view, element_id, key_list); 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteSubmitElement( 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::SUBMIT), 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementText( 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::GET_TEXT), 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementValue( 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "function(elem) { return elem['value'] }", 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementTagName( 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "function(elem) { return elem.tagName.toLowerCase() }", 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteIsElementSelected( 3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::IS_SELECTED), 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteIsElementEnabled( 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::IS_ENABLED), 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteIsElementDisplayed( 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::IS_DISPLAYED), 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementLocation( 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::GET_LOCATION), 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementLocationOnceScrolledIntoView( 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebPoint location; 415c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = ScrollElementIntoView( 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session, web_view, element_id, &location); 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value->reset(CreateValueFrom(location)); 420c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementSize( 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ListValue args; 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args.Append(CreateElement(element_id)); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return web_view->CallFunction( 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) session->GetCurrentFrameId(), 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webdriver::atoms::asString(webdriver::atoms::GET_SIZE), 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) args, 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementAttribute( 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string name; 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!params.GetString("name", &name)) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "missing 'name'"); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return GetElementAttribute(session, web_view, element_id, name, value); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteGetElementValueOfCSSProperty( 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 456c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string property_name; 457c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!params.GetString("propertyName", &property_name)) 458c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kUnknownError, "missing 'propertyName'"); 459c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string property_value; 460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = GetElementEffectiveStyle( 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) session, web_view, element_id, property_name, &property_value); 462c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 463c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 464c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) value->reset(new base::StringValue(property_value)); 465c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ExecuteElementEquals( 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Session* session, 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebView* web_view, 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& element_id, 4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::DictionaryValue& params, 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<base::Value>* value) { 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string other_element_id; 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!params.GetString("other", &other_element_id)) 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "'other' must be a string"); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) value->reset(new base::FundamentalValue(element_id == other_element_id)); 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 480