OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/session_manager.h" | 5 #include "chrome/test/webdriver/session_manager.h" |
6 | 6 |
7 #ifdef OS_POSIX | 7 #ifdef OS_POSIX |
8 #include <dirent.h> | 8 #include <dirent.h> |
9 #include <unistd.h> | 9 #include <unistd.h> |
10 #include <sys/stat.h> | 10 #include <sys/stat.h> |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
62 | 62 |
63 Session::Session(const std::string& id) | 63 Session::Session(const std::string& id) |
64 : UITestBase(), id_(id), window_num_(0), implicit_wait_(0), | 64 : UITestBase(), id_(id), window_num_(0), implicit_wait_(0), |
65 current_frame_xpath_(L"") { | 65 current_frame_xpath_(L"") { |
66 } | 66 } |
67 | 67 |
68 bool Session::Init() { | 68 bool Session::Init() { |
69 // Create a temp directory for the new profile. | 69 // Create a temp directory for the new profile. |
70 if (!CreateTemporaryProfileDirectory()) { | 70 if (!CreateTemporaryProfileDirectory()) { |
71 LOG(ERROR) << "Could not make a temp profile directory, " | 71 LOG(ERROR) << "Could not make a temp profile directory, " |
72 << tmp_profile_dir() << std::endl | 72 << tmp_profile_dir() |
73 << "Need to quit, the issue must be fixed"; | 73 << "\nNeed to quit, the issue must be fixed"; |
74 exit(-1); | 74 exit(-1); |
75 } | 75 } |
76 | 76 |
77 SetupCommandLine(); | 77 SetupCommandLine(); |
78 LaunchBrowserAndServer(); | 78 LaunchBrowserAndServer(); |
79 return LoadProxies(); | 79 return LoadProxies(); |
80 } | 80 } |
81 | 81 |
82 scoped_refptr<TabProxy> Session::ActiveTab() { | 82 scoped_refptr<TabProxy> Session::ActiveTab() { |
83 int tab_index; | 83 int tab_index; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 LOG(ERROR) << "Could not generate temp directory name"; | 156 LOG(ERROR) << "Could not generate temp directory name"; |
157 return false; | 157 return false; |
158 } | 158 } |
159 | 159 |
160 if (!CreateDirectoryA(tmp_profile_dir_, NULL)) { | 160 if (!CreateDirectoryA(tmp_profile_dir_, NULL)) { |
161 DWORD dw = GetLastError(); | 161 DWORD dw = GetLastError(); |
162 LOG(ERROR) << "Error code: " << dw; | 162 LOG(ERROR) << "Error code: " << dw; |
163 return false; | 163 return false; |
164 } | 164 } |
165 #endif | 165 #endif |
166 LOG(INFO) << "Using temporary profile directory: " << tmp_profile_dir_; | 166 VLOG(1) << "Using temporary profile directory: " << tmp_profile_dir_; |
167 return true; | 167 return true; |
168 } | 168 } |
169 | 169 |
170 void Session::Terminate() { | 170 void Session::Terminate() { |
171 QuitBrowser(); | 171 QuitBrowser(); |
172 #ifdef OS_POSIX | 172 #ifdef OS_POSIX |
173 FilePath del_dir = FilePath(tmp_profile_dir()); | 173 FilePath del_dir = FilePath(tmp_profile_dir()); |
174 #elif OS_WIN | 174 #elif OS_WIN |
175 FilePath del_dir = FilePath(ASCIIToWide(tmp_profile_dir())); | 175 FilePath del_dir = FilePath(ASCIIToWide(tmp_profile_dir())); |
176 #endif | 176 #endif |
177 if (file_util::PathExists(del_dir) && !file_util::Delete(del_dir, true)) { | 177 if (file_util::PathExists(del_dir) && !file_util::Delete(del_dir, true)) |
178 LOG(ERROR) << "Could not clean up temp directory: " | 178 LOG(ERROR) << "Could not clean up temp directory: " << tmp_profile_dir(); |
179 << tmp_profile_dir() << std::endl; | |
180 } | |
181 } | 179 } |
182 | 180 |
183 ErrorCode Session::ExecuteScript(const std::wstring& script, | 181 ErrorCode Session::ExecuteScript(const std::wstring& script, |
184 const ListValue* const args, | 182 const ListValue* const args, |
185 Value** value) { | 183 Value** value) { |
186 std::string args_as_json; | 184 std::string args_as_json; |
187 base::JSONWriter::Write(static_cast<const Value* const>(args), | 185 base::JSONWriter::Write(static_cast<const Value* const>(args), |
188 /*pretty_print=*/false, | 186 /*pretty_print=*/false, |
189 &args_as_json); | 187 &args_as_json); |
190 | 188 |
191 std::wstring jscript = L"window.domAutomationController.send("; | 189 std::wstring jscript = L"window.domAutomationController.send((function(){" + |
192 jscript.append(L"(function(){") | 190 // Every injected script is fed through the executeScript atom. This atom |
193 // Every injected script is fed through the executeScript atom. This atom | 191 // will catch any errors that are thrown and convert them to the |
194 // will catch any errors that are thrown and convert them to the | 192 // appropriate JSON structure. |
195 // appropriate JSON structure. | 193 build_atom(EXECUTE_SCRIPT, sizeof EXECUTE_SCRIPT) + |
196 .append(build_atom(EXECUTE_SCRIPT, sizeof EXECUTE_SCRIPT)) | 194 L"var result = executeScript(function(){" + script + L"}," + |
197 .append(L"var result = executeScript(function(){") | 195 ASCIIToWide(args_as_json) + L");return JSON.stringify(result);})());"; |
198 .append(script) | |
199 .append(L"},") | |
200 .append(ASCIIToWide(args_as_json)) | |
201 .append(L");return JSON.stringify(result);})());"); | |
202 | 196 |
203 // Should we also log the script that's being executed? It could be several KB | 197 // Should we also log the script that's being executed? It could be several KB |
204 // in size and will add lots of noise to the logs. | 198 // in size and will add lots of noise to the logs. |
205 LOG(INFO) << "Executing script in frame: " << current_frame_xpath_; | 199 VLOG(1) << "Executing script in frame: " << current_frame_xpath_; |
206 | 200 |
207 std::wstring result; | 201 std::wstring result; |
208 scoped_refptr<TabProxy> tab = ActiveTab(); | 202 scoped_refptr<TabProxy> tab = ActiveTab(); |
209 if (!tab->ExecuteAndExtractString(current_frame_xpath_, jscript, &result)) { | 203 if (!tab->ExecuteAndExtractString(current_frame_xpath_, jscript, &result)) { |
210 *value = Value::CreateStringValue( | 204 *value = Value::CreateStringValue( |
211 "Unknown internal script execution failure"); | 205 "Unknown internal script execution failure"); |
212 return kUnknownError; | 206 return kUnknownError; |
213 } | 207 } |
214 | 208 |
215 LOG(INFO) << "...script result: " << result; | 209 VLOG(1) << "...script result: " << result; |
216 std::string temp = WideToASCII(result); | 210 std::string temp = WideToASCII(result); |
217 scoped_ptr<Value> r(base::JSONReader::ReadAndReturnError( | 211 scoped_ptr<Value> r(base::JSONReader::ReadAndReturnError( |
218 temp, true, NULL, NULL)); | 212 temp, true, NULL, NULL)); |
219 if (!r.get()) { | 213 if (!r.get()) { |
220 *value = Value::CreateStringValue( | 214 *value = Value::CreateStringValue( |
221 "Internal script execution error: failed to parse script result"); | 215 "Internal script execution error: failed to parse script result"); |
222 return kUnknownError; | 216 return kUnknownError; |
223 } | 217 } |
224 | 218 |
225 if (r->GetType() != Value::TYPE_DICTIONARY) { | 219 if (r->GetType() != Value::TYPE_DICTIONARY) { |
226 std::ostringstream stream; | 220 std::ostringstream stream; |
227 stream << "Internal script execution error: script result must be a " | 221 stream << "Internal script execution error: script result must be a " |
228 << print_valuetype(Value::TYPE_DICTIONARY) | 222 << print_valuetype(Value::TYPE_DICTIONARY) << ", but was " |
229 << ", but was " | 223 << print_valuetype(r->GetType()) << ": " << result; |
230 << print_valuetype(r->GetType()) << ": " << result; | |
231 *value = Value::CreateStringValue(stream.str()); | 224 *value = Value::CreateStringValue(stream.str()); |
232 return kUnknownError; | 225 return kUnknownError; |
233 } | 226 } |
234 | 227 |
235 DictionaryValue* result_dict = static_cast<DictionaryValue*>(r.get()); | 228 DictionaryValue* result_dict = static_cast<DictionaryValue*>(r.get()); |
236 | 229 |
237 Value* tmp; | 230 Value* tmp; |
238 if (result_dict->Get("value", &tmp)) { | 231 if (result_dict->Get("value", &tmp)) { |
239 // result_dict owns the returned value, so we need to make a copy. | 232 // result_dict owns the returned value, so we need to make a copy. |
240 *value = tmp->DeepCopy(); | 233 *value = tmp->DeepCopy(); |
241 } else { | 234 } else { |
242 // "value" was not defined in the returned dictionary, set to null. | 235 // "value" was not defined in the returned dictionary, set to null. |
243 *value = Value::CreateNullValue(); | 236 *value = Value::CreateNullValue(); |
244 } | 237 } |
245 | 238 |
246 int status; | 239 int status; |
247 if (!result_dict->GetInteger("status", &status)) { | 240 if (!result_dict->GetInteger("status", &status)) { |
248 NOTREACHED() << "...script did not return a status flag."; | 241 NOTREACHED() << "...script did not return a status flag."; |
249 } | 242 } |
250 return static_cast<ErrorCode>(status); | 243 return static_cast<ErrorCode>(status); |
251 } | 244 } |
252 | 245 |
253 } // namespace webdriver | 246 } // namespace webdriver |
OLD | NEW |