OLD | NEW |
1 // Copyright (c) 2010 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/cookie_commands.h" | 5 #include "chrome/test/webdriver/commands/cookie_commands.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/scoped_ptr.h" | 10 #include "base/scoped_ptr.h" |
| 11 #include "base/string_split.h" |
11 #include "base/string_util.h" | 12 #include "base/string_util.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
13 #include "chrome/test/webdriver/cookie.h" | 14 #include "chrome/test/webdriver/cookie.h" |
14 #include "chrome/test/webdriver/session.h" | 15 #include "chrome/test/webdriver/session.h" |
15 #include "chrome/test/webdriver/session_manager.h" | 16 #include "chrome/test/webdriver/session_manager.h" |
16 #include "chrome/test/webdriver/commands/response.h" | 17 #include "chrome/test/webdriver/commands/response.h" |
17 | 18 |
| 19 namespace { |
| 20 // The first build number that the new automation JSON interface for setting, |
| 21 // deleting, and getting detailed cookies is availble for. |
| 22 const int kNewInterfaceBuildNo = 720; |
| 23 } |
| 24 |
18 namespace webdriver { | 25 namespace webdriver { |
19 | 26 |
20 CookieCommand::CookieCommand(const std::vector<std::string>& path_segments, | 27 CookieCommand::CookieCommand(const std::vector<std::string>& path_segments, |
21 const DictionaryValue* const parameters) | 28 const DictionaryValue* const parameters) |
22 : WebDriverCommand(path_segments, parameters) {} | 29 : WebDriverCommand(path_segments, parameters) {} |
23 | 30 |
24 CookieCommand::~CookieCommand() {} | 31 CookieCommand::~CookieCommand() {} |
25 | 32 |
26 bool CookieCommand::Init(Response* const response) { | 33 bool CookieCommand::Init(Response* const response) { |
27 if (WebDriverCommand::Init(response)) { | 34 if (!WebDriverCommand::Init(response)) |
28 if (session_->GetURL(¤t_url_)) { | 35 return false; |
29 return true; | 36 if (!session_->CompareBrowserVersion(kNewInterfaceBuildNo, 0, |
30 } | 37 &uses_new_interface_)) { |
| 38 SET_WEBDRIVER_ERROR(response, "Failed to check Chrome version number", |
| 39 kUnknownError); |
| 40 return false; |
| 41 } |
| 42 if (!session_->GetURL(¤t_url_)) { |
31 SET_WEBDRIVER_ERROR(response, "Failed to query current page URL", | 43 SET_WEBDRIVER_ERROR(response, "Failed to query current page URL", |
32 kInternalServerError); | 44 kInternalServerError); |
33 return false; | 45 return false; |
34 } | 46 } |
35 | 47 return true; |
36 return false; | |
37 } | 48 } |
38 | 49 |
39 bool CookieCommand::DoesDelete() { | 50 bool CookieCommand::DoesDelete() { |
40 return true; | 51 return true; |
41 } | 52 } |
42 | 53 |
43 bool CookieCommand::DoesGet() { | 54 bool CookieCommand::DoesGet() { |
44 return true; | 55 return true; |
45 } | 56 } |
46 | 57 |
47 bool CookieCommand::DoesPost() { | 58 bool CookieCommand::DoesPost() { |
48 return true; | 59 return true; |
49 } | 60 } |
50 | 61 |
51 void CookieCommand::ExecuteGet(Response* const response) { | 62 void CookieCommand::ExecuteGet(Response* const response) { |
52 // TODO(JMikhail): Add GetJSONCookies to automation proxy since | 63 if (uses_new_interface_) { |
53 // GetCookies does not return the necessary information | 64 ListValue* cookies; |
54 std::string cookies; | 65 if (!session_->GetCookies(current_url_.possibly_invalid_spec(), &cookies)) { |
55 std::vector<std::string> tokens; | 66 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies", |
56 | 67 kUnknownError); |
57 if (!session_->GetCookies(current_url_, &cookies)) { | |
58 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies", | |
59 kUnknownError); | |
60 return; | |
61 } | |
62 | |
63 // Note that ';' separates cookies while ':' separates name/value pairs. | |
64 Tokenize(cookies, ";", &tokens); | |
65 scoped_ptr<ListValue> cookie_list(new ListValue()); | |
66 for (std::vector<std::string>::iterator i = tokens.begin(); | |
67 i != tokens.end(); ++i) { | |
68 Cookie cookie(*i); | |
69 if (cookie.valid()) { | |
70 cookie_list->Append(cookie.ToDictionary()); | |
71 } else { | |
72 LOG(ERROR) << "Failed to parse cookie: " << *i; | |
73 SET_WEBDRIVER_ERROR(response, "Could not get all cookies", | |
74 kInternalServerError); | |
75 return; | 68 return; |
76 } | 69 } |
| 70 response->SetStatus(kSuccess); |
| 71 response->SetValue(cookies); |
| 72 } else { |
| 73 std::string cookies; |
| 74 std::vector<std::string> tokens; |
| 75 if (!session_->GetCookiesDeprecated(current_url_, &cookies)) { |
| 76 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies", |
| 77 kUnknownError); |
| 78 return; |
| 79 } |
| 80 // Note that ';' separates cookies while ':' separates name/value pairs. |
| 81 Tokenize(cookies, ";", &tokens); |
| 82 scoped_ptr<ListValue> cookie_list(new ListValue()); |
| 83 for (std::vector<std::string>::iterator i = tokens.begin(); |
| 84 i != tokens.end(); ++i) { |
| 85 Cookie cookie(*i); |
| 86 if (cookie.valid()) { |
| 87 cookie_list->Append(cookie.ToDictionary()); |
| 88 } else { |
| 89 LOG(ERROR) << "Failed to parse cookie: " << *i; |
| 90 SET_WEBDRIVER_ERROR(response, "Could not get all cookies", |
| 91 kInternalServerError); |
| 92 return; |
| 93 } |
| 94 } |
| 95 response->SetStatus(kSuccess); |
| 96 response->SetValue(cookie_list.release()); |
77 } | 97 } |
78 | |
79 response->SetStatus(kSuccess); | |
80 response->SetValue(cookie_list.release()); | |
81 } | 98 } |
82 | 99 |
83 void CookieCommand::ExecutePost(Response* const response) { | 100 void CookieCommand::ExecutePost(Response* const response) { |
84 std::string cookie_string; | 101 std::string cookie_string; |
85 DictionaryValue* cookie_dict; | 102 DictionaryValue* cookie_dict; |
86 | 103 |
87 // Check to see if the cookie was passed in as a JSON onject. | 104 // Check to see if the cookie was passed in as a JSON onject. |
88 if (!GetDictionaryParameter("cookie", &cookie_dict)) { | 105 if (!GetDictionaryParameter("cookie", &cookie_dict)) { |
89 // No valid cookie sent. | 106 // No valid cookie sent. |
90 SET_WEBDRIVER_ERROR(response, "Cookie key not found", | 107 SET_WEBDRIVER_ERROR(response, "Cookie key not found", |
91 kBadRequest); | 108 kBadRequest); |
92 return; | 109 return; |
93 } | 110 } |
94 Cookie cookie(*cookie_dict); | |
95 | 111 |
96 // Make sure the cookie is formated preoperly. | 112 if (uses_new_interface_) { |
97 if (!cookie.valid()) { | 113 std::string domain; |
98 SET_WEBDRIVER_ERROR(response, "Invalid cookie", | 114 if (cookie_dict->GetString("domain", &domain)) { |
99 kBadRequest); | 115 std::vector<std::string> split_domain; |
100 return; | 116 base::SplitString(domain, ':', &split_domain); |
| 117 if (split_domain.size() > 2) { |
| 118 SET_WEBDRIVER_ERROR(response, "Cookie domain has too many colons", |
| 119 kInvalidCookieDomain); |
| 120 return; |
| 121 } else if (split_domain.size() == 2) { |
| 122 // Remove the port number. |
| 123 cookie_dict->SetString("domain", split_domain[0]); |
| 124 } |
| 125 } |
| 126 if (!session_->SetCookie(current_url_.possibly_invalid_spec(), |
| 127 cookie_dict)) { |
| 128 SET_WEBDRIVER_ERROR(response, "Failed to set cookie", |
| 129 kUnableToSetCookie); |
| 130 return; |
| 131 } |
| 132 } else { |
| 133 Cookie cookie(*cookie_dict); |
| 134 |
| 135 // Make sure the cookie is formated preoperly. |
| 136 if (!cookie.valid()) { |
| 137 SET_WEBDRIVER_ERROR(response, "Invalid cookie", |
| 138 kBadRequest); |
| 139 return; |
| 140 } |
| 141 |
| 142 if (!session_->SetCookieDeprecated(current_url_, cookie.ToString())) { |
| 143 SET_WEBDRIVER_ERROR(response, "Failed to set cookie", |
| 144 kUnableToSetCookie); |
| 145 return; |
| 146 } |
| 147 response->SetValue(new StringValue(cookie.ToString())); |
101 } | 148 } |
102 | |
103 if (!session_->SetCookie(current_url_, cookie.ToString())) { | |
104 SET_WEBDRIVER_ERROR(response, "Failed to set cookie", | |
105 kUnableToSetCookie); | |
106 return; | |
107 } | |
108 | |
109 response->SetStatus(kSuccess); | 149 response->SetStatus(kSuccess); |
110 response->SetValue(new StringValue(cookie.ToString())); | |
111 } | 150 } |
112 | 151 |
113 void CookieCommand::ExecuteDelete(Response* const response) { | 152 void CookieCommand::ExecuteDelete(Response* const response) { |
114 std::string cookies; | 153 if (uses_new_interface_) { |
115 std::vector<std::string> tokens; | 154 ListValue* unscoped_cookies; |
| 155 if (!session_->GetCookies(current_url_.possibly_invalid_spec(), |
| 156 &unscoped_cookies)) { |
| 157 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies", |
| 158 kUnknownError); |
| 159 return; |
| 160 } |
| 161 scoped_ptr<ListValue> cookies(unscoped_cookies); |
| 162 for (size_t i = 0; i < cookies->GetSize(); ++i) { |
| 163 DictionaryValue* cookie_dict; |
| 164 if (!cookies->GetDictionary(i, &cookie_dict)) { |
| 165 SET_WEBDRIVER_ERROR(response, "GetCookies returned non-dict type", |
| 166 kUnknownError); |
| 167 return; |
| 168 } |
| 169 std::string name; |
| 170 if (!cookie_dict->GetString("name", &name)) { |
| 171 SET_WEBDRIVER_ERROR( |
| 172 response, |
| 173 "GetCookies returned cookie with missing or invalid 'name'", |
| 174 kUnknownError); |
| 175 return; |
| 176 } |
| 177 if (!session_->DeleteCookie(current_url_.possibly_invalid_spec(), |
| 178 name)) { |
| 179 SET_WEBDRIVER_ERROR(response, "Could not delete all cookies", |
| 180 kUnknownError); |
| 181 return; |
| 182 } |
| 183 } |
| 184 } else { |
| 185 std::string cookies; |
| 186 std::vector<std::string> tokens; |
116 | 187 |
117 if (!session_->GetCookies(current_url_, &cookies)) { | 188 if (!session_->GetCookiesDeprecated(current_url_, &cookies)) { |
118 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies", | 189 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookies", |
119 kUnableToSetCookie); | 190 kUnableToSetCookie); |
120 return; | 191 return; |
121 } | 192 } |
122 | 193 |
123 Tokenize(cookies, ":", &tokens); | 194 Tokenize(cookies, ":", &tokens); |
124 for (std::vector<std::string>::iterator i = tokens.begin(); | 195 for (std::vector<std::string>::iterator i = tokens.begin(); |
125 i != tokens.end(); ++i) { | 196 i != tokens.end(); ++i) { |
126 Cookie cookie(*i); | 197 Cookie cookie(*i); |
127 if (cookie.valid()) { | 198 if (cookie.valid()) { |
128 if (!session_->DeleteCookie(current_url_, cookie.name())) { | 199 if (!session_->DeleteCookie(current_url_.possibly_invalid_spec(), |
129 VLOG(1) << "Could not delete cookie: " << cookie.name() << "\n" | 200 cookie.name())) { |
130 << "Contents of cookie: " << cookie.ToString(); | 201 VLOG(1) << "Could not delete cookie: " << cookie.name() << "\n" |
| 202 << "Contents of cookie: " << cookie.ToString(); |
| 203 SET_WEBDRIVER_ERROR(response, "Could not delete all cookies", |
| 204 kInternalServerError); |
| 205 return; |
| 206 } |
| 207 } else { |
| 208 LOG(ERROR) << "Failed to parse cookie: " << *i; |
131 SET_WEBDRIVER_ERROR(response, "Could not delete all cookies", | 209 SET_WEBDRIVER_ERROR(response, "Could not delete all cookies", |
132 kInternalServerError); | 210 kInternalServerError); |
133 return; | 211 return; |
134 } | 212 } |
135 } else { | |
136 LOG(ERROR) << "Failed to parse cookie: " << *i; | |
137 SET_WEBDRIVER_ERROR(response, "Could not delete all cookies", | |
138 kInternalServerError); | |
139 return; | |
140 } | 213 } |
141 } | 214 } |
142 | 215 |
143 response->SetStatus(kSuccess); | 216 response->SetStatus(kSuccess); |
144 } | 217 } |
145 | 218 |
146 NamedCookieCommand::NamedCookieCommand( | 219 NamedCookieCommand::NamedCookieCommand( |
147 const std::vector<std::string>& path_segments, | 220 const std::vector<std::string>& path_segments, |
148 const DictionaryValue* const parameters) | 221 const DictionaryValue* const parameters) |
149 : WebDriverCommand(path_segments, parameters) {} | 222 : WebDriverCommand(path_segments, parameters) {} |
150 | 223 |
151 NamedCookieCommand::~NamedCookieCommand() {} | 224 NamedCookieCommand::~NamedCookieCommand() {} |
152 | 225 |
153 bool NamedCookieCommand::Init(Response* const response) { | 226 bool NamedCookieCommand::Init(Response* const response) { |
154 if (WebDriverCommand::Init(response)) { | 227 if (!WebDriverCommand::Init(response)) |
155 if (!session_->GetURL(¤t_url_)) { | 228 return false; |
156 SET_WEBDRIVER_ERROR(response, "Failed to query current page URL", | |
157 kInternalServerError); | |
158 return false; | |
159 } | |
160 | 229 |
161 // There should be at least 5 segments to match | 230 if (!session_->CompareBrowserVersion(kNewInterfaceBuildNo, 0, |
162 // /session/:sessionId/cookie/:name | 231 &uses_new_interface_)) { |
163 cookie_name_ = GetPathVariable(4); | 232 SET_WEBDRIVER_ERROR(response, "Failed to check Chrome version number", |
164 if (cookie_name_ == "") { | 233 kUnknownError); |
165 SET_WEBDRIVER_ERROR(response, "No cookie name specified", | 234 return false; |
166 kBadRequest); | |
167 return false; | |
168 } | |
169 | |
170 return true; | |
171 } | 235 } |
172 | 236 |
173 return false; | 237 if (!session_->GetURL(¤t_url_)) { |
| 238 SET_WEBDRIVER_ERROR(response, "Failed to query current page URL", |
| 239 kInternalServerError); |
| 240 return false; |
| 241 } |
| 242 |
| 243 // There should be at least 5 segments to match |
| 244 // /session/:sessionId/cookie/:name |
| 245 cookie_name_ = GetPathVariable(4); |
| 246 if (cookie_name_ == "") { |
| 247 SET_WEBDRIVER_ERROR(response, "No cookie name specified", |
| 248 kBadRequest); |
| 249 return false; |
| 250 } |
| 251 |
| 252 return true; |
174 } | 253 } |
175 | 254 |
176 bool NamedCookieCommand::DoesDelete() { | 255 bool NamedCookieCommand::DoesDelete() { |
177 return true; | 256 return true; |
178 } | 257 } |
179 | 258 |
180 bool NamedCookieCommand::DoesGet() { | 259 void NamedCookieCommand::ExecuteDelete(Response* const response) { |
181 return true; | 260 if (uses_new_interface_) { |
182 } | 261 if (!session_->DeleteCookie(current_url_.possibly_invalid_spec(), |
183 | 262 cookie_name_)) { |
184 void NamedCookieCommand::ExecuteGet(Response* const response) { | 263 SET_WEBDRIVER_ERROR(response, |
185 std::string cookie; | 264 "Failed to delete cookie", |
186 | 265 kUnknownError); |
187 if (!session_->GetCookieByName(current_url_, cookie_name_, &cookie)) { | 266 return; |
188 SET_WEBDRIVER_ERROR(response, "Failed to fetch cookie", | 267 } |
189 kUnknownError); | 268 } else { |
190 return; | 269 if (!session_->DeleteCookieDeprecated(current_url_, cookie_name_)) { |
| 270 SET_WEBDRIVER_ERROR(response, "Failed to delete cookie", |
| 271 kUnknownError); |
| 272 return; |
| 273 } |
191 } | 274 } |
192 | |
193 response->SetStatus(kSuccess); | |
194 response->SetValue(new StringValue(cookie)); | |
195 } | |
196 | |
197 void NamedCookieCommand::ExecuteDelete(Response* const response) { | |
198 if (!session_->DeleteCookie(current_url_, cookie_name_)) { | |
199 SET_WEBDRIVER_ERROR(response, "Failed to delete cookie", | |
200 kUnknownError); | |
201 return; | |
202 } | |
203 | |
204 response->SetStatus(kSuccess); | 275 response->SetStatus(kSuccess); |
205 } | 276 } |
206 | 277 |
207 } // namespace webdriver | 278 } // namespace webdriver |
208 | |
OLD | NEW |