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

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

Issue 7055004: File upload API in chromedriver (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Fixed according to the code review Created 9 years, 7 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
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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/webdriver/commands/webelement_commands.h" 5 #include "chrome/test/webdriver/commands/webelement_commands.h"
6 6
7 #include "base/file_util.h"
7 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/string_util.h"
8 #include "base/stringprintf.h" 10 #include "base/stringprintf.h"
9 #include "base/third_party/icu/icu_utf.h" 11 #include "base/third_party/icu/icu_utf.h"
10 #include "base/values.h" 12 #include "base/values.h"
11 #include "chrome/test/webdriver/commands/response.h" 13 #include "chrome/test/webdriver/commands/response.h"
12 #include "chrome/test/webdriver/session.h" 14 #include "chrome/test/webdriver/session.h"
13 #include "chrome/test/webdriver/webdriver_error.h" 15 #include "chrome/test/webdriver/webdriver_error.h"
14 #include "third_party/webdriver/atoms.h" 16 #include "third_party/webdriver/atoms.h"
15 #include "ui/gfx/point.h" 17 #include "ui/gfx/point.h"
16 #include "ui/gfx/size.h" 18 #include "ui/gfx/size.h"
17 19
(...skipping 19 matching lines...) Expand all
37 response->SetError(new Error(kBadRequest, "Path segments is less than 5")); 39 response->SetError(new Error(kBadRequest, "Path segments is less than 5"));
38 return false; 40 return false;
39 } 41 }
40 42
41 // We cannot verify the ID is valid until we execute the command and 43 // We cannot verify the ID is valid until we execute the command and
42 // inject the ID into the in-page cache. 44 // inject the ID into the in-page cache.
43 element = WebElementId(path_segments_.at(4)); 45 element = WebElementId(path_segments_.at(4));
44 return true; 46 return true;
45 } 47 }
46 48
49 Error* WebElementCommand::GetAttribute(const std::string& key,
50 Value** value) const {
51 std::string script = base::StringPrintf(
52 "return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE);
53
54 scoped_ptr<ListValue> args(new ListValue);
kkania 2011/05/27 20:48:47 don't use scoped_ptr here; just allocate it on the
nodchip 2011/05/30 04:51:45 Done.
55 args->Append(element.ToValue());
56 args->Append(Value::CreateStringValue(key));
57
58 Error* error = session_->ExecuteScript(script, args.get(), value);
59 if (error) {
60 return error;
61 }
62
63 return NULL;
64 }
65
66 Error* WebElementCommand::GetClickableLocation(gfx::Point* location) const {
67 Error* error = session_->CheckElementPreconditionsForClicking(element);
68 if (error) {
69 return error;
70 }
71
72 error = session_->GetElementLocationInView(element, location);
73 if (error) {
74 return error;
75 }
76
77 gfx::Size size;
78 error = session_->GetElementSize(session_->current_target(), element, &size);
79 if (error) {
80 return error;
81 }
82
83 location->Offset(size.width() / 2, size.height() / 2);
84 return NULL;
85 }
86
47 ///////////////////// ElementAttributeCommand //////////////////// 87 ///////////////////// ElementAttributeCommand ////////////////////
48 88
49 ElementAttributeCommand::ElementAttributeCommand( 89 ElementAttributeCommand::ElementAttributeCommand(
50 const std::vector<std::string>& path_segments, 90 const std::vector<std::string>& path_segments,
51 DictionaryValue* parameters) 91 DictionaryValue* parameters)
52 : WebElementCommand(path_segments, parameters) {} 92 : WebElementCommand(path_segments, parameters) {}
53 93
54 ElementAttributeCommand::~ElementAttributeCommand() {} 94 ElementAttributeCommand::~ElementAttributeCommand() {}
55 95
56 bool ElementAttributeCommand::DoesGet() { 96 bool ElementAttributeCommand::DoesGet() {
57 return true; 97 return true;
58 } 98 }
59 99
60 void ElementAttributeCommand::ExecuteGet(Response* const response) { 100 void ElementAttributeCommand::ExecuteGet(Response* const response) {
61 // There should be at least 7 segments to match 101 // There should be at least 7 segments to match
62 // "/session/$session/element/$id/attribute/$name" 102 // "/session/$session/element/$id/attribute/$name"
63 if (path_segments_.size() < 7) { 103 if (path_segments_.size() < 7) {
64 response->SetError(new Error(kBadRequest, "Path segments is less than 7")); 104 response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
65 return; 105 return;
66 } 106 }
67 107
68 std::string script = base::StringPrintf( 108 const std::string key = path_segments_.at(6);
69 "return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE); 109 Value* value;
70 110 Error* error = GetAttribute(key, &value);
71 ListValue args;
72 args.Append(element.ToValue());
73 args.Append(Value::CreateStringValue(path_segments_.at(6)));
74
75 Value* result = NULL;
76 Error* error = session_->ExecuteScript(script, &args, &result);
77 if (error) { 111 if (error) {
78 response->SetError(error); 112 response->SetError(error);
79 return; 113 return;
80 } 114 }
81 response->SetValue(result); 115
116 response->SetValue(value);
82 } 117 }
83 118
84 ///////////////////// ElementClearCommand //////////////////// 119 ///////////////////// ElementClearCommand ////////////////////
85 120
86 ElementClearCommand::ElementClearCommand( 121 ElementClearCommand::ElementClearCommand(
87 const std::vector<std::string>& path_segments, 122 const std::vector<std::string>& path_segments,
88 DictionaryValue* parameters) 123 DictionaryValue* parameters)
89 : WebElementCommand(path_segments, parameters) {} 124 : WebElementCommand(path_segments, parameters) {}
90 125
91 ElementClearCommand::~ElementClearCommand() {} 126 ElementClearCommand::~ElementClearCommand() {}
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 if (!result->IsType(Value::TYPE_STRING) && 526 if (!result->IsType(Value::TYPE_STRING) &&
492 !result->IsType(Value::TYPE_NULL)) { 527 !result->IsType(Value::TYPE_NULL)) {
493 response->SetError(new Error( 528 response->SetError(new Error(
494 kUnknownError, "Result is not string or null type")); 529 kUnknownError, "Result is not string or null type"));
495 return; 530 return;
496 } 531 }
497 response->SetValue(result.release()); 532 response->SetValue(result.release());
498 } 533 }
499 534
500 void ElementValueCommand::ExecutePost(Response* const response) { 535 void ElementValueCommand::ExecutePost(Response* const response) {
536 bool is_input = false;
537 Error* error = HasAttribute("tagName", "input", &is_input);
538 if (error) {
539 response->SetError(error);
540 return;
541 }
542
543 bool is_file = false;
544 error = HasAttribute("type", "file", &is_file);
545 if (error) {
546 response->SetError(error);
547 return;
548 }
549
550 // If the element is a file upload control, set the file paths to the element.
551 // Otherwise send the value to the element as key input.
552 if (is_input && is_file) {
553 error = DragAndDropFilePaths();
554 } else {
555 error = SendKeys();
556 }
557
558 if (error) {
559 response->SetError(error);
560 return;
561 }
562
563 response->SetStatus(kSuccess);
564 }
565
566 Error* ElementValueCommand::HasAttribute(const std::string& key,
kkania 2011/05/27 20:48:47 HasAttribute sounds a bit misleading to me. How ab
nodchip 2011/05/30 04:51:45 Done.
567 const std::string& value,
568 bool* result) const {
569 Value* unscoped_value = NULL;
570 Error* error = GetAttribute(key, &unscoped_value);
571 scoped_ptr<Value> scoped_value(unscoped_value);
572 unscoped_value = NULL;
573
574 if (error) {
575 return error;
576 }
577
578 if (!scoped_value.get()) {
kkania 2011/05/27 20:48:47 can this ever happen? I thought ExecuteScript neve
nodchip 2011/05/30 04:51:45 Done.
579 *result = false;
580 return NULL;
581 }
582
583 std::string actual_value;
584 if (!scoped_value->GetAsString(&actual_value)) {
kkania 2011/05/27 20:48:47 could scoped_value be TYPE_NULL?
nodchip 2011/05/30 04:51:45 Done. I added a type check.
585 return new Error(kUnknownError, "Could not get the attribute value");
586 }
587
588 *result = LowerCaseEqualsASCII(actual_value, value.c_str());
589 return NULL;
590 }
591
592 Error* ElementValueCommand::DragAndDropFilePaths() const {
593 ListValue* path_list;
594 if (!GetListParameter("value", &path_list)) {
595 return new Error(kBadRequest, "Missing or invalid 'value' parameter");
596 }
597
598 std::vector<std::string> paths;
599 for (size_t i = 0; i < path_list->GetSize(); ++i) {
600 std::string path;
601 if (!path_list->GetString(i, &path)) {
602 return new Error(kBadRequest, "Invalid element in 'value' parameter");
603 }
604
605 if (!file_util::PathExists(FilePath(path))) {
kkania 2011/05/27 20:48:47 you can't make a file path with a std::string on w
nodchip 2011/05/30 04:51:45 Done.
606 return new Error(kBadRequest, "Path does not exist");
607 }
608
609 paths.push_back(path);
610 }
611
612 gfx::Point location;
613 Error* error = GetClickableLocation(&location);
614 if (error) {
615 return error;
616 }
617
618 return session_->DragAndDropFilePaths(location, paths);
619 }
620
621 Error* ElementValueCommand::SendKeys() const {
501 ListValue* key_list; 622 ListValue* key_list;
502 if (!GetListParameter("value", &key_list)) { 623 if (!GetListParameter("value", &key_list)) {
503 response->SetError(new Error( 624 return new Error(kBadRequest, "Missing or invalid 'value' parameter");
504 kBadRequest, "Missing or invalid 'value' parameter"));
505 return;
506 } 625 }
626
507 // Flatten the given array of strings into one. 627 // Flatten the given array of strings into one.
508 string16 keys; 628 string16 keys;
509 for (size_t i = 0; i < key_list->GetSize(); ++i) { 629 for (size_t i = 0; i < key_list->GetSize(); ++i) {
510 string16 keys_list_part; 630 string16 keys_list_part;
511 key_list->GetString(i, &keys_list_part); 631 key_list->GetString(i, &keys_list_part);
512 for (size_t j = 0; j < keys_list_part.size(); ++j) { 632 for (size_t j = 0; j < keys_list_part.size(); ++j) {
513 if (CBU16_IS_SURROGATE(keys_list_part[j])) { 633 if (CBU16_IS_SURROGATE(keys_list_part[j])) {
514 response->SetError(new Error( 634 return new Error(kBadRequest,
515 kBadRequest, "ChromeDriver only supports characters in the BMP")); 635 "ChromeDriver only supports characters in the BMP");
516 return;
517 } 636 }
518 } 637 }
519 keys.append(keys_list_part); 638 keys.append(keys_list_part);
520 } 639 }
521 640
522 Error* error = session_->SendKeys(element, keys); 641 return session_->SendKeys(element, keys);
523 if (error)
524 response->SetError(error);
525 } 642 }
526 643
527 ///////////////////// ElementTextCommand //////////////////// 644 ///////////////////// ElementTextCommand ////////////////////
528 645
529 ElementTextCommand::ElementTextCommand( 646 ElementTextCommand::ElementTextCommand(
530 const std::vector<std::string>& path_segments, 647 const std::vector<std::string>& path_segments,
531 DictionaryValue* parameters) 648 DictionaryValue* parameters)
532 : WebElementCommand(path_segments, parameters) {} 649 : WebElementCommand(path_segments, parameters) {}
533 650
534 ElementTextCommand::~ElementTextCommand() {} 651 ElementTextCommand::~ElementTextCommand() {}
(...skipping 18 matching lines...) Expand all
553 return; 670 return;
554 } 671 }
555 if (!result->IsType(Value::TYPE_STRING)) { 672 if (!result->IsType(Value::TYPE_STRING)) {
556 response->SetError(new Error(kUnknownError, "Result is not string type")); 673 response->SetError(new Error(kUnknownError, "Result is not string type"));
557 return; 674 return;
558 } 675 }
559 response->SetValue(result.release()); 676 response->SetValue(result.release());
560 } 677 }
561 678
562 } // namespace webdriver 679 } // namespace webdriver
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698