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

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, 6 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
58 } 60 }
59 61
60 void ElementAttributeCommand::ExecuteGet(Response* const response) { 62 void ElementAttributeCommand::ExecuteGet(Response* const response) {
61 // There should be at least 7 segments to match 63 // There should be at least 7 segments to match
62 // "/session/$session/element/$id/attribute/$name" 64 // "/session/$session/element/$id/attribute/$name"
63 if (path_segments_.size() < 7) { 65 if (path_segments_.size() < 7) {
64 response->SetError(new Error(kBadRequest, "Path segments is less than 7")); 66 response->SetError(new Error(kBadRequest, "Path segments is less than 7"));
65 return; 67 return;
66 } 68 }
67 69
68 std::string script = base::StringPrintf( 70 const std::string key = path_segments_.at(6);
69 "return (%s).apply(null, arguments);", atoms::GET_ATTRIBUTE); 71 Value* value;
70 72 Error* error = session_->GetAttribute(element, 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) { 73 if (error) {
78 response->SetError(error); 74 response->SetError(error);
79 return; 75 return;
80 } 76 }
81 response->SetValue(result); 77
78 response->SetValue(value);
82 } 79 }
83 80
84 ///////////////////// ElementClearCommand //////////////////// 81 ///////////////////// ElementClearCommand ////////////////////
85 82
86 ElementClearCommand::ElementClearCommand( 83 ElementClearCommand::ElementClearCommand(
87 const std::vector<std::string>& path_segments, 84 const std::vector<std::string>& path_segments,
88 DictionaryValue* parameters) 85 DictionaryValue* parameters)
89 : WebElementCommand(path_segments, parameters) {} 86 : WebElementCommand(path_segments, parameters) {}
90 87
91 ElementClearCommand::~ElementClearCommand() {} 88 ElementClearCommand::~ElementClearCommand() {}
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 if (!result->IsType(Value::TYPE_STRING) && 488 if (!result->IsType(Value::TYPE_STRING) &&
492 !result->IsType(Value::TYPE_NULL)) { 489 !result->IsType(Value::TYPE_NULL)) {
493 response->SetError(new Error( 490 response->SetError(new Error(
494 kUnknownError, "Result is not string or null type")); 491 kUnknownError, "Result is not string or null type"));
495 return; 492 return;
496 } 493 }
497 response->SetValue(result.release()); 494 response->SetValue(result.release());
498 } 495 }
499 496
500 void ElementValueCommand::ExecutePost(Response* const response) { 497 void ElementValueCommand::ExecutePost(Response* const response) {
498 bool is_input = false;
499 Error* error = HasAttributeWithLowerCaseValueASCII("tagName", "input",
500 &is_input);
501 if (error) {
502 response->SetError(error);
503 return;
504 }
505
506 bool is_file = false;
507 error = HasAttributeWithLowerCaseValueASCII("type", "file", &is_file);
508 if (error) {
509 response->SetError(error);
510 return;
511 }
512
513 // If the element is a file upload control, set the file paths to the element.
514 // Otherwise send the value to the element as key input.
515 if (is_input && is_file) {
516 error = DragAndDropFilePaths();
517 } else {
518 error = SendKeys();
519 }
520
521 if (error) {
522 response->SetError(error);
523 return;
524 }
525 }
526
527 Error* ElementValueCommand::HasAttributeWithLowerCaseValueASCII(
528 const std::string& key, const std::string& value, bool* result) const {
529 Value* unscoped_value = NULL;
530 Error* error = session_->GetAttribute(element, key, &unscoped_value);
531 scoped_ptr<Value> scoped_value(unscoped_value);
532 unscoped_value = NULL;
533
534 if (error) {
535 return error;
536 }
537
538 std::string actual_value;
539 if (!scoped_value->GetAsString(&actual_value)) {
540 return new Error(kUnknownError,
541 StringPrintf("Attribute '%s' did not have a string value",
kkania 2011/06/07 15:12:04 base::StringPrintf is preferred
nodchip 2011/06/08 02:37:19 Done.
542 key.c_str()));
543 }
544
545 *result = LowerCaseEqualsASCII(actual_value, value.c_str());
546 return NULL;
547 }
548
549 Error* ElementValueCommand::DragAndDropFilePaths() const {
550 ListValue* path_list;
551 if (!GetListParameter("value", &path_list)) {
552 return new Error(kBadRequest, "Missing or invalid 'value' parameter");
553 }
554
555 std::vector<std::string> paths;
556 for (size_t i = 0; i < path_list->GetSize(); ++i) {
557 FilePath::StringType path;
558 if (!path_list->GetString(i, &path)) {
559 return new Error(kBadRequest,
560 StringPrintf("%zd-th element in 'value' is not string",
kkania 2011/06/07 15:12:04 The style guide says use %"PRIuS" for size_t (http
nodchip 2011/06/08 02:37:19 Done.
561 i));
562 }
563
564 if (!file_util::PathExists(FilePath(path))) {
kkania 2011/06/07 15:12:04 Does the spec actually disallow non-existent file
nodchip 2011/06/08 02:37:19 There are no spec about file uploading in the offi
565 return new Error(kBadRequest,
566 StringPrintf("'%s' does not exist on the file system",
kkania 2011/06/07 15:12:04 base::
nodchip 2011/06/08 02:37:19 Done.
567 path.c_str()));
568 }
569
570 paths.push_back(path);
571 }
572
573 gfx::Point location;
574 Error* error = session_->GetClickableLocation(element, &location);
575 if (error) {
576 return error;
577 }
578
579 return session_->DragAndDropFilePaths(location, paths);
580 }
581
582 Error* ElementValueCommand::SendKeys() const {
501 ListValue* key_list; 583 ListValue* key_list;
502 if (!GetListParameter("value", &key_list)) { 584 if (!GetListParameter("value", &key_list)) {
503 response->SetError(new Error( 585 return new Error(kBadRequest, "Missing or invalid 'value' parameter");
504 kBadRequest, "Missing or invalid 'value' parameter"));
505 return;
506 } 586 }
587
507 // Flatten the given array of strings into one. 588 // Flatten the given array of strings into one.
508 string16 keys; 589 string16 keys;
509 for (size_t i = 0; i < key_list->GetSize(); ++i) { 590 for (size_t i = 0; i < key_list->GetSize(); ++i) {
510 string16 keys_list_part; 591 string16 keys_list_part;
511 key_list->GetString(i, &keys_list_part); 592 key_list->GetString(i, &keys_list_part);
512 for (size_t j = 0; j < keys_list_part.size(); ++j) { 593 for (size_t j = 0; j < keys_list_part.size(); ++j) {
513 if (CBU16_IS_SURROGATE(keys_list_part[j])) { 594 if (CBU16_IS_SURROGATE(keys_list_part[j])) {
514 response->SetError(new Error( 595 return new Error(kBadRequest,
515 kBadRequest, "ChromeDriver only supports characters in the BMP")); 596 "ChromeDriver only supports characters in the BMP");
516 return;
517 } 597 }
518 } 598 }
519 keys.append(keys_list_part); 599 keys.append(keys_list_part);
520 } 600 }
521 601
522 Error* error = session_->SendKeys(element, keys); 602 return session_->SendKeys(element, keys);
523 if (error)
524 response->SetError(error);
525 } 603 }
526 604
527 ///////////////////// ElementTextCommand //////////////////// 605 ///////////////////// ElementTextCommand ////////////////////
528 606
529 ElementTextCommand::ElementTextCommand( 607 ElementTextCommand::ElementTextCommand(
530 const std::vector<std::string>& path_segments, 608 const std::vector<std::string>& path_segments,
531 DictionaryValue* parameters) 609 DictionaryValue* parameters)
532 : WebElementCommand(path_segments, parameters) {} 610 : WebElementCommand(path_segments, parameters) {}
533 611
534 ElementTextCommand::~ElementTextCommand() {} 612 ElementTextCommand::~ElementTextCommand() {}
(...skipping 18 matching lines...) Expand all
553 return; 631 return;
554 } 632 }
555 if (!result->IsType(Value::TYPE_STRING)) { 633 if (!result->IsType(Value::TYPE_STRING)) {
556 response->SetError(new Error(kUnknownError, "Result is not string type")); 634 response->SetError(new Error(kUnknownError, "Result is not string type"));
557 return; 635 return;
558 } 636 }
559 response->SetValue(result.release()); 637 response->SetValue(result.release());
560 } 638 }
561 639
562 } // namespace webdriver 640 } // namespace webdriver
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698