| OLD | NEW |
| 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/automation.h" | 5 #include "chrome/test/webdriver/automation.h" |
| 6 | 6 |
| 7 #if defined(OS_WIN) | 7 #if defined(OS_WIN) |
| 8 #include <windows.h> | 8 #include <windows.h> |
| 9 #endif | 9 #endif |
| 10 | 10 |
| 11 #include "base/base_paths.h" | 11 #include "base/base_paths.h" |
| 12 #include "base/basictypes.h" |
| 12 #include "base/callback.h" | 13 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 14 #include "base/environment.h" | 15 #include "base/environment.h" |
| 15 #include "base/file_path.h" | 16 #include "base/file_path.h" |
| 16 #include "base/file_util.h" | 17 #include "base/file_util.h" |
| 17 #include "base/json/json_writer.h" | 18 #include "base/json/json_writer.h" |
| 18 #include "base/logging.h" | 19 #include "base/logging.h" |
| 20 #include "base/memory/ref_counted.h" |
| 19 #include "base/path_service.h" | 21 #include "base/path_service.h" |
| 20 #include "base/string_number_conversions.h" | 22 #include "base/string_number_conversions.h" |
| 21 #include "base/string_split.h" | 23 #include "base/string_split.h" |
| 22 #include "base/stringprintf.h" | 24 #include "base/stringprintf.h" |
| 23 #include "base/synchronization/waitable_event.h" | 25 #include "base/synchronization/waitable_event.h" |
| 24 #include "base/utf_string_conversions.h" | 26 #include "base/utf_string_conversions.h" |
| 25 #include "base/values.h" | 27 #include "base/values.h" |
| 26 #include "chrome/common/automation_constants.h" | 28 #include "chrome/common/automation_constants.h" |
| 27 #include "chrome/common/chrome_constants.h" | 29 #include "chrome/common/chrome_constants.h" |
| 28 #include "chrome/common/chrome_switches.h" | 30 #include "chrome/common/chrome_switches.h" |
| 29 #include "chrome/common/url_constants.h" | 31 #include "chrome/common/url_constants.h" |
| 30 #include "chrome/test/automation/automation_json_requests.h" | 32 #include "chrome/test/automation/automation_json_requests.h" |
| 31 #include "chrome/test/automation/automation_proxy.h" | 33 #include "chrome/test/automation/automation_proxy.h" |
| 34 #include "chrome/test/automation/browser_proxy.h" |
| 32 #include "chrome/test/automation/extension_proxy.h" | 35 #include "chrome/test/automation/extension_proxy.h" |
| 33 #include "chrome/test/automation/proxy_launcher.h" | 36 #include "chrome/test/automation/proxy_launcher.h" |
| 37 #include "chrome/test/automation/tab_proxy.h" |
| 34 #include "chrome/test/webdriver/frame_path.h" | 38 #include "chrome/test/webdriver/frame_path.h" |
| 35 #include "chrome/test/webdriver/webdriver_error.h" | 39 #include "chrome/test/webdriver/webdriver_error.h" |
| 36 #include "ui/gfx/point.h" | 40 #include "ui/gfx/point.h" |
| 37 | 41 |
| 38 #if defined(OS_WIN) | 42 #if defined(OS_WIN) |
| 39 #include "base/win/registry.h" | 43 #include "base/win/registry.h" |
| 40 #include "base/win/windows_version.h" | 44 #include "base/win/windows_version.h" |
| 41 #endif | 45 #endif |
| 42 | 46 |
| 43 namespace { | 47 namespace { |
| 44 | 48 |
| 49 // Iterates through each browser executable path, and checks if the path exists |
| 50 // in any of the given locations. If found, returns true and sets |browser_exe|. |
| 51 bool CheckForChromeExe(const std::vector<FilePath>& browser_exes, |
| 52 const std::vector<FilePath>& locations, |
| 53 FilePath* browser_exe) { |
| 54 for (size_t i = 0; i < browser_exes.size(); ++i) { |
| 55 for (size_t j = 0; j < locations.size(); ++j) { |
| 56 FilePath path = locations[j].Append(browser_exes[i]); |
| 57 if (file_util::PathExists(path)) { |
| 58 *browser_exe = path; |
| 59 return true; |
| 60 } |
| 61 } |
| 62 } |
| 63 return false; |
| 64 } |
| 65 |
| 45 // Gets the path to the default Chrome executable. Returns true on success. | 66 // Gets the path to the default Chrome executable. Returns true on success. |
| 46 bool GetDefaultChromeExe(FilePath* browser_exe) { | 67 bool GetDefaultChromeExe(FilePath* browser_exe) { |
| 68 // Instead of using chrome constants, we hardcode these constants here so |
| 69 // that we can locate chrome or chromium regardless of the branding |
| 70 // chromedriver is built with. It may be argued that then we need to keep |
| 71 // these in sync with chrome constants. However, if chrome constants changes, |
| 72 // we need to look for the previous and new versions to support some |
| 73 // backwards compatibility. |
| 74 #if defined(OS_WIN) |
| 75 FilePath browser_exes_array[] = { |
| 76 FilePath(L"chrome.exe") |
| 77 }; |
| 78 #elif defined(OS_MACOSX) |
| 79 FilePath browser_exes_array[] = { |
| 80 FilePath("Google Chrome.app/Contents/MacOS/Google Chrome"), |
| 81 FilePath("Chromium.app/Contents/MacOS/Chromium") |
| 82 }; |
| 83 #elif defined(OS_LINUX) |
| 84 FilePath browser_exes_array[] = { |
| 85 FilePath("google-chrome"), |
| 86 FilePath("chrome"), |
| 87 FilePath("chromium"), |
| 88 FilePath("chromium-browser") |
| 89 }; |
| 90 #endif |
| 91 std::vector<FilePath> browser_exes( |
| 92 browser_exes_array, browser_exes_array + arraysize(browser_exes_array)); |
| 93 |
| 94 // Step 1: Check the directory this module resides in. This is done |
| 95 // before all else so that the tests will pickup the built chrome. |
| 96 FilePath module_dir; |
| 97 if (PathService::Get(base::DIR_MODULE, &module_dir)) { |
| 98 for (size_t j = 0; j < browser_exes.size(); ++j) { |
| 99 FilePath path = module_dir.Append(browser_exes[j]); |
| 100 if (file_util::PathExists(path)) { |
| 101 *browser_exe = path; |
| 102 return true; |
| 103 } |
| 104 } |
| 105 } |
| 106 |
| 107 // Step 2: Add all possible install locations, in order they should be |
| 108 // searched. If a location can only hold a chromium install, add it to |
| 109 // |chromium_locations|. Since on some platforms we cannot tell by the binary |
| 110 // name whether it is chrome or chromium, we search these locations last. |
| 111 // We attempt to run chrome before chromium, if any install can be found. |
| 47 std::vector<FilePath> locations; | 112 std::vector<FilePath> locations; |
| 48 // Add the directory which this module resides in. | 113 std::vector<FilePath> chromium_locations; |
| 49 FilePath module_dir; | |
| 50 if (PathService::Get(base::DIR_MODULE, &module_dir)) | |
| 51 locations.push_back(module_dir); | |
| 52 | |
| 53 #if defined(OS_WIN) | 114 #if defined(OS_WIN) |
| 54 // Add the App Paths registry key location. | 115 // Add the App Paths registry key location. |
| 55 const wchar_t kSubKey[] = | 116 const wchar_t kSubKey[] = |
| 56 L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe"; | 117 L"Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe"; |
| 57 base::win::RegKey key(HKEY_CURRENT_USER, kSubKey, KEY_READ); | 118 base::win::RegKey key(HKEY_CURRENT_USER, kSubKey, KEY_READ); |
| 58 std::wstring path; | 119 std::wstring path; |
| 59 if (key.ReadValue(L"path", &path) == ERROR_SUCCESS) | 120 if (key.ReadValue(L"path", &path) == ERROR_SUCCESS) |
| 60 locations.push_back(FilePath(path)); | 121 locations.push_back(FilePath(path)); |
| 61 base::win::RegKey sys_key(HKEY_LOCAL_MACHINE, kSubKey, KEY_READ); | 122 base::win::RegKey sys_key(HKEY_LOCAL_MACHINE, kSubKey, KEY_READ); |
| 62 if (sys_key.ReadValue(L"path", &path) == ERROR_SUCCESS) | 123 if (sys_key.ReadValue(L"path", &path) == ERROR_SUCCESS) |
| 63 locations.push_back(FilePath(path)); | 124 locations.push_back(FilePath(path)); |
| 64 | 125 |
| 65 // Add the user-level location for Chrome. | 126 // Add the user-level location for Chrome. |
| 66 FilePath app_from_google(L"Google\\Chrome\\Application"); | 127 FilePath app_from_google(L"Google\\Chrome\\Application"); |
| 128 FilePath app_from_chromium(L"Chromium\\Application"); |
| 67 scoped_ptr<base::Environment> env(base::Environment::Create()); | 129 scoped_ptr<base::Environment> env(base::Environment::Create()); |
| 68 std::string home_dir; | 130 std::string home_dir; |
| 69 if (env->GetVar("userprofile", &home_dir)) { | 131 if (env->GetVar("userprofile", &home_dir)) { |
| 70 FilePath default_location(UTF8ToWide(home_dir)); | 132 FilePath default_location(UTF8ToWide(home_dir)); |
| 71 if (base::win::GetVersion() < base::win::VERSION_VISTA) { | 133 if (base::win::GetVersion() < base::win::VERSION_VISTA) { |
| 72 default_location = default_location.Append( | 134 default_location = default_location.Append( |
| 73 L"Local Settings\\Application Data"); | 135 L"Local Settings\\Application Data"); |
| 74 } else { | 136 } else { |
| 75 default_location = default_location.Append(L"AppData\\Local"); | 137 default_location = default_location.Append(L"AppData\\Local"); |
| 76 } | 138 } |
| 77 locations.push_back(default_location.Append(app_from_google)); | 139 locations.push_back(default_location.Append(app_from_google)); |
| 140 chromium_locations.push_back(default_location.Append(app_from_chromium)); |
| 78 } | 141 } |
| 79 | 142 |
| 80 // Add the system-level location for Chrome. | 143 // Add the system-level location for Chrome. |
| 81 std::string program_dir; | 144 std::string program_dir; |
| 82 if (env->GetVar("ProgramFiles", &program_dir)) { | 145 if (env->GetVar("ProgramFiles", &program_dir)) { |
| 83 locations.push_back(FilePath(UTF8ToWide(program_dir)) | 146 locations.push_back(FilePath(UTF8ToWide(program_dir)) |
| 84 .Append(app_from_google)); | 147 .Append(app_from_google)); |
| 148 chromium_locations.push_back(FilePath(UTF8ToWide(program_dir)) |
| 149 .Append(app_from_chromium)); |
| 85 } | 150 } |
| 86 if (env->GetVar("ProgramFiles(x86)", &program_dir)) { | 151 if (env->GetVar("ProgramFiles(x86)", &program_dir)) { |
| 87 locations.push_back(FilePath(UTF8ToWide(program_dir)) | 152 locations.push_back(FilePath(UTF8ToWide(program_dir)) |
| 88 .Append(app_from_google)); | 153 .Append(app_from_google)); |
| 154 chromium_locations.push_back(FilePath(UTF8ToWide(program_dir)) |
| 155 .Append(app_from_chromium)); |
| 89 } | 156 } |
| 90 #elif defined(OS_MACOSX) | 157 #elif defined(OS_MACOSX) |
| 158 locations.push_back(file_util::GetHomeDir().AppendASCII("Applications")); |
| 91 locations.push_back(FilePath("/Applications")); | 159 locations.push_back(FilePath("/Applications")); |
| 92 #elif defined(OS_LINUX) | 160 #elif defined(OS_LINUX) |
| 93 // Proxy launcher doesn't check for google-chrome, only chrome. | 161 locations.push_back(FilePath("/opt/google/chrome")); |
| 94 FilePath chrome_sym_link("/usr/bin/google-chrome"); | 162 locations.push_back(FilePath("/usr/local/bin")); |
| 95 if (file_util::PathExists(chrome_sym_link)) { | 163 locations.push_back(FilePath("/usr/local/sbin")); |
| 96 FilePath chrome; | 164 locations.push_back(FilePath("/usr/bin")); |
| 97 if (file_util::ReadSymbolicLink(chrome_sym_link, &chrome)) { | 165 locations.push_back(FilePath("/usr/sbin")); |
| 98 locations.push_back(chrome.DirName()); | 166 locations.push_back(FilePath("/bin")); |
| 99 } | 167 locations.push_back(FilePath("/sbin")); |
| 100 } | |
| 101 #endif | 168 #endif |
| 102 | 169 |
| 103 // Add the current directory. | 170 // Add the current directory. |
| 104 FilePath current_dir; | 171 FilePath current_dir; |
| 105 if (file_util::GetCurrentDirectory(¤t_dir)) | 172 if (file_util::GetCurrentDirectory(¤t_dir)) |
| 106 locations.push_back(current_dir); | 173 locations.push_back(current_dir); |
| 107 | 174 |
| 108 // Determine the default directory. | 175 // Step 3: For each browser exe path, check each location to see if the |
| 109 for (size_t i = 0; i < locations.size(); ++i) { | 176 // browser is installed there. Check the chromium locations lastly. |
| 110 FilePath path = locations[i].Append(chrome::kBrowserProcessExecutablePath); | 177 return CheckForChromeExe(browser_exes, locations, browser_exe) || |
| 111 if (file_util::PathExists(path)) { | 178 CheckForChromeExe(browser_exes, chromium_locations, browser_exe); |
| 112 *browser_exe = path; | |
| 113 return true; | |
| 114 } | |
| 115 } | |
| 116 return false; | |
| 117 } | 179 } |
| 118 | 180 |
| 119 } // namespace | 181 } // namespace |
| 120 | 182 |
| 121 namespace webdriver { | 183 namespace webdriver { |
| 122 | 184 |
| 123 Automation::Automation() {} | 185 Automation::Automation() {} |
| 124 | 186 |
| 125 Automation::~Automation() {} | 187 Automation::~Automation() {} |
| 126 | 188 |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 url, 1, &navigate_response, | 485 url, 1, &navigate_response, |
| 424 &error_msg)) { | 486 &error_msg)) { |
| 425 *error = new Error(kUnknownError, error_msg); | 487 *error = new Error(kUnknownError, error_msg); |
| 426 return; | 488 return; |
| 427 } | 489 } |
| 428 // TODO(kkania): Do not rely on this enum. | 490 // TODO(kkania): Do not rely on this enum. |
| 429 if (navigate_response == AUTOMATION_MSG_NAVIGATION_ERROR) | 491 if (navigate_response == AUTOMATION_MSG_NAVIGATION_ERROR) |
| 430 *error = new Error(kUnknownError, "Navigation error occurred"); | 492 *error = new Error(kUnknownError, "Navigation error occurred"); |
| 431 } | 493 } |
| 432 | 494 |
| 495 void Automation::NavigateToURLAsync(int tab_id, |
| 496 const std::string& url, |
| 497 Error** error) { |
| 498 int windex = 0, tab_index = 0; |
| 499 *error = GetIndicesForTab(tab_id, &windex, &tab_index); |
| 500 if (*error) |
| 501 return; |
| 502 |
| 503 scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(windex); |
| 504 if (!browser) { |
| 505 *error = new Error(kUnknownError, "Couldn't obtain browser proxy"); |
| 506 return; |
| 507 } |
| 508 scoped_refptr<TabProxy> tab = browser->GetTab(tab_index); |
| 509 if (!tab) { |
| 510 *error = new Error(kUnknownError, "Couldn't obtain tab proxy"); |
| 511 return; |
| 512 } |
| 513 if (!tab->NavigateToURLAsync(GURL(url))) { |
| 514 *error = new Error(kUnknownError, "Unable to navigate to url"); |
| 515 return; |
| 516 } |
| 517 } |
| 518 |
| 433 void Automation::GoForward(int tab_id, Error** error) { | 519 void Automation::GoForward(int tab_id, Error** error) { |
| 434 int windex = 0, tab_index = 0; | 520 int windex = 0, tab_index = 0; |
| 435 *error = GetIndicesForTab(tab_id, &windex, &tab_index); | 521 *error = GetIndicesForTab(tab_id, &windex, &tab_index); |
| 436 if (*error) | 522 if (*error) |
| 437 return; | 523 return; |
| 438 | 524 |
| 439 std::string error_msg; | 525 std::string error_msg; |
| 440 if (!SendGoForwardJSONRequest( | 526 if (!SendGoForwardJSONRequest( |
| 441 automation(), windex, tab_index, &error_msg)) { | 527 automation(), windex, tab_index, &error_msg)) { |
| 442 *error = new Error(kUnknownError, error_msg); | 528 *error = new Error(kUnknownError, error_msg); |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 768, 0, "Alerts are not supported for this version of Chrome"); | 718 768, 0, "Alerts are not supported for this version of Chrome"); |
| 633 } | 719 } |
| 634 | 720 |
| 635 Error* Automation::CheckAdvancedInteractionsSupported() { | 721 Error* Automation::CheckAdvancedInteractionsSupported() { |
| 636 const char* message = | 722 const char* message = |
| 637 "Advanced user interactions are not supported for this version of Chrome"; | 723 "Advanced user interactions are not supported for this version of Chrome"; |
| 638 return CheckVersion(750, 0, message); | 724 return CheckVersion(750, 0, message); |
| 639 } | 725 } |
| 640 | 726 |
| 641 } // namespace webdriver | 727 } // namespace webdriver |
| OLD | NEW |