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

Side by Side Diff: chrome/test/chromedriver/capabilities.cc

Issue 251933005: [ChromeDriver] Support mobile emulation on desktop Chrome. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Cleaning up DeviceMetrics architecture; adding a test Created 6 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
OLDNEW
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/capabilities.h" 5 #include "chrome/test/chromedriver/capabilities.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
11 #include "base/json/string_escape.h" 11 #include "base/json/string_escape.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/string_split.h" 14 #include "base/strings/string_split.h"
15 #include "base/strings/string_tokenizer.h" 15 #include "base/strings/string_tokenizer.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "base/strings/stringprintf.h" 17 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h" 18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h" 19 #include "base/values.h"
20 #include "chrome/test/chromedriver/chrome/status.h" 20 #include "chrome/test/chromedriver/chrome/status.h"
21 #include "chrome/test/chromedriver/logging.h" 21 #include "chrome/test/chromedriver/logging.h"
22 #include "chrome/test/chromedriver/mobile_device.h"
22 #include "net/base/net_util.h" 23 #include "net/base/net_util.h"
23 24
24 namespace { 25 namespace {
25 26
26 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser; 27 typedef base::Callback<Status(const base::Value&, Capabilities*)> Parser;
27 28
28 Status ParseBoolean( 29 Status ParseBoolean(
29 bool* to_set, 30 bool* to_set,
30 const base::Value& option, 31 const base::Value& option,
31 Capabilities* capabilities) { 32 Capabilities* capabilities) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) { 78 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) {
78 return Status(kOk); 79 return Status(kOk);
79 } 80 }
80 81
81 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) { 82 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) {
82 if (!option.GetAsString(&capabilities->log_path)) 83 if (!option.GetAsString(&capabilities->log_path))
83 return Status(kUnknownError, "must be a string"); 84 return Status(kUnknownError, "must be a string");
84 return Status(kOk); 85 return Status(kOk);
85 } 86 }
86 87
88 Status ParseDeviceName(std::string device_name, Capabilities* capabilities) {
89 scoped_ptr<MobileDevice> device;
90 Status status = FindMobileDevice(device_name, &device);
91
92 if (status.IsError()) {
93 return Status(kUnknownError,
94 "'" + device_name + "' must be a valid device",
95 status);
96 }
97
98 capabilities->device_metrics.reset(device->device_metrics.release());
99 capabilities->switches.SetUnparsedSwitch(
100 "--user-agent='" + device->user_agent + "'");
samuong 2014/05/16 22:56:21 I noticed that if you use SetUnparsedSwitch, the s
sam.rawlins 2014/05/16 23:35:51 Done.
101
102 return Status(kOk);
103 }
104
105 Status ParseMobileEmulation(const base::Value& option,
106 Capabilities* capabilities) {
107 const base::DictionaryValue* mobile_emulation;
108 if (!option.GetAsDictionary(&mobile_emulation))
109 return Status(kUnknownError, "'mobileEmulation' must be a dictionary");
110
111 if (mobile_emulation->HasKey("deviceName")) {
112 // Cannot use any other options with deviceName.
113 if (mobile_emulation->size() > 1)
114 return Status(kUnknownError, "'deviceName' must be used alone");
115
116 std::string device_name;
117 if (!mobile_emulation->GetString("deviceName", &device_name))
118 return Status(kUnknownError, "'deviceName' must be a string");
119
120 return ParseDeviceName(device_name, capabilities);
121 }
122
123 if (mobile_emulation->HasKey("deviceMetrics")) {
124 const base::DictionaryValue* metrics;
125 if (!mobile_emulation->GetDictionary("deviceMetrics", &metrics))
126 return Status(kUnknownError, "'deviceMetrics' must be a dictionary");
127
128 int width;
129 int height;
130 double device_scale_factor;
131 if (!metrics->GetInteger("width", &width) ||
132 !metrics->GetInteger("height", &height) ||
133 !metrics->GetDouble("pixelRatio", &device_scale_factor))
134 return Status(kUnknownError, "invalid 'deviceMetrics'");
135
136 DeviceMetrics* device_metrics =
137 new DeviceMetrics(width, height, device_scale_factor);
138 capabilities->device_metrics =
139 scoped_ptr<DeviceMetrics>(device_metrics);
140 }
141
142 if (mobile_emulation->HasKey("userAgent")) {
143 std::string user_agent;
144 if (!mobile_emulation->GetString("userAgent", &user_agent))
145 return Status(kUnknownError, "'userAgent' must be a string");
146
147 capabilities->switches.SetUnparsedSwitch(
148 "--user-agent='" + user_agent + "'");
samuong 2014/05/16 22:56:21 Same as above.
sam.rawlins 2014/05/16 23:35:51 Done.
149 }
150
151 return Status(kOk);
152 }
153
87 Status ParseSwitches(const base::Value& option, 154 Status ParseSwitches(const base::Value& option,
88 Capabilities* capabilities) { 155 Capabilities* capabilities) {
89 const base::ListValue* switches_list = NULL; 156 const base::ListValue* switches_list = NULL;
90 if (!option.GetAsList(&switches_list)) 157 if (!option.GetAsList(&switches_list))
91 return Status(kUnknownError, "must be a list"); 158 return Status(kUnknownError, "must be a list");
92 for (size_t i = 0; i < switches_list->GetSize(); ++i) { 159 for (size_t i = 0; i < switches_list->GetSize(); ++i) {
93 std::string arg_string; 160 std::string arg_string;
94 if (!switches_list->GetString(i, &arg_string)) 161 if (!switches_list->GetString(i, &arg_string))
95 return Status(kUnknownError, "each argument must be a string"); 162 return Status(kUnknownError, "each argument must be a string");
96 capabilities->switches.SetUnparsedSwitch(arg_string); 163 capabilities->switches.SetUnparsedSwitch(arg_string);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 parser_map["androidUseRunningApp"] = 332 parser_map["androidUseRunningApp"] =
266 base::Bind(&ParseBoolean, &capabilities->android_use_running_app); 333 base::Bind(&ParseBoolean, &capabilities->android_use_running_app);
267 parser_map["args"] = base::Bind(&ParseSwitches); 334 parser_map["args"] = base::Bind(&ParseSwitches);
268 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync"); 335 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync");
269 } else if (is_existing) { 336 } else if (is_existing) {
270 parser_map["debuggerAddress"] = base::Bind(&ParseUseExistingBrowser); 337 parser_map["debuggerAddress"] = base::Bind(&ParseUseExistingBrowser);
271 } else { 338 } else {
272 parser_map["args"] = base::Bind(&ParseSwitches); 339 parser_map["args"] = base::Bind(&ParseSwitches);
273 parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary); 340 parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary);
274 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach); 341 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach);
342 parser_map["mobileEmulation"] = base::Bind(&ParseMobileEmulation);
275 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches); 343 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches);
276 parser_map["extensions"] = base::Bind(&ParseExtensions); 344 parser_map["extensions"] = base::Bind(&ParseExtensions);
277 parser_map["forceDevToolsScreenshot"] = base::Bind( 345 parser_map["forceDevToolsScreenshot"] = base::Bind(
278 &ParseBoolean, &capabilities->force_devtools_screenshot); 346 &ParseBoolean, &capabilities->force_devtools_screenshot);
279 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync"); 347 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync");
280 parser_map["localState"] = 348 parser_map["localState"] =
281 base::Bind(&ParseDict, &capabilities->local_state); 349 base::Bind(&ParseDict, &capabilities->local_state);
282 parser_map["logPath"] = base::Bind(&ParseLogPath); 350 parser_map["logPath"] = base::Bind(&ParseLogPath);
283 parser_map["minidumpPath"] = 351 parser_map["minidumpPath"] =
284 base::Bind(&ParseString, &capabilities->minidump_path); 352 base::Bind(&ParseString, &capabilities->minidump_path);
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 if (desired_caps.Get(it->first, &capability)) { 501 if (desired_caps.Get(it->first, &capability)) {
434 Status status = it->second.Run(*capability, this); 502 Status status = it->second.Run(*capability, this);
435 if (status.IsError()) { 503 if (status.IsError()) {
436 return Status( 504 return Status(
437 kUnknownError, "cannot parse capability: " + it->first, status); 505 kUnknownError, "cannot parse capability: " + it->first, status);
438 } 506 }
439 } 507 }
440 } 508 }
441 return Status(kOk); 509 return Status(kOk);
442 } 510 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698