OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/test/chromedriver/element_util.h" | 5 #include "chrome/test/chromedriver/element_util.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
9 #include "base/strings/string_number_conversions.h" | 9 #include "base/strings/string_number_conversions.h" |
10 #include "base/threading/platform_thread.h" | 10 #include "base/threading/platform_thread.h" |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 args.Append(CreateValueFrom(location)); | 107 args.Append(CreateValueFrom(location)); |
108 scoped_ptr<base::Value> result; | 108 scoped_ptr<base::Value> result; |
109 Status status = CallAtomsJs( | 109 Status status = CallAtomsJs( |
110 frame, web_view, webdriver::atoms::IS_ELEMENT_CLICKABLE, | 110 frame, web_view, webdriver::atoms::IS_ELEMENT_CLICKABLE, |
111 args, &result); | 111 args, &result); |
112 if (status.IsError()) | 112 if (status.IsError()) |
113 return status; | 113 return status; |
114 base::DictionaryValue* dict; | 114 base::DictionaryValue* dict; |
115 bool is_clickable; | 115 bool is_clickable; |
116 if (!result->GetAsDictionary(&dict) || | 116 if (!result->GetAsDictionary(&dict) || |
117 !dict->GetBoolean("clickable", &is_clickable)) | 117 !dict->GetBoolean("clickable", &is_clickable)) { |
118 return Status(kUnknownError, "fail to parse value of IS_ELEMENT_CLICKABLE"); | 118 return Status(kUnknownError, |
| 119 "failed to parse value of IS_ELEMENT_CLICKABLE"); |
| 120 } |
119 | 121 |
120 if (!is_clickable) { | 122 if (!is_clickable) { |
121 std::string message; | 123 std::string message; |
122 if (!dict->GetString("message", &message)) | 124 if (!dict->GetString("message", &message)) |
123 message = "element is not clickable"; | 125 message = "element is not clickable"; |
124 return Status(kUnknownError, message); | 126 return Status(kUnknownError, message); |
125 } | 127 } |
126 return Status(kOk); | 128 return Status(kOk); |
127 } | 129 } |
128 | 130 |
129 Status ScrollElementRegionIntoViewHelper( | 131 Status ScrollElementRegionIntoViewHelper( |
130 const std::string& frame, | 132 const std::string& frame, |
131 WebView* web_view, | 133 WebView* web_view, |
132 const std::string& element_id, | 134 const std::string& element_id, |
133 const WebRect& region, | 135 const WebRect& region, |
134 bool center, | 136 bool center, |
135 bool verify_clickable, | 137 bool verify_clickable, |
136 WebPoint* location) { | 138 WebPoint* location) { |
137 WebPoint tmp_location = *location; | 139 WebPoint tmp_location = *location; |
138 base::ListValue args; | 140 base::ListValue args; |
139 args.Append(CreateElement(element_id)); | 141 args.Append(CreateElement(element_id)); |
140 args.AppendBoolean(center); | 142 args.AppendBoolean(center); |
141 args.Append(CreateValueFrom(region)); | 143 args.Append(CreateValueFrom(region)); |
142 scoped_ptr<base::Value> result; | 144 scoped_ptr<base::Value> result; |
143 Status status = web_view->CallFunction( | 145 Status status = web_view->CallFunction( |
144 frame, webdriver::atoms::asString(webdriver::atoms::GET_LOCATION_IN_VIEW), | 146 frame, webdriver::atoms::asString(webdriver::atoms::GET_LOCATION_IN_VIEW), |
145 args, &result); | 147 args, &result); |
146 if (status.IsError()) | 148 if (status.IsError()) |
147 return status; | 149 return status; |
148 if (!ParseFromValue(result.get(), &tmp_location)) | 150 if (!ParseFromValue(result.get(), &tmp_location)) { |
149 return Status(kUnknownError, "fail to parse value of GET_LOCATION_IN_VIEW"); | 151 return Status(kUnknownError, |
| 152 "failed to parse value of GET_LOCATION_IN_VIEW"); |
| 153 } |
150 if (verify_clickable) { | 154 if (verify_clickable) { |
151 WebPoint middle = tmp_location; | 155 WebPoint middle = tmp_location; |
152 middle.Offset(region.Width() / 2, region.Height() / 2); | 156 middle.Offset(region.Width() / 2, region.Height() / 2); |
153 status = VerifyElementClickable(frame, web_view, element_id, middle); | 157 status = VerifyElementClickable(frame, web_view, element_id, middle); |
154 if (status.IsError()) | 158 if (status.IsError()) |
155 return status; | 159 return status; |
156 } | 160 } |
157 *location = tmp_location; | 161 *location = tmp_location; |
158 return Status(kOk); | 162 return Status(kOk); |
159 } | 163 } |
160 | 164 |
161 Status GetElementEffectiveStyle( | 165 Status GetElementEffectiveStyle( |
162 const std::string& frame, | 166 const std::string& frame, |
163 WebView* web_view, | 167 WebView* web_view, |
164 const std::string& element_id, | 168 const std::string& element_id, |
165 const std::string& property, | 169 const std::string& property, |
166 std::string* value) { | 170 std::string* value) { |
167 base::ListValue args; | 171 base::ListValue args; |
168 args.Append(CreateElement(element_id)); | 172 args.Append(CreateElement(element_id)); |
169 args.AppendString(property); | 173 args.AppendString(property); |
170 scoped_ptr<base::Value> result; | 174 scoped_ptr<base::Value> result; |
171 Status status = web_view->CallFunction( | 175 Status status = web_view->CallFunction( |
172 frame, webdriver::atoms::asString(webdriver::atoms::GET_EFFECTIVE_STYLE), | 176 frame, webdriver::atoms::asString(webdriver::atoms::GET_EFFECTIVE_STYLE), |
173 args, &result); | 177 args, &result); |
174 if (status.IsError()) | 178 if (status.IsError()) |
175 return status; | 179 return status; |
176 if (!result->GetAsString(value)) | 180 if (!result->GetAsString(value)) { |
177 return Status(kUnknownError, "fail to parse value of GET_EFFECTIVE_STYLE"); | 181 return Status(kUnknownError, |
| 182 "failed to parse value of GET_EFFECTIVE_STYLE"); |
| 183 } |
178 return Status(kOk); | 184 return Status(kOk); |
179 } | 185 } |
180 | 186 |
181 Status GetElementBorder( | 187 Status GetElementBorder( |
182 const std::string& frame, | 188 const std::string& frame, |
183 WebView* web_view, | 189 WebView* web_view, |
184 const std::string& element_id, | 190 const std::string& element_id, |
185 int* border_left, | 191 int* border_left, |
186 int* border_top) { | 192 int* border_top) { |
187 std::string border_left_str; | 193 std::string border_left_str; |
188 Status status = GetElementEffectiveStyle( | 194 Status status = GetElementEffectiveStyle( |
189 frame, web_view, element_id, "border-left-width", &border_left_str); | 195 frame, web_view, element_id, "border-left-width", &border_left_str); |
190 if (status.IsError()) | 196 if (status.IsError()) |
191 return status; | 197 return status; |
192 std::string border_top_str; | 198 std::string border_top_str; |
193 status = GetElementEffectiveStyle( | 199 status = GetElementEffectiveStyle( |
194 frame, web_view, element_id, "border-top-width", &border_top_str); | 200 frame, web_view, element_id, "border-top-width", &border_top_str); |
195 if (status.IsError()) | 201 if (status.IsError()) |
196 return status; | 202 return status; |
197 int border_left_tmp = -1; | 203 int border_left_tmp = -1; |
198 int border_top_tmp = -1; | 204 int border_top_tmp = -1; |
199 base::StringToInt(border_left_str, &border_left_tmp); | 205 base::StringToInt(border_left_str, &border_left_tmp); |
200 base::StringToInt(border_top_str, &border_top_tmp); | 206 base::StringToInt(border_top_str, &border_top_tmp); |
201 if (border_left_tmp == -1 || border_top_tmp == -1) | 207 if (border_left_tmp == -1 || border_top_tmp == -1) |
202 return Status(kUnknownError, "fail to get border width of element"); | 208 return Status(kUnknownError, "failed to get border width of element"); |
203 *border_left = border_left_tmp; | 209 *border_left = border_left_tmp; |
204 *border_top = border_top_tmp; | 210 *border_top = border_top_tmp; |
205 return Status(kOk); | 211 return Status(kOk); |
206 } | 212 } |
207 | 213 |
208 } // namespace | 214 } // namespace |
209 | 215 |
210 base::DictionaryValue* CreateElement(const std::string& element_id) { | 216 base::DictionaryValue* CreateElement(const std::string& element_id) { |
211 base::DictionaryValue* element = new base::DictionaryValue(); | 217 base::DictionaryValue* element = new base::DictionaryValue(); |
212 element->SetString(kElementKey, element_id); | 218 element->SetString(kElementKey, element_id); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
333 | 339 |
334 status = ScrollElementRegionIntoView( | 340 status = ScrollElementRegionIntoView( |
335 session, web_view, element_id, rect, | 341 session, web_view, element_id, rect, |
336 true /* center */, true /* verify_clickable */, location); | 342 true /* center */, true /* verify_clickable */, location); |
337 if (status.IsError()) | 343 if (status.IsError()) |
338 return status; | 344 return status; |
339 location->Offset(rect.Width() / 2, rect.Height() / 2); | 345 location->Offset(rect.Width() / 2, rect.Height() / 2); |
340 return Status(kOk); | 346 return Status(kOk); |
341 } | 347 } |
342 | 348 |
| 349 Status GetElementEffectiveStyle( |
| 350 Session* session, |
| 351 WebView* web_view, |
| 352 const std::string& element_id, |
| 353 const std::string& property_name, |
| 354 std::string* property_value) { |
| 355 return GetElementEffectiveStyle(session->GetCurrentFrameId(), web_view, |
| 356 element_id, property_name, property_value); |
| 357 } |
| 358 |
343 Status GetElementRegion( | 359 Status GetElementRegion( |
344 Session* session, | 360 Session* session, |
345 WebView* web_view, | 361 WebView* web_view, |
346 const std::string& element_id, | 362 const std::string& element_id, |
347 WebRect* rect) { | 363 WebRect* rect) { |
348 base::ListValue args; | 364 base::ListValue args; |
349 args.Append(CreateElement(element_id)); | 365 args.Append(CreateElement(element_id)); |
350 scoped_ptr<base::Value> result; | 366 scoped_ptr<base::Value> result; |
351 Status status = web_view->CallFunction( | 367 Status status = web_view->CallFunction( |
352 session->GetCurrentFrameId(), kGetElementRegionScript, args, &result); | 368 session->GetCurrentFrameId(), kGetElementRegionScript, args, &result); |
353 if (status.IsError()) | 369 if (status.IsError()) |
354 return status; | 370 return status; |
355 if (!ParseFromValue(result.get(), rect)) { | 371 if (!ParseFromValue(result.get(), rect)) { |
356 return Status(kUnknownError, | 372 return Status(kUnknownError, |
357 "fail to parse value of getElementRegion"); | 373 "failed to parse value of getElementRegion"); |
358 } | 374 } |
359 return Status(kOk); | 375 return Status(kOk); |
360 } | 376 } |
361 | 377 |
362 Status GetElementTagName( | 378 Status GetElementTagName( |
363 Session* session, | 379 Session* session, |
364 WebView* web_view, | 380 WebView* web_view, |
365 const std::string& element_id, | 381 const std::string& element_id, |
366 std::string* name) { | 382 std::string* name) { |
367 base::ListValue args; | 383 base::ListValue args; |
368 args.Append(CreateElement(element_id)); | 384 args.Append(CreateElement(element_id)); |
369 scoped_ptr<base::Value> result; | 385 scoped_ptr<base::Value> result; |
370 Status status = web_view->CallFunction( | 386 Status status = web_view->CallFunction( |
371 session->GetCurrentFrameId(), | 387 session->GetCurrentFrameId(), |
372 "function(elem) { return elem.tagName.toLowerCase(); }", | 388 "function(elem) { return elem.tagName.toLowerCase(); }", |
373 args, &result); | 389 args, &result); |
374 if (status.IsError()) | 390 if (status.IsError()) |
375 return status; | 391 return status; |
376 if (!result->GetAsString(name)) | 392 if (!result->GetAsString(name)) |
377 return Status(kUnknownError, "fail to get element tag name"); | 393 return Status(kUnknownError, "failed to get element tag name"); |
378 return Status(kOk); | 394 return Status(kOk); |
379 } | 395 } |
380 | 396 |
381 Status GetElementSize( | 397 Status GetElementSize( |
382 Session* session, | 398 Session* session, |
383 WebView* web_view, | 399 WebView* web_view, |
384 const std::string& element_id, | 400 const std::string& element_id, |
385 WebSize* size) { | 401 WebSize* size) { |
386 base::ListValue args; | 402 base::ListValue args; |
387 args.Append(CreateElement(element_id)); | 403 args.Append(CreateElement(element_id)); |
388 scoped_ptr<base::Value> result; | 404 scoped_ptr<base::Value> result; |
389 Status status = CallAtomsJs( | 405 Status status = CallAtomsJs( |
390 session->GetCurrentFrameId(), web_view, webdriver::atoms::GET_SIZE, | 406 session->GetCurrentFrameId(), web_view, webdriver::atoms::GET_SIZE, |
391 args, &result); | 407 args, &result); |
392 if (status.IsError()) | 408 if (status.IsError()) |
393 return status; | 409 return status; |
394 if (!ParseFromValue(result.get(), size)) | 410 if (!ParseFromValue(result.get(), size)) |
395 return Status(kUnknownError, "fail to parse value of GET_SIZE"); | 411 return Status(kUnknownError, "failed to parse value of GET_SIZE"); |
396 return Status(kOk); | 412 return Status(kOk); |
397 } | 413 } |
398 | 414 |
399 Status IsElementDisplayed( | 415 Status IsElementDisplayed( |
400 Session* session, | 416 Session* session, |
401 WebView* web_view, | 417 WebView* web_view, |
402 const std::string& element_id, | 418 const std::string& element_id, |
403 bool ignore_opacity, | 419 bool ignore_opacity, |
404 bool* is_displayed) { | 420 bool* is_displayed) { |
405 base::ListValue args; | 421 base::ListValue args; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 bool* is_togglable) { | 475 bool* is_togglable) { |
460 base::ListValue args; | 476 base::ListValue args; |
461 args.Append(CreateElement(element_id)); | 477 args.Append(CreateElement(element_id)); |
462 scoped_ptr<base::Value> result; | 478 scoped_ptr<base::Value> result; |
463 Status status = web_view->CallFunction( | 479 Status status = web_view->CallFunction( |
464 session->GetCurrentFrameId(), kIsOptionElementToggleableScript, | 480 session->GetCurrentFrameId(), kIsOptionElementToggleableScript, |
465 args, &result); | 481 args, &result); |
466 if (status.IsError()) | 482 if (status.IsError()) |
467 return status; | 483 return status; |
468 if (!result->GetAsBoolean(is_togglable)) | 484 if (!result->GetAsBoolean(is_togglable)) |
469 return Status(kUnknownError, "fail check if option togglable or not"); | 485 return Status(kUnknownError, "failed check if option togglable or not"); |
470 return Status(kOk); | 486 return Status(kOk); |
471 } | 487 } |
472 | 488 |
473 Status SetOptionElementSelected( | 489 Status SetOptionElementSelected( |
474 Session* session, | 490 Session* session, |
475 WebView* web_view, | 491 WebView* web_view, |
476 const std::string& element_id, | 492 const std::string& element_id, |
477 bool selected) { | 493 bool selected) { |
478 // TODO(171034): need to fix throwing error if an alert is triggered. | 494 // TODO(171034): need to fix throwing error if an alert is triggered. |
479 base::ListValue args; | 495 base::ListValue args; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
540 scoped_ptr<base::Value> result; | 556 scoped_ptr<base::Value> result; |
541 status = web_view->CallFunction( | 557 status = web_view->CallFunction( |
542 rit->parent_frame_id, kFindSubFrameScript, args, &result); | 558 rit->parent_frame_id, kFindSubFrameScript, args, &result); |
543 if (status.IsError()) | 559 if (status.IsError()) |
544 return status; | 560 return status; |
545 const base::DictionaryValue* element_dict; | 561 const base::DictionaryValue* element_dict; |
546 if (!result->GetAsDictionary(&element_dict)) | 562 if (!result->GetAsDictionary(&element_dict)) |
547 return Status(kUnknownError, "no element reference returned by script"); | 563 return Status(kUnknownError, "no element reference returned by script"); |
548 std::string frame_element_id; | 564 std::string frame_element_id; |
549 if (!element_dict->GetString(kElementKey, &frame_element_id)) | 565 if (!element_dict->GetString(kElementKey, &frame_element_id)) |
550 return Status(kUnknownError, "fail to locate a sub frame"); | 566 return Status(kUnknownError, "failed to locate a sub frame"); |
551 | 567 |
552 // Modify |region_offset| by the frame's border. | 568 // Modify |region_offset| by the frame's border. |
553 int border_left = -1; | 569 int border_left = -1; |
554 int border_top = -1; | 570 int border_top = -1; |
555 status = GetElementBorder( | 571 status = GetElementBorder( |
556 rit->parent_frame_id, web_view, frame_element_id, | 572 rit->parent_frame_id, web_view, frame_element_id, |
557 &border_left, &border_top); | 573 &border_left, &border_top); |
558 if (status.IsError()) | 574 if (status.IsError()) |
559 return status; | 575 return status; |
560 region_offset.Offset(border_left, border_top); | 576 region_offset.Offset(border_left, border_top); |
561 | 577 |
562 status = ScrollElementRegionIntoViewHelper( | 578 status = ScrollElementRegionIntoViewHelper( |
563 rit->parent_frame_id, web_view, frame_element_id, | 579 rit->parent_frame_id, web_view, frame_element_id, |
564 WebRect(region_offset, region_size), | 580 WebRect(region_offset, region_size), |
565 center, verify_clickable, ®ion_offset); | 581 center, verify_clickable, ®ion_offset); |
566 if (status.IsError()) | 582 if (status.IsError()) |
567 return status; | 583 return status; |
568 } | 584 } |
569 *location = region_offset; | 585 *location = region_offset; |
570 return Status(kOk); | 586 return Status(kOk); |
571 } | 587 } |
OLD | NEW |