OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 #include "chrome/test/webdriver/commands/mouse_commands.h" | |
6 | |
7 #include "base/values.h" | |
8 #include "chrome/common/automation_constants.h" | |
9 #include "chrome/test/automation/value_conversion_util.h" | |
10 #include "chrome/test/webdriver/commands/response.h" | |
11 #include "chrome/test/webdriver/webdriver_basic_types.h" | |
12 #include "chrome/test/webdriver/webdriver_element_id.h" | |
13 #include "chrome/test/webdriver/webdriver_error.h" | |
14 #include "chrome/test/webdriver/webdriver_session.h" | |
15 #include "chrome/test/webdriver/webdriver_util.h" | |
16 | |
17 namespace { | |
18 | |
19 const int kLeftButton = 0; | |
20 const int kMiddleButton = 1; | |
21 const int kRightButton = 2; | |
22 | |
23 } // namespace | |
24 | |
25 namespace webdriver { | |
26 | |
27 MoveAndClickCommand::MoveAndClickCommand( | |
28 const std::vector<std::string>& path_segments, | |
29 const DictionaryValue* const parameters) | |
30 : WebElementCommand(path_segments, parameters) {} | |
31 | |
32 MoveAndClickCommand::~MoveAndClickCommand() {} | |
33 | |
34 bool MoveAndClickCommand::DoesPost() { | |
35 return true; | |
36 } | |
37 | |
38 void MoveAndClickCommand::ExecutePost(Response* response) { | |
39 std::string tag_name; | |
40 Error* error = session_->GetElementTagName( | |
41 session_->current_target(), element, &tag_name); | |
42 if (error) { | |
43 response->SetError(error); | |
44 return; | |
45 } | |
46 | |
47 if (tag_name == "option") { | |
48 const char* kCanOptionBeToggledScript = | |
49 "function(option) {" | |
50 " for (var parent = option.parentElement;" | |
51 " parent;" | |
52 " parent = parent.parentElement) {" | |
53 " if (parent.tagName.toLowerCase() == 'select') {" | |
54 " return parent.multiple;" | |
55 " }" | |
56 " }" | |
57 " throw new Error('Option element is not in a select');" | |
58 "}"; | |
59 bool can_be_toggled; | |
60 error = session_->ExecuteScriptAndParse( | |
61 session_->current_target(), | |
62 kCanOptionBeToggledScript, | |
63 "canOptionBeToggled", | |
64 CreateListValueFrom(element), | |
65 CreateDirectValueParser(&can_be_toggled)); | |
66 if (error) { | |
67 response->SetError(error); | |
68 return; | |
69 } | |
70 | |
71 if (can_be_toggled) { | |
72 error = session_->ToggleOptionElement( | |
73 session_->current_target(), element); | |
74 } else { | |
75 error = session_->SetOptionElementSelected( | |
76 session_->current_target(), element, true); | |
77 } | |
78 } else { | |
79 Point location; | |
80 error = session_->GetClickableLocation(element, &location); | |
81 if (!error) | |
82 error = session_->MouseMoveAndClick(location, automation::kLeftButton); | |
83 } | |
84 if (error) { | |
85 response->SetError(error); | |
86 return; | |
87 } | |
88 } | |
89 | |
90 HoverCommand::HoverCommand(const std::vector<std::string>& path_segments, | |
91 const DictionaryValue* const parameters) | |
92 : WebElementCommand(path_segments, parameters) {} | |
93 | |
94 HoverCommand::~HoverCommand() {} | |
95 | |
96 bool HoverCommand::DoesPost() { | |
97 return true; | |
98 } | |
99 | |
100 void HoverCommand::ExecutePost(Response* response) { | |
101 Error* error = NULL; | |
102 Point location; | |
103 error = session_->GetClickableLocation(element, &location); | |
104 if (!error) | |
105 error = session_->MouseMove(location); | |
106 if (error) { | |
107 response->SetError(error); | |
108 return; | |
109 } | |
110 } | |
111 | |
112 DragCommand::DragCommand(const std::vector<std::string>& path_segments, | |
113 const DictionaryValue* const parameters) | |
114 : WebElementCommand(path_segments, parameters) {} | |
115 | |
116 DragCommand::~DragCommand() {} | |
117 | |
118 bool DragCommand::Init(Response* const response) { | |
119 if (!WebElementCommand::Init(response)) | |
120 return false; | |
121 | |
122 if (!GetIntegerParameter("x", &drag_x_) || | |
123 !GetIntegerParameter("y", &drag_y_)) { | |
124 response->SetError(new Error(kBadRequest, "Missing (x,y) coordinates")); | |
125 return false; | |
126 } | |
127 | |
128 return true; | |
129 } | |
130 | |
131 bool DragCommand::DoesPost() { | |
132 return true; | |
133 } | |
134 | |
135 void DragCommand::ExecutePost(Response* response) { | |
136 Error* error = NULL; | |
137 Point drag_from; | |
138 error = session_->GetClickableLocation(element, &drag_from); | |
139 if (error) { | |
140 response->SetError(error); | |
141 return; | |
142 } | |
143 | |
144 Point drag_to(drag_from); | |
145 drag_to.Offset(drag_x_, drag_y_); | |
146 if (drag_to.x() < 0 || drag_to.y() < 0) | |
147 error = new Error(kBadRequest, "Invalid (x,y) coordinates"); | |
148 if (!error) | |
149 error = session_->MouseDrag(drag_from, drag_to); | |
150 | |
151 if (error) { | |
152 response->SetError(error); | |
153 return; | |
154 } | |
155 } | |
156 | |
157 AdvancedMouseCommand::AdvancedMouseCommand( | |
158 const std::vector<std::string>& path_segments, | |
159 const DictionaryValue* const parameters) | |
160 : WebDriverCommand(path_segments, parameters) {} | |
161 | |
162 AdvancedMouseCommand::~AdvancedMouseCommand() {} | |
163 | |
164 bool AdvancedMouseCommand::DoesPost() { | |
165 return true; | |
166 } | |
167 | |
168 MoveToCommand::MoveToCommand( | |
169 const std::vector<std::string>& path_segments, | |
170 const DictionaryValue* const parameters) | |
171 : AdvancedMouseCommand(path_segments, parameters), has_element_(false), | |
172 has_offset_(false), x_offset_(0), y_offset_(0) {} | |
173 | |
174 MoveToCommand::~MoveToCommand() {} | |
175 | |
176 bool MoveToCommand::Init(Response* const response) { | |
177 if (!AdvancedMouseCommand::Init(response)) | |
178 return false; | |
179 | |
180 std::string element_name; | |
181 has_element_ = GetStringParameter("element", &element_name); | |
182 | |
183 if (has_element_) { | |
184 element_ = ElementId(element_name); | |
185 } | |
186 | |
187 has_offset_ = GetIntegerParameter("xoffset", &x_offset_) && | |
188 GetIntegerParameter("yoffset", &y_offset_); | |
189 | |
190 if (!has_element_ && !has_offset_) { | |
191 response->SetError(new Error( | |
192 kBadRequest, "Invalid command arguments")); | |
193 return false; | |
194 } | |
195 | |
196 return true; | |
197 } | |
198 | |
199 void MoveToCommand::ExecutePost(Response* const response) { | |
200 Point location; | |
201 Error* error; | |
202 | |
203 if (has_element_) { | |
204 // If an element is specified, calculate the coordinate. | |
205 error = session_->GetElementLocationInView(element_, &location); | |
206 if (error) { | |
207 response->SetError(error); | |
208 return; | |
209 } | |
210 } else { | |
211 // If not, use the current mouse position. | |
212 location = session_->get_mouse_position(); | |
213 } | |
214 | |
215 if (has_offset_) { | |
216 // If an offset is specified, translate by the offset. | |
217 location.Offset(x_offset_, y_offset_); | |
218 } else { | |
219 DCHECK(has_element_); | |
220 | |
221 // If not, calculate the half of the element size and translate by it. | |
222 Size size; | |
223 error = session_->GetElementSize(session_->current_target(), | |
224 element_, &size); | |
225 if (error) { | |
226 response->SetError(error); | |
227 return; | |
228 } | |
229 | |
230 location.Offset(size.width() / 2, size.height() / 2); | |
231 } | |
232 | |
233 error = session_->MouseMove(location); | |
234 if (error) { | |
235 response->SetError(error); | |
236 return; | |
237 } | |
238 } | |
239 | |
240 ClickCommand::ClickCommand(const std::vector<std::string>& path_segments, | |
241 const DictionaryValue* const parameters) | |
242 : AdvancedMouseCommand(path_segments, parameters) {} | |
243 | |
244 ClickCommand::~ClickCommand() {} | |
245 | |
246 bool ClickCommand::Init(Response* const response) { | |
247 if (!AdvancedMouseCommand::Init(response)) | |
248 return false; | |
249 | |
250 if (!GetIntegerParameter("button", &button_)) { | |
251 response->SetError(new Error(kBadRequest, "Missing mouse button argument")); | |
252 return false; | |
253 } | |
254 | |
255 return true; | |
256 } | |
257 | |
258 void ClickCommand::ExecutePost(Response* const response) { | |
259 // Convert the button argument to a constant value in automation. | |
260 automation::MouseButton button; | |
261 if (button_ == kLeftButton) { | |
262 button = automation::kLeftButton; | |
263 } else if (button_ == kMiddleButton) { | |
264 button = automation::kMiddleButton; | |
265 } else if (button_ == kRightButton) { | |
266 button = automation::kRightButton; | |
267 } else { | |
268 response->SetError(new Error(kBadRequest, "Invalid mouse button")); | |
269 return; | |
270 } | |
271 | |
272 Error* error = session_->MouseClick(button); | |
273 if (error) { | |
274 response->SetError(error); | |
275 return; | |
276 } | |
277 } | |
278 | |
279 ButtonDownCommand::ButtonDownCommand( | |
280 const std::vector<std::string>& path_segments, | |
281 const DictionaryValue* const parameters) | |
282 : AdvancedMouseCommand(path_segments, parameters) {} | |
283 | |
284 ButtonDownCommand::~ButtonDownCommand() {} | |
285 | |
286 void ButtonDownCommand::ExecutePost(Response* const response) { | |
287 session_->MouseButtonDown(); | |
288 } | |
289 | |
290 ButtonUpCommand::ButtonUpCommand(const std::vector<std::string>& path_segments, | |
291 const DictionaryValue* const parameters) | |
292 : AdvancedMouseCommand(path_segments, parameters) {} | |
293 | |
294 ButtonUpCommand::~ButtonUpCommand() {} | |
295 | |
296 void ButtonUpCommand::ExecutePost(Response* const response) { | |
297 session_->MouseButtonUp(); | |
298 } | |
299 | |
300 DoubleClickCommand::DoubleClickCommand( | |
301 const std::vector<std::string>& path_segments, | |
302 const DictionaryValue* const parameters) | |
303 : AdvancedMouseCommand(path_segments, parameters) {} | |
304 | |
305 DoubleClickCommand::~DoubleClickCommand() {} | |
306 | |
307 void DoubleClickCommand::ExecutePost(Response* const response) { | |
308 Error* error = session_->MouseDoubleClick(); | |
309 if (error) { | |
310 response->SetError(error); | |
311 return; | |
312 } | |
313 } | |
314 | |
315 } // namespace webdriver | |
OLD | NEW |