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

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: Convert Capability to mobileEmulation; add integration- and unit-tests 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"
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) { 77 Status IgnoreCapability(const base::Value& option, Capabilities* capabilities) {
78 return Status(kOk); 78 return Status(kOk);
79 } 79 }
80 80
81 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) { 81 Status ParseLogPath(const base::Value& option, Capabilities* capabilities) {
82 if (!option.GetAsString(&capabilities->log_path)) 82 if (!option.GetAsString(&capabilities->log_path))
83 return Status(kUnknownError, "must be a string"); 83 return Status(kUnknownError, "must be a string");
84 return Status(kOk); 84 return Status(kOk);
85 } 85 }
86 86
87 Status ParseDeviceName(std::string device_name, Capabilities* capabilities) {
88 // TODO(srawlins) Move this list into something auto-generated from WebKit.
89 std::map<std::string, MobileDevice> devices;
90 devices["Apple iPhone 3GS"] = MobileDevice(
91 DeviceMetrics(320, 480, 1),
92 "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_2_1 like Mac OS X; en-us) AppleWe bKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8C148 Safari/6533.18.5");
93 // ...
94 devices["Google Nexus 4"] = MobileDevice(
95 DeviceMetrics(384, 640, 2),
96 "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 4 Build/JOP40D) AppleWebKi t/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19");
97 devices["Google Nexus 5"] = MobileDevice(
98 DeviceMetrics(360, 640, 3),
99 "Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKi t/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Mobile Safari/535.19");
100
101 std::map<std::string, MobileDevice>::iterator it = devices.find(device_name);
102
103 if (it == devices.end())
104 return Status(kUnknownError, "must be a valid device");
samuong 2014/05/07 23:39:36 It would be good to also mention what the invalid
sam.rawlins 2014/05/09 05:35:17 Done.
105
106 MobileDevice device = it->second;
107
108 capabilities->device_metrics.width = device.device_metrics.width;
109 capabilities->device_metrics.height = device.device_metrics.height;
110 capabilities->device_metrics.device_scale_factor =
111 device.device_metrics.device_scale_factor;
112 capabilities->device_metrics.emulate_viewport = false;
113 capabilities->device_metrics.fit_window = true;
114 capabilities->device_metrics.text_autosizing = true;
115 capabilities->device_metrics.font_scale_factor = 1;
116
117 capabilities->switches.SetUnparsedSwitch(
118 "--user-agent='" + device.user_agent + "'");
119
120 return Status(kOk);
121 }
122
123 Status ParseMobileEmulation(const base::Value& option,
124 Capabilities* capabilities) {
125 const base::DictionaryValue* mobile_emulation;
126 if (!option.GetAsDictionary(&mobile_emulation))
127 return Status(kUnknownError, "must be a dictionary");
samuong 2014/05/07 23:39:36 There are a few error messages that just say "must
sam.rawlins 2014/05/09 05:35:17 Done.
128
129 if (mobile_emulation->HasKey("deviceName")) {
130 // Cannot use any other options with deviceName
131 if (mobile_emulation->size() > 1)
132 return Status(kUnknownError, "'deviceName' must be used alone");
133
134 std::string device_name;
135 if (!mobile_emulation->GetString("deviceName", &device_name))
136 return Status(kUnknownError, "'deviceName' must be a string");
137
138 return ParseDeviceName(device_name, capabilities);
139 }
140
141 if (mobile_emulation->HasKey("deviceMetrics")) {
142 const base::DictionaryValue* metrics;
143 if (!mobile_emulation->GetDictionary("deviceMetrics", &metrics))
144 return Status(kUnknownError, "'deviceMetrics' must be a dictionary");
145
146 if (!metrics->GetInteger("width", &capabilities->device_metrics.width) ||
147 !metrics->GetInteger("height", &capabilities->device_metrics.height) ||
148 !metrics->GetDouble("pixelRatio",
149 &capabilities->device_metrics.device_scale_factor))
150 return Status(kUnknownError, "invalid 'deviceMetrics'");
151
152 capabilities->device_metrics.emulate_viewport = false;
153 capabilities->device_metrics.fit_window = true;
154 capabilities->device_metrics.text_autosizing = true;
155 capabilities->device_metrics.font_scale_factor = 1;
samuong 2014/05/07 23:39:36 This is done a few times. Should we put this in a
sam.rawlins 2014/05/09 05:35:17 Done.
156 }
157
158 if (mobile_emulation->HasKey("userAgent")) {
159 std::string user_agent;
160 if (!mobile_emulation->GetString("userAgent", &user_agent))
161 return Status(kUnknownError, "'userAgent' must be a string");
162
163 capabilities->switches.SetUnparsedSwitch(
164 "--user-agent='" + user_agent + "'");
165 }
166
167 return Status(kOk);
168 }
169
87 Status ParseSwitches(const base::Value& option, 170 Status ParseSwitches(const base::Value& option,
88 Capabilities* capabilities) { 171 Capabilities* capabilities) {
89 const base::ListValue* switches_list = NULL; 172 const base::ListValue* switches_list = NULL;
90 if (!option.GetAsList(&switches_list)) 173 if (!option.GetAsList(&switches_list))
91 return Status(kUnknownError, "must be a list"); 174 return Status(kUnknownError, "must be a list");
92 for (size_t i = 0; i < switches_list->GetSize(); ++i) { 175 for (size_t i = 0; i < switches_list->GetSize(); ++i) {
93 std::string arg_string; 176 std::string arg_string;
94 if (!switches_list->GetString(i, &arg_string)) 177 if (!switches_list->GetString(i, &arg_string))
95 return Status(kUnknownError, "each argument must be a string"); 178 return Status(kUnknownError, "each argument must be a string");
96 capabilities->switches.SetUnparsedSwitch(arg_string); 179 capabilities->switches.SetUnparsedSwitch(arg_string);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 parser_map["androidUseRunningApp"] = 348 parser_map["androidUseRunningApp"] =
266 base::Bind(&ParseBoolean, &capabilities->android_use_running_app); 349 base::Bind(&ParseBoolean, &capabilities->android_use_running_app);
267 parser_map["args"] = base::Bind(&ParseSwitches); 350 parser_map["args"] = base::Bind(&ParseSwitches);
268 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync"); 351 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync");
269 } else if (is_existing) { 352 } else if (is_existing) {
270 parser_map["debuggerAddress"] = base::Bind(&ParseUseExistingBrowser); 353 parser_map["debuggerAddress"] = base::Bind(&ParseUseExistingBrowser);
271 } else { 354 } else {
272 parser_map["args"] = base::Bind(&ParseSwitches); 355 parser_map["args"] = base::Bind(&ParseSwitches);
273 parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary); 356 parser_map["binary"] = base::Bind(&ParseFilePath, &capabilities->binary);
274 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach); 357 parser_map["detach"] = base::Bind(&ParseBoolean, &capabilities->detach);
358 parser_map["mobileEmulation"] =
359 base::Bind(&ParseMobileEmulation);
samuong 2014/05/07 23:39:36 Can be one line.
sam.rawlins 2014/05/09 05:35:17 Done.
275 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches); 360 parser_map["excludeSwitches"] = base::Bind(&ParseExcludeSwitches);
276 parser_map["extensions"] = base::Bind(&ParseExtensions); 361 parser_map["extensions"] = base::Bind(&ParseExtensions);
277 parser_map["forceDevToolsScreenshot"] = base::Bind( 362 parser_map["forceDevToolsScreenshot"] = base::Bind(
278 &ParseBoolean, &capabilities->force_devtools_screenshot); 363 &ParseBoolean, &capabilities->force_devtools_screenshot);
279 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync"); 364 parser_map["loadAsync"] = base::Bind(&IgnoreDeprecatedOption, "loadAsync");
280 parser_map["localState"] = 365 parser_map["localState"] =
281 base::Bind(&ParseDict, &capabilities->local_state); 366 base::Bind(&ParseDict, &capabilities->local_state);
282 parser_map["logPath"] = base::Bind(&ParseLogPath); 367 parser_map["logPath"] = base::Bind(&ParseLogPath);
283 parser_map["minidumpPath"] = 368 parser_map["minidumpPath"] =
284 base::Bind(&ParseString, &capabilities->minidump_path); 369 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)) { 518 if (desired_caps.Get(it->first, &capability)) {
434 Status status = it->second.Run(*capability, this); 519 Status status = it->second.Run(*capability, this);
435 if (status.IsError()) { 520 if (status.IsError()) {
436 return Status( 521 return Status(
437 kUnknownError, "cannot parse capability: " + it->first, status); 522 kUnknownError, "cannot parse capability: " + it->first, status);
438 } 523 }
439 } 524 }
440 } 525 }
441 return Status(kOk); 526 return Status(kOk);
442 } 527 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698