Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(472)

Side by Side Diff: chrome/test/webdriver/commands/webelement_commands.cc

Issue 23526047: Delete old chromedriver code, and remove mongoose webserver. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "chrome/test/webdriver/commands/webelement_commands.h"
6
7 #include "base/file_util.h"
8 #include "base/format_macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/test/webdriver/commands/response.h"
16 #include "chrome/test/webdriver/webdriver_basic_types.h"
17 #include "chrome/test/webdriver/webdriver_error.h"
18 #include "chrome/test/webdriver/webdriver_session.h"
19 #include "chrome/test/webdriver/webdriver_util.h"
20 #include "third_party/webdriver/atoms.h"
21
22 namespace webdriver {
23
24 ///////////////////// WebElementCommand ////////////////////
25
26 WebElementCommand::WebElementCommand(
27 const std::vector<std::string>& path_segments,
28 const base::DictionaryValue* const parameters)
29 : WebDriverCommand(path_segments, parameters),
30 path_segments_(path_segments) {}
31
32 WebElementCommand::~WebElementCommand() {}
33
34 bool WebElementCommand::Init(Response* const response) {
35 if (!WebDriverCommand::Init(response))
36 return false;
37
38 // There should be at least 5 segments to match
39 // "/session/$session/element/$id"
40 if (path_segments_.size() < 5) {
41 response->SetError(new Error(kBadRequest, "Path segments is less than 5"));
42 return false;
43 }
44
45 // We cannot verify the ID is valid until we execute the command and
46 // inject the ID into the in-page cache.
47 element = ElementId(path_segments_.at(4));
48 return true;
49 }
50
51 ///////////////////// ElementAttributeCommand ////////////////////
52
53 ElementAttributeCommand::ElementAttributeCommand(
54 const std::vector<std::string>& path_segments,
55 const base::DictionaryValue* parameters)
56 : WebElementCommand(path_segments, parameters) {}
57
58 ElementAttributeCommand::~ElementAttributeCommand() {}
59
60 bool ElementAttributeCommand::DoesGet() {
61 return true;
62 }
63
64 void ElementAttributeCommand::ExecuteGet(Response* const response) {
65 // There should be at least 7 segments to match
66 // "/session/$session/element/$id/attribute/$name"
67 if (path_segments_.size() < 7) {
68 response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
69 return;
70 }
71
72 const std::string key = path_segments_.at(6);
73 base::Value* value;
74 Error* error = session_->GetAttribute(element, key, &value);
75 if (error) {
76 response->SetError(error);
77 return;
78 }
79
80 response->SetValue(value);
81 }
82
83 ///////////////////// ElementClearCommand ////////////////////
84
85 ElementClearCommand::ElementClearCommand(
86 const std::vector<std::string>& path_segments,
87 const base::DictionaryValue* parameters)
88 : WebElementCommand(path_segments, parameters) {}
89
90 ElementClearCommand::~ElementClearCommand() {}
91
92 bool ElementClearCommand::DoesPost() {
93 return true;
94 }
95
96 void ElementClearCommand::ExecutePost(Response* const response) {
97 base::ListValue args;
98 args.Append(element.ToValue());
99
100 std::string script = base::StringPrintf(
101 "(%s).apply(null, arguments);", atoms::asString(atoms::CLEAR).c_str());
102
103 base::Value* result = NULL;
104 Error* error = session_->ExecuteScript(script, &args, &result);
105 if (error) {
106 response->SetError(error);
107 return;
108 }
109 response->SetValue(result);
110 }
111
112 ///////////////////// ElementCssCommand ////////////////////
113
114 ElementCssCommand::ElementCssCommand(
115 const std::vector<std::string>& path_segments,
116 const base::DictionaryValue* parameters)
117 : WebElementCommand(path_segments, parameters) {}
118
119 ElementCssCommand::~ElementCssCommand() {}
120
121 bool ElementCssCommand::DoesGet() {
122 return true;
123 }
124
125 void ElementCssCommand::ExecuteGet(Response* const response) {
126 // There should be at least 7 segments to match
127 // "/session/$session/element/$id/css/$propertyName"
128 if (path_segments_.size() < 7) {
129 response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
130 return;
131 }
132
133 std::string script = base::StringPrintf(
134 "return (%s).apply(null, arguments);",
135 atoms::asString(atoms::GET_EFFECTIVE_STYLE).c_str());
136
137 base::ListValue args;
138 args.Append(element.ToValue());
139 args.Append(new base::StringValue(path_segments_.at(6)));
140
141 base::Value* result = NULL;
142 Error* error = session_->ExecuteScript(script, &args, &result);
143 if (error) {
144 response->SetError(error);
145 return;
146 }
147 response->SetValue(result);
148 }
149
150 ///////////////////// ElementDisplayedCommand ////////////////////
151
152 ElementDisplayedCommand::ElementDisplayedCommand(
153 const std::vector<std::string>& path_segments,
154 const base::DictionaryValue* parameters)
155 : WebElementCommand(path_segments, parameters) {}
156
157 ElementDisplayedCommand::~ElementDisplayedCommand() {}
158
159 bool ElementDisplayedCommand::DoesGet() {
160 return true;
161 }
162
163 void ElementDisplayedCommand::ExecuteGet(Response* const response) {
164 bool is_displayed;
165 Error* error = session_->IsElementDisplayed(
166 session_->current_target(), element, false /* ignore_opacity */,
167 &is_displayed);
168 if (error) {
169 response->SetError(error);
170 return;
171 }
172 response->SetValue(new base::FundamentalValue(is_displayed));
173 }
174
175 ///////////////////// ElementEnabledCommand ////////////////////
176
177 ElementEnabledCommand::ElementEnabledCommand(
178 const std::vector<std::string>& path_segments,
179 const base::DictionaryValue* parameters)
180 : WebElementCommand(path_segments, parameters) {}
181
182 ElementEnabledCommand::~ElementEnabledCommand() {}
183
184 bool ElementEnabledCommand::DoesGet() {
185 return true;
186 }
187
188 void ElementEnabledCommand::ExecuteGet(Response* const response) {
189 base::ListValue args;
190 args.Append(element.ToValue());
191
192 std::string script = base::StringPrintf(
193 "return (%s).apply(null, arguments);",
194 atoms::asString(atoms::IS_ENABLED).c_str());
195
196 base::Value* result = NULL;
197 Error* error = session_->ExecuteScript(script, &args, &result);
198 if (error) {
199 response->SetError(error);
200 return;
201 }
202 response->SetValue(result);
203 }
204
205 ///////////////////// ElementEqualsCommand ////////////////////
206
207 ElementEqualsCommand::ElementEqualsCommand(
208 const std::vector<std::string>& path_segments,
209 const base::DictionaryValue* parameters)
210 : WebElementCommand(path_segments, parameters) {}
211
212 ElementEqualsCommand::~ElementEqualsCommand() {}
213
214 bool ElementEqualsCommand::DoesGet() {
215 return true;
216 }
217
218 void ElementEqualsCommand::ExecuteGet(Response* const response) {
219 // There should be at least 7 segments to match
220 // "/session/$session/element/$id/equals/$other"
221 if (path_segments_.size() < 7) {
222 response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
223 return;
224 }
225
226 std::string script = "return arguments[0] == arguments[1];";
227
228 base::ListValue args;
229 args.Append(element.ToValue());
230
231 ElementId other_element(path_segments_.at(6));
232 args.Append(other_element.ToValue());
233
234 base::Value* result = NULL;
235 Error* error = session_->ExecuteScript(script, &args, &result);
236 if (error) {
237 response->SetError(error);
238 return;
239 }
240 response->SetValue(result);
241 }
242
243 ///////////////////// ElementLocationCommand ////////////////////
244
245 ElementLocationCommand::ElementLocationCommand(
246 const std::vector<std::string>& path_segments,
247 const base::DictionaryValue* parameters)
248 : WebElementCommand(path_segments, parameters) {}
249
250 ElementLocationCommand::~ElementLocationCommand() {}
251
252 bool ElementLocationCommand::DoesGet() {
253 return true;
254 }
255
256 void ElementLocationCommand::ExecuteGet(Response* const response) {
257 std::string script = base::StringPrintf(
258 "return (%s).apply(null, arguments);",
259 atoms::asString(atoms::GET_LOCATION).c_str());
260
261 base::ListValue args;
262 args.Append(element.ToValue());
263
264 base::Value* result = NULL;
265 Error* error = session_->ExecuteScript(script, &args, &result);
266 if (error) {
267 response->SetError(error);
268 return;
269 }
270 response->SetValue(result);
271 }
272
273 ///////////////////// ElementLocationInViewCommand ////////////////////
274
275 ElementLocationInViewCommand::ElementLocationInViewCommand(
276 const std::vector<std::string>& path_segments,
277 const base::DictionaryValue* parameters)
278 : WebElementCommand(path_segments, parameters) {}
279
280 ElementLocationInViewCommand::~ElementLocationInViewCommand() {}
281
282 bool ElementLocationInViewCommand::DoesGet() {
283 return true;
284 }
285
286 void ElementLocationInViewCommand::ExecuteGet(Response* const response) {
287 Point location;
288 Error* error = session_->GetElementLocationInView(element, &location);
289 if (error) {
290 response->SetError(error);
291 return;
292 }
293 base::DictionaryValue* coord_dict = new base::DictionaryValue();
294 coord_dict->SetInteger("x", location.x());
295 coord_dict->SetInteger("y", location.y());
296 response->SetValue(coord_dict);
297 }
298
299 ///////////////////// ElementNameCommand ////////////////////
300
301 ElementNameCommand::ElementNameCommand(
302 const std::vector<std::string>& path_segments,
303 const base::DictionaryValue* parameters)
304 : WebElementCommand(path_segments, parameters) {}
305
306 ElementNameCommand::~ElementNameCommand() {}
307
308 bool ElementNameCommand::DoesGet() {
309 return true;
310 }
311
312 void ElementNameCommand::ExecuteGet(Response* const response) {
313 std::string tag_name;
314 Error* error = session_->GetElementTagName(
315 session_->current_target(), element, &tag_name);
316 if (error) {
317 response->SetError(error);
318 return;
319 }
320 response->SetValue(new base::StringValue(tag_name));
321 }
322
323 ///////////////////// ElementSelectedCommand ////////////////////
324
325 ElementSelectedCommand::ElementSelectedCommand(
326 const std::vector<std::string>& path_segments,
327 const base::DictionaryValue* parameters)
328 : WebElementCommand(path_segments, parameters) {}
329
330 ElementSelectedCommand::~ElementSelectedCommand() {}
331
332 bool ElementSelectedCommand::DoesGet() {
333 return true;
334 }
335
336 bool ElementSelectedCommand::DoesPost() {
337 return true;
338 }
339
340 void ElementSelectedCommand::ExecuteGet(Response* const response) {
341 bool is_selected;
342 Error* error = session_->IsOptionElementSelected(
343 session_->current_target(), element, &is_selected);
344 if (error) {
345 response->SetError(error);
346 return;
347 }
348 response->SetValue(new base::FundamentalValue(is_selected));
349 }
350
351 void ElementSelectedCommand::ExecutePost(Response* const response) {
352 Error* error = session_->SetOptionElementSelected(
353 session_->current_target(), element, true);
354 if (error) {
355 response->SetError(error);
356 return;
357 }
358 }
359
360 ///////////////////// ElementSizeCommand ////////////////////
361
362 ElementSizeCommand::ElementSizeCommand(
363 const std::vector<std::string>& path_segments,
364 const base::DictionaryValue* parameters)
365 : WebElementCommand(path_segments, parameters) {}
366
367 ElementSizeCommand::~ElementSizeCommand() {}
368
369 bool ElementSizeCommand::DoesGet() {
370 return true;
371 }
372
373 void ElementSizeCommand::ExecuteGet(Response* const response) {
374 Size size;
375 Error* error = session_->GetElementSize(
376 session_->current_target(), element, &size);
377 if (error) {
378 response->SetError(error);
379 return;
380 }
381 base::DictionaryValue* dict = new base::DictionaryValue();
382 dict->SetInteger("width", size.width());
383 dict->SetInteger("height", size.height());
384 response->SetValue(dict);
385 }
386
387 ///////////////////// ElementSubmitCommand ////////////////////
388
389 ElementSubmitCommand::ElementSubmitCommand(
390 const std::vector<std::string>& path_segments,
391 const base::DictionaryValue* parameters)
392 : WebElementCommand(path_segments, parameters) {}
393
394 ElementSubmitCommand::~ElementSubmitCommand() {}
395
396 bool ElementSubmitCommand::DoesPost() {
397 return true;
398 }
399
400 void ElementSubmitCommand::ExecutePost(Response* const response) {
401 std::string script = base::StringPrintf(
402 "(%s).apply(null, arguments);", atoms::asString(atoms::SUBMIT).c_str());
403
404 base::ListValue args;
405 args.Append(element.ToValue());
406
407 base::Value* result = NULL;
408 Error* error = session_->ExecuteScript(script, &args, &result);
409 if (error) {
410 response->SetError(error);
411 return;
412 }
413 response->SetValue(result);
414 }
415
416 ///////////////////// ElementToggleCommand ////////////////////
417
418 ElementToggleCommand::ElementToggleCommand(
419 const std::vector<std::string>& path_segments,
420 const base::DictionaryValue* parameters)
421 : WebElementCommand(path_segments, parameters) {}
422
423 ElementToggleCommand::~ElementToggleCommand() {}
424
425 bool ElementToggleCommand::DoesPost() {
426 return true;
427 }
428
429 void ElementToggleCommand::ExecutePost(Response* const response) {
430 std::string script = base::StringPrintf(
431 "return (%s).apply(null, arguments);",
432 atoms::asString(atoms::CLICK).c_str());
433
434 base::ListValue args;
435 args.Append(element.ToValue());
436
437 base::Value* result = NULL;
438 Error* error = session_->ExecuteScript(script, &args, &result);
439 if (error) {
440 response->SetError(error);
441 return;
442 }
443 response->SetValue(result);
444 }
445
446 ///////////////////// ElementValueCommand ////////////////////
447
448 ElementValueCommand::ElementValueCommand(
449 const std::vector<std::string>& path_segments,
450 const base::DictionaryValue* parameters)
451 : WebElementCommand(path_segments, parameters) {}
452
453 ElementValueCommand::~ElementValueCommand() {}
454
455 bool ElementValueCommand::DoesGet() {
456 return true;
457 }
458
459 bool ElementValueCommand::DoesPost() {
460 return true;
461 }
462
463 void ElementValueCommand::ExecuteGet(Response* const response) {
464 base::Value* unscoped_result = NULL;
465 base::ListValue args;
466 std::string script = "return arguments[0]['value']";
467 args.Append(element.ToValue());
468
469 Error* error = session_->ExecuteScript(script, &args, &unscoped_result);
470 scoped_ptr<base::Value> result(unscoped_result);
471 if (error) {
472 response->SetError(error);
473 return;
474 }
475 if (!result->IsType(base::Value::TYPE_STRING) &&
476 !result->IsType(base::Value::TYPE_NULL)) {
477 response->SetError(new Error(
478 kUnknownError, "Result is not string or null type"));
479 return;
480 }
481 response->SetValue(result.release());
482 }
483
484 void ElementValueCommand::ExecutePost(Response* const response) {
485 bool is_input = false;
486 Error* error = HasAttributeWithLowerCaseValueASCII("tagName", "input",
487 &is_input);
488 if (error) {
489 response->SetError(error);
490 return;
491 }
492
493 bool is_file = false;
494 error = HasAttributeWithLowerCaseValueASCII("type", "file", &is_file);
495 if (error) {
496 response->SetError(error);
497 return;
498 }
499
500 // If the element is a file upload control, set the file paths to the element.
501 // Otherwise send the value to the element as key input.
502 if (is_input && is_file) {
503 error = DragAndDropFilePaths();
504 } else {
505 error = SendKeys();
506 }
507
508 if (error) {
509 response->SetError(error);
510 return;
511 }
512 }
513
514 Error* ElementValueCommand::HasAttributeWithLowerCaseValueASCII(
515 const std::string& key, const std::string& value, bool* result) const {
516 base::Value* unscoped_value = NULL;
517 Error* error = session_->GetAttribute(element, key, &unscoped_value);
518 scoped_ptr<base::Value> scoped_value(unscoped_value);
519 if (error)
520 return error;
521
522 std::string actual_value;
523 if (scoped_value->GetAsString(&actual_value)) {
524 *result = LowerCaseEqualsASCII(actual_value, value.c_str());
525 } else {
526 // Note we do not handle converting a number to a string.
527 *result = false;
528 }
529 return NULL;
530 }
531
532 Error* ElementValueCommand::DragAndDropFilePaths() const {
533 const base::ListValue* path_list;
534 if (!GetListParameter("value", &path_list))
535 return new Error(kBadRequest, "Missing or invalid 'value' parameter");
536
537 // Compress array into single string.
538 base::FilePath::StringType paths_string;
539 for (size_t i = 0; i < path_list->GetSize(); ++i) {
540 base::FilePath::StringType path_part;
541 if (!path_list->GetString(i, &path_part)) {
542 return new Error(
543 kBadRequest,
544 "'value' is invalid: " + JsonStringify(path_list));
545 }
546 paths_string.append(path_part);
547 }
548
549 // Separate the string into separate paths, delimited by \n.
550 std::vector<base::FilePath::StringType> paths;
551 base::SplitString(paths_string, '\n', &paths);
552
553 // Return an error if trying to drop multiple paths on a single file input.
554 bool multiple = false;
555 Error* error = HasAttributeWithLowerCaseValueASCII("multiple", "true",
556 &multiple);
557 if (error)
558 return error;
559 if (!multiple && paths.size() > 1)
560 return new Error(kBadRequest, "The element can not hold multiple files");
561
562 // Check the files exist.
563 for (size_t i = 0; i < paths.size(); ++i) {
564 if (!base::PathExists(base::FilePath(paths[i]))) {
565 return new Error(
566 kBadRequest,
567 base::StringPrintf("'%s' does not exist on the file system",
568 UTF16ToUTF8(
569 base::FilePath(paths[i]).LossyDisplayName()).c_str()));
570 }
571 }
572
573 Point location;
574 error = session_->GetClickableLocation(element, &location);
575 if (error)
576 return error;
577
578 return session_->DragAndDropFilePaths(location, paths);
579 }
580
581 Error* ElementValueCommand::SendKeys() const {
582 const base::ListValue* key_list;
583 if (!GetListParameter("value", &key_list)) {
584 return new Error(kBadRequest, "Missing or invalid 'value' parameter");
585 }
586
587 // Flatten the given array of strings into one.
588 string16 keys;
589 Error* error = FlattenStringArray(key_list, &keys);
590 if (error)
591 return error;
592
593 return session_->SendKeys(element, keys);
594 }
595
596 ///////////////////// ElementTextCommand ////////////////////
597
598 ElementTextCommand::ElementTextCommand(
599 const std::vector<std::string>& path_segments,
600 const base::DictionaryValue* parameters)
601 : WebElementCommand(path_segments, parameters) {}
602
603 ElementTextCommand::~ElementTextCommand() {}
604
605 bool ElementTextCommand::DoesGet() {
606 return true;
607 }
608
609 void ElementTextCommand::ExecuteGet(Response* const response) {
610 base::Value* unscoped_result = NULL;
611 base::ListValue args;
612 args.Append(element.ToValue());
613
614 std::string script = base::StringPrintf(
615 "return (%s).apply(null, arguments);",
616 atoms::asString(atoms::GET_TEXT).c_str());
617
618 Error* error = session_->ExecuteScript(script, &args,
619 &unscoped_result);
620 scoped_ptr<base::Value> result(unscoped_result);
621 if (error) {
622 response->SetError(error);
623 return;
624 }
625 if (!result->IsType(base::Value::TYPE_STRING)) {
626 response->SetError(new Error(kUnknownError, "Result is not string type"));
627 return;
628 }
629 response->SetValue(result.release());
630 }
631
632 } // namespace webdriver
OLDNEW
« no previous file with comments | « chrome/test/webdriver/commands/webelement_commands.h ('k') | chrome/test/webdriver/commands/window_commands.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698