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/ui/ui_test.h" | 5 #include "chrome/test/ui/ui_test.h" |
6 | 6 |
7 #if defined(OS_POSIX) | 7 #if defined(OS_POSIX) |
8 #include <signal.h> | 8 #include <signal.h> |
9 #include <sys/types.h> | 9 #include <sys/types.h> |
10 #endif | 10 #endif |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
54 | 54 |
55 #if defined(OS_WIN) | 55 #if defined(OS_WIN) |
56 #include "base/win/windows_version.h" | 56 #include "base/win/windows_version.h" |
57 #endif | 57 #endif |
58 | 58 |
59 | 59 |
60 using base::Time; | 60 using base::Time; |
61 using base::TimeDelta; | 61 using base::TimeDelta; |
62 using base::TimeTicks; | 62 using base::TimeTicks; |
63 | 63 |
64 // Passed as value of kTestType. | |
65 static const char kUITestType[] = "ui"; | |
66 | |
67 const wchar_t UITestBase::kFailedNoCrashService[] = | 64 const wchar_t UITestBase::kFailedNoCrashService[] = |
68 #if defined(OS_WIN) | 65 #if defined(OS_WIN) |
69 L"NOTE: This test is expected to fail if crash_service.exe is not " | 66 L"NOTE: This test is expected to fail if crash_service.exe is not " |
70 L"running. Start it manually before running this test (see the build " | 67 L"running. Start it manually before running this test (see the build " |
71 L"output directory)."; | 68 L"output directory)."; |
72 #elif defined(OS_LINUX) | 69 #elif defined(OS_LINUX) |
73 L"NOTE: This test is expected to fail if breakpad is not built in " | 70 L"NOTE: This test is expected to fail if breakpad is not built in " |
74 L"or if chromium is not running headless (try CHROME_HEADLESS=1)."; | 71 L"or if chromium is not running headless (try CHROME_HEADLESS=1)."; |
75 #else | 72 #else |
76 L"NOTE: Crash service not ported to this platform!"; | 73 L"NOTE: Crash service not ported to this platform!"; |
77 #endif | 74 #endif |
78 bool UITestBase::in_process_renderer_ = false; | |
79 bool UITestBase::no_sandbox_ = false; | |
80 bool UITestBase::full_memory_dump_ = false; | |
81 bool UITestBase::safe_plugins_ = false; | |
82 bool UITestBase::show_error_dialogs_ = true; | |
83 bool UITestBase::dump_histograms_on_exit_ = false; | |
84 bool UITestBase::enable_dcheck_ = false; | |
85 bool UITestBase::silent_dump_on_dcheck_ = false; | |
86 bool UITestBase::disable_breakpad_ = false; | |
87 std::string UITestBase::js_flags_ = ""; | |
88 std::string UITestBase::log_level_ = ""; | |
89 | 75 |
90 // Uncomment this line to have the spawned process wait for the debugger to | 76 // Uncomment this line to have the spawned process wait for the debugger to |
91 // attach. This only works on Windows. On posix systems, you can set the | 77 // attach. This only works on Windows. On posix systems, you can set the |
92 // BROWSER_WRAPPER env variable to wrap the browser process. | 78 // BROWSER_WRAPPER env variable to wrap the browser process. |
93 // #define WAIT_FOR_DEBUGGER_ON_OPEN 1 | 79 // #define WAIT_FOR_DEBUGGER_ON_OPEN 1 |
94 | 80 |
95 UITestBase::UITestBase() | 81 UITestBase::UITestBase() |
96 : launch_arguments_(CommandLine::NO_PROGRAM), | 82 : launch_arguments_(CommandLine::NO_PROGRAM), |
97 expected_errors_(0), | 83 expected_errors_(0), |
98 expected_crashes_(0), | 84 expected_crashes_(0), |
99 homepage_(chrome::kAboutBlankURL), | |
100 wait_for_initial_loads_(true), | 85 wait_for_initial_loads_(true), |
101 dom_automation_enabled_(false), | 86 dom_automation_enabled_(false), |
102 process_(base::kNullProcessHandle), | 87 process_(base::kNullProcessHandle), |
103 process_id_(-1), | 88 process_id_(-1), |
104 show_window_(false), | 89 show_window_(false), |
105 clear_profile_(true), | 90 clear_profile_(true), |
106 include_testing_id_(true), | 91 include_testing_id_(true), |
107 enable_file_cookies_(true), | 92 enable_file_cookies_(true), |
108 profile_type_(UITestBase::DEFAULT_THEME), | 93 profile_type_(ProxyLauncher::DEFAULT_THEME), |
109 shutdown_type_(UITestBase::WINDOW_CLOSE), | 94 shutdown_type_(ProxyLauncher::WINDOW_CLOSE) { |
110 temp_profile_dir_(new ScopedTempDir()) { | |
111 PathService::Get(chrome::DIR_APP, &browser_directory_); | 95 PathService::Get(chrome::DIR_APP, &browser_directory_); |
112 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); | 96 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); |
97 launcher_.reset(CreateProxyLauncher()); | |
Paweł Hajdan Jr.
2011/01/05 21:47:59
I wonder if we should do it in SetUp... that might
dtu
2011/01/06 01:41:13
It was originally in SetUp(). I moved it out of Se
Paweł Hajdan Jr.
2011/01/06 20:37:14
I see. How about removing knowledge about homepage
dtu
2011/01/08 01:54:51
Done.
| |
113 } | 98 } |
114 | 99 |
115 UITestBase::UITestBase(MessageLoop::Type msg_loop_type) | 100 UITestBase::UITestBase(MessageLoop::Type msg_loop_type) |
116 : launch_arguments_(CommandLine::NO_PROGRAM), | 101 : launch_arguments_(CommandLine::NO_PROGRAM), |
117 expected_errors_(0), | 102 expected_errors_(0), |
118 expected_crashes_(0), | 103 expected_crashes_(0), |
119 homepage_(chrome::kAboutBlankURL), | |
120 wait_for_initial_loads_(true), | 104 wait_for_initial_loads_(true), |
121 dom_automation_enabled_(false), | 105 dom_automation_enabled_(false), |
122 process_(base::kNullProcessHandle), | 106 process_(base::kNullProcessHandle), |
123 process_id_(-1), | 107 process_id_(-1), |
124 show_window_(false), | 108 show_window_(false), |
125 clear_profile_(true), | 109 clear_profile_(true), |
126 include_testing_id_(true), | 110 include_testing_id_(true), |
127 enable_file_cookies_(true), | 111 enable_file_cookies_(true), |
128 profile_type_(UITestBase::DEFAULT_THEME), | 112 profile_type_(ProxyLauncher::DEFAULT_THEME), |
129 shutdown_type_(UITestBase::WINDOW_CLOSE) { | 113 shutdown_type_(ProxyLauncher::WINDOW_CLOSE) { |
130 PathService::Get(chrome::DIR_APP, &browser_directory_); | 114 PathService::Get(chrome::DIR_APP, &browser_directory_); |
131 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); | 115 PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory_); |
116 launcher_.reset(CreateProxyLauncher()); | |
132 } | 117 } |
133 | 118 |
134 UITestBase::~UITestBase() { | 119 UITestBase::~UITestBase() { |
135 } | 120 } |
136 | 121 |
137 void UITestBase::SetUp() { | 122 void UITestBase::SetUp() { |
138 AssertAppNotRunning(L"Please close any other instances " | |
139 L"of the app before testing."); | |
140 | |
141 JavaScriptExecutionController::set_timeout( | 123 JavaScriptExecutionController::set_timeout( |
142 TestTimeouts::action_max_timeout_ms()); | 124 TestTimeouts::action_max_timeout_ms()); |
143 test_start_time_ = Time::NowFromSystemTime(); | 125 test_start_time_ = Time::NowFromSystemTime(); |
144 | 126 |
145 launcher_.reset(CreateProxyLauncher()); | 127 launcher_->SetUp(process_id_); |
146 launcher_->InitializeConnection(this); | 128 |
129 SetLaunchSwitches(); | |
130 | |
131 launcher_->InitializeConnection(launch_arguments_, include_testing_id_, | |
Paweł Hajdan Jr.
2011/01/05 21:47:59
Another idea is to push data to launcher_ in place
| |
132 clear_profile_, template_user_data_, | |
133 profile_type_, browser_directory_, | |
134 show_window_, wait_for_initial_loads_, | |
135 &browser_launch_time_, &process_, | |
136 &process_id_); | |
147 } | 137 } |
148 | 138 |
149 void UITestBase::TearDown() { | 139 void UITestBase::TearDown() { |
150 CloseBrowserAndServer(); | 140 CloseBrowserAndServer(); |
151 | 141 |
152 // Make sure that we didn't encounter any assertion failures | 142 // Make sure that we didn't encounter any assertion failures |
153 logging::AssertionList assertions; | 143 logging::AssertionList assertions; |
154 logging::GetFatalAssertions(&assertions); | 144 logging::GetFatalAssertions(&assertions); |
155 | 145 |
156 // If there were errors, get all the error strings for display. | 146 // If there were errors, get all the error strings for display. |
(...skipping 14 matching lines...) Expand all Loading... | |
171 L"Encountered an unexpected crash in the program during this test."; | 161 L"Encountered an unexpected crash in the program during this test."; |
172 if (expected_crashes_ > 0 && actual_crashes == 0) { | 162 if (expected_crashes_ > 0 && actual_crashes == 0) { |
173 error_msg += L" "; | 163 error_msg += L" "; |
174 error_msg += kFailedNoCrashService; | 164 error_msg += kFailedNoCrashService; |
175 } | 165 } |
176 EXPECT_EQ(expected_crashes_, actual_crashes) << error_msg; | 166 EXPECT_EQ(expected_crashes_, actual_crashes) << error_msg; |
177 } | 167 } |
178 | 168 |
179 // TODO(phajdan.jr): get rid of set_command_execution_timeout_ms. | 169 // TODO(phajdan.jr): get rid of set_command_execution_timeout_ms. |
180 void UITestBase::set_command_execution_timeout_ms(int timeout) { | 170 void UITestBase::set_command_execution_timeout_ms(int timeout) { |
181 automation_proxy_->set_command_execution_timeout_ms(timeout); | 171 automation()->set_command_execution_timeout_ms(timeout); |
182 VLOG(1) << "Automation command execution timeout set to " << timeout << " ms"; | 172 VLOG(1) << "Automation command execution timeout set to " << timeout << " ms"; |
183 } | 173 } |
184 | 174 |
185 ProxyLauncher* UITestBase::CreateProxyLauncher() { | 175 ProxyLauncher* UITestBase::CreateProxyLauncher() { |
186 return new AnonymousProxyLauncher(false); | 176 return new AnonymousProxyLauncher(false); |
187 } | 177 } |
188 | 178 |
179 void UITestBase::SetLaunchSwitches() { | |
180 // We need cookies on file:// for things like the page cycler. | |
181 if (enable_file_cookies_) | |
182 SetLaunchSwitch(switches::kEnableFileCookies); | |
183 if (dom_automation_enabled_) | |
184 SetLaunchSwitch(switches::kDomAutomationController); | |
185 } | |
186 | |
187 void UITestBase::SetLaunchSwitch(const std::string& switch_string) { | |
188 if (!launch_arguments_.HasSwitch(switch_string)) | |
Paweł Hajdan Jr.
2011/01/05 21:47:59
Do we need this check? It seems it would be simple
dtu
2011/01/06 01:41:13
Yes, I believe this check is optional. Done.
| |
189 launch_arguments_.AppendSwitch(switch_string); | |
190 } | |
191 | |
189 void UITestBase::LaunchBrowser() { | 192 void UITestBase::LaunchBrowser() { |
190 LaunchBrowser(launch_arguments_, clear_profile_); | 193 LaunchBrowser(launch_arguments_, clear_profile_); |
191 } | 194 } |
192 | 195 |
193 void UITestBase::LaunchBrowserAndServer() { | 196 void UITestBase::LaunchBrowserAndServer() { |
194 // Set up IPC testing interface as a server. | 197 launcher_->LaunchBrowserAndServer(launch_arguments_, include_testing_id_, |
195 automation_proxy_.reset(launcher_->CreateAutomationProxy( | 198 clear_profile_, template_user_data_, |
196 TestTimeouts::command_execution_timeout_ms())); | 199 profile_type_, browser_directory_, |
197 | 200 show_window_, wait_for_initial_loads_, |
198 LaunchBrowser(launch_arguments_, clear_profile_); | 201 &browser_launch_time_, &process_, |
199 WaitForBrowserLaunch(); | 202 &process_id_); |
200 } | 203 } |
201 | 204 |
202 void UITestBase::ConnectToRunningBrowser() { | 205 void UITestBase::ConnectToRunningBrowser() { |
203 // Set up IPC testing interface as a client. | 206 launcher_->ConnectToRunningBrowser(wait_for_initial_loads_); |
204 automation_proxy_.reset(launcher_->CreateAutomationProxy( | |
205 TestTimeouts::command_execution_timeout_ms())); | |
206 WaitForBrowserLaunch(); | |
207 } | |
208 | |
209 void UITestBase::WaitForBrowserLaunch() { | |
210 ASSERT_EQ(AUTOMATION_SUCCESS, automation_proxy_->WaitForAppLaunch()) | |
211 << "Error while awaiting automation ping from browser process"; | |
212 if (wait_for_initial_loads_) | |
213 ASSERT_TRUE(automation_proxy_->WaitForInitialLoads()); | |
214 else | |
215 base::PlatformThread::Sleep(sleep_timeout_ms()); | |
216 | |
217 EXPECT_TRUE(automation()->SetFilteredInet(ShouldFilterInet())); | |
218 } | 207 } |
219 | 208 |
220 void UITestBase::CloseBrowserAndServer() { | 209 void UITestBase::CloseBrowserAndServer() { |
221 QuitBrowser(); | 210 launcher_->CloseBrowserAndServer(shutdown_type_, &browser_quit_time_, |
222 CleanupAppProcesses(); | 211 &process_, &process_id_); |
223 | |
224 // Suppress spammy failures that seem to be occurring when running | |
225 // the UI tests in single-process mode. | |
226 // TODO(jhughes): figure out why this is necessary at all, and fix it | |
227 if (!in_process_renderer_) | |
228 AssertAppNotRunning(StringPrintf( | |
229 L"Unable to quit all browser processes. Original PID %d", process_id_)); | |
230 | |
231 automation_proxy_.reset(); // Shut down IPC testing interface. | |
232 } | 212 } |
233 | 213 |
234 void UITestBase::LaunchBrowser(const CommandLine& arguments, | 214 void UITestBase::LaunchBrowser(const CommandLine& arguments, |
235 bool clear_profile) { | 215 bool clear_profile) { |
236 if (clear_profile || !temp_profile_dir_->IsValid()) { | 216 launcher_->LaunchBrowser(arguments, include_testing_id_, clear_profile, |
237 temp_profile_dir_.reset(new ScopedTempDir()); | 217 template_user_data_, profile_type_, |
238 ASSERT_TRUE(temp_profile_dir_->CreateUniqueTempDir()); | 218 browser_directory_, show_window_, |
239 | 219 &browser_launch_time_, &process_, &process_id_); |
240 ASSERT_TRUE( | |
241 test_launcher_utils::OverrideUserDataDir(temp_profile_dir_->path())); | |
242 } | |
243 | |
244 if (!template_user_data_.empty()) { | |
245 // Recursively copy the template directory to the user_data_dir. | |
246 ASSERT_TRUE(file_util::CopyRecursiveDirNoCache( | |
247 template_user_data_, | |
248 user_data_dir())); | |
249 // If we're using the complex theme data, we need to write the | |
250 // user_data_dir_ to our preferences file. | |
251 if (profile_type_ == UITestBase::COMPLEX_THEME) { | |
252 RewritePreferencesFile(user_data_dir()); | |
253 } | |
254 | |
255 // Update the history file to include recent dates. | |
256 UpdateHistoryDates(); | |
257 } | |
258 | |
259 ASSERT_TRUE(LaunchBrowserHelper(arguments, false, &process_)); | |
260 process_id_ = base::GetProcId(process_); | |
261 } | 220 } |
262 | 221 |
263 #if !defined(OS_MACOSX) | 222 #if !defined(OS_MACOSX) |
264 bool UITestBase::LaunchAnotherBrowserBlockUntilClosed( | 223 bool UITestBase::LaunchAnotherBrowserBlockUntilClosed( |
265 const CommandLine& cmdline) { | 224 const CommandLine& cmdline) { |
266 return LaunchBrowserHelper(cmdline, true, NULL); | 225 return launcher_->LaunchAnotherBrowserBlockUntilClosed( |
226 cmdline, include_testing_id_, browser_directory_, | |
227 show_window_, &browser_launch_time_); | |
267 } | 228 } |
268 #endif | 229 #endif |
269 | 230 |
270 void UITestBase::QuitBrowser() { | 231 void UITestBase::QuitBrowser() { |
271 if (SESSION_ENDING == shutdown_type_) { | 232 launcher_->QuitBrowser(shutdown_type_, &browser_quit_time_, |
272 TerminateBrowser(); | 233 &process_, &process_id_); |
273 return; | |
274 } | |
275 | |
276 // There's nothing to do here if the browser is not running. | |
277 // WARNING: There is a race condition here where the browser may shut down | |
278 // after this check but before some later automation call. Your test should | |
279 // use WaitForBrowserProcessToQuit() if it intentionally | |
280 // causes the browser to shut down. | |
281 if (IsBrowserRunning()) { | |
282 TimeTicks quit_start = TimeTicks::Now(); | |
283 EXPECT_TRUE(automation()->SetFilteredInet(false)); | |
284 | |
285 if (WINDOW_CLOSE == shutdown_type_) { | |
286 int window_count = 0; | |
287 EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
288 | |
289 // Synchronously close all but the last browser window. Closing them | |
290 // one-by-one may help with stability. | |
291 while (window_count > 1) { | |
292 scoped_refptr<BrowserProxy> browser_proxy = | |
293 automation()->GetBrowserWindow(0); | |
294 EXPECT_TRUE(browser_proxy.get()); | |
295 if (browser_proxy.get()) { | |
296 EXPECT_TRUE(browser_proxy->RunCommand(IDC_CLOSE_WINDOW)); | |
297 EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
298 } else { | |
299 break; | |
300 } | |
301 } | |
302 | |
303 // Close the last window asynchronously, because the browser may | |
304 // shutdown faster than it will be able to send a synchronous response | |
305 // to our message. | |
306 scoped_refptr<BrowserProxy> browser_proxy = | |
307 automation()->GetBrowserWindow(0); | |
308 EXPECT_TRUE(browser_proxy.get()); | |
309 if (browser_proxy.get()) { | |
310 EXPECT_TRUE(browser_proxy->ApplyAccelerator(IDC_CLOSE_WINDOW)); | |
311 browser_proxy = NULL; | |
312 } | |
313 } else if (USER_QUIT == shutdown_type_) { | |
314 scoped_refptr<BrowserProxy> browser_proxy = | |
315 automation()->GetBrowserWindow(0); | |
316 EXPECT_TRUE(browser_proxy.get()); | |
317 if (browser_proxy.get()) { | |
318 EXPECT_TRUE(browser_proxy->RunCommandAsync(IDC_EXIT)); | |
319 } | |
320 } else { | |
321 NOTREACHED() << "Invalid shutdown type " << shutdown_type_; | |
322 } | |
323 | |
324 // Now, drop the automation IPC channel so that the automation provider in | |
325 // the browser notices and drops its reference to the browser process. | |
326 automation()->Disconnect(); | |
327 | |
328 // Wait for the browser process to quit. It should quit once all tabs have | |
329 // been closed. | |
330 if (!WaitForBrowserProcessToQuit()) { | |
331 // We need to force the browser to quit because it didn't quit fast | |
332 // enough. Take no chance and kill every chrome processes. | |
333 CleanupAppProcesses(); | |
334 } | |
335 browser_quit_time_ = TimeTicks::Now() - quit_start; | |
336 } | |
337 | |
338 // Don't forget to close the handle | |
339 base::CloseProcessHandle(process_); | |
340 process_ = base::kNullProcessHandle; | |
341 process_id_ = -1; | |
342 } | 234 } |
343 | 235 |
344 void UITestBase::TerminateBrowser() { | 236 void UITestBase::TerminateBrowser() { |
345 if (IsBrowserRunning()) { | 237 launcher_->TerminateBrowser(&browser_quit_time_, &process_, &process_id_); |
346 TimeTicks quit_start = TimeTicks::Now(); | |
347 EXPECT_TRUE(automation()->SetFilteredInet(false)); | |
348 #if defined(OS_WIN) | |
349 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | |
350 ASSERT_TRUE(browser.get()); | |
351 ASSERT_TRUE(browser->TerminateSession()); | |
352 #endif // defined(OS_WIN) | |
353 | |
354 // Now, drop the automation IPC channel so that the automation provider in | |
355 // the browser notices and drops its reference to the browser process. | |
356 automation()->Disconnect(); | |
357 | |
358 #if defined(OS_POSIX) | |
359 EXPECT_EQ(kill(process_, SIGTERM), 0); | |
360 #endif // OS_POSIX | |
361 | |
362 if (!WaitForBrowserProcessToQuit()) { | |
363 // We need to force the browser to quit because it didn't quit fast | |
364 // enough. Take no chance and kill every chrome processes. | |
365 CleanupAppProcesses(); | |
366 } | |
367 browser_quit_time_ = TimeTicks::Now() - quit_start; | |
368 } | |
369 | |
370 // Don't forget to close the handle | |
371 base::CloseProcessHandle(process_); | |
372 process_ = base::kNullProcessHandle; | |
373 process_id_ = -1; | |
374 } | |
375 | |
376 void UITestBase::AssertAppNotRunning(const std::wstring& error_message) { | |
377 std::wstring final_error_message(error_message); | |
378 | |
379 ChromeProcessList processes = GetRunningChromeProcesses(process_id_); | |
380 if (!processes.empty()) { | |
381 final_error_message += L" Leftover PIDs: ["; | |
382 for (ChromeProcessList::const_iterator it = processes.begin(); | |
383 it != processes.end(); ++it) { | |
384 final_error_message += StringPrintf(L" %d", *it); | |
385 } | |
386 final_error_message += L" ]"; | |
387 } | |
388 ASSERT_TRUE(processes.empty()) << final_error_message; | |
389 } | 238 } |
390 | 239 |
391 void UITestBase::CleanupAppProcesses() { | 240 void UITestBase::CleanupAppProcesses() { |
392 TerminateAllChromeProcesses(process_id_); | 241 TerminateAllChromeProcesses(process_id_); |
393 } | 242 } |
394 | 243 |
395 scoped_refptr<TabProxy> UITestBase::GetActiveTab(int window_index) { | 244 scoped_refptr<TabProxy> UITestBase::GetActiveTab(int window_index) { |
396 EXPECT_GE(window_index, 0); | 245 EXPECT_GE(window_index, 0); |
397 int window_count = -1; | 246 int window_count = -1; |
398 // We have to use EXPECT rather than ASSERT here because ASSERT_* only works | 247 // We have to use EXPECT rather than ASSERT here because ASSERT_* only works |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 automation()->GetBrowserWindow(window_index); | 307 automation()->GetBrowserWindow(window_index); |
459 ASSERT_TRUE(window.get()); | 308 ASSERT_TRUE(window.get()); |
460 scoped_refptr<TabProxy> tab_proxy(window->GetTab(tab_index)); | 309 scoped_refptr<TabProxy> tab_proxy(window->GetTab(tab_index)); |
461 ASSERT_TRUE(tab_proxy.get()); | 310 ASSERT_TRUE(tab_proxy.get()); |
462 EXPECT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, | 311 EXPECT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, |
463 tab_proxy->NavigateToURLBlockUntilNavigationsComplete( | 312 tab_proxy->NavigateToURLBlockUntilNavigationsComplete( |
464 url, number_of_navigations)) << url.spec(); | 313 url, number_of_navigations)) << url.spec(); |
465 } | 314 } |
466 | 315 |
467 bool UITestBase::WaitForBrowserProcessToQuit() { | 316 bool UITestBase::WaitForBrowserProcessToQuit() { |
468 // Wait for the browser process to quit. | 317 return launcher_->WaitForBrowserProcessToQuit(process_); |
469 int timeout = TestTimeouts::wait_for_terminate_timeout_ms(); | |
470 #ifdef WAIT_FOR_DEBUGGER_ON_OPEN | |
471 timeout = 500000; | |
472 #endif | |
473 return base::WaitForSingleProcess(process_, timeout); | |
474 } | 318 } |
475 | 319 |
476 bool UITestBase::WaitForBookmarkBarVisibilityChange(BrowserProxy* browser, | 320 bool UITestBase::WaitForBookmarkBarVisibilityChange(BrowserProxy* browser, |
477 bool wait_for_open) { | 321 bool wait_for_open) { |
478 const int kCycles = 10; | 322 const int kCycles = 10; |
479 for (int i = 0; i < kCycles; i++) { | 323 for (int i = 0; i < kCycles; i++) { |
480 bool visible = false; | 324 bool visible = false; |
481 bool animating = true; | 325 bool animating = true; |
482 if (!browser->GetBookmarkBarVisibility(&visible, &animating)) | 326 if (!browser->GetBookmarkBarVisibility(&visible, &animating)) |
483 return false; // Some error. | 327 return false; // Some error. |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
526 EXPECT_TRUE(window_proxy.get()); | 370 EXPECT_TRUE(window_proxy.get()); |
527 if (!window_proxy.get()) | 371 if (!window_proxy.get()) |
528 return -1; | 372 return -1; |
529 | 373 |
530 int active_tab_index = -1; | 374 int active_tab_index = -1; |
531 EXPECT_TRUE(window_proxy->GetActiveTabIndex(&active_tab_index)); | 375 EXPECT_TRUE(window_proxy->GetActiveTabIndex(&active_tab_index)); |
532 return active_tab_index; | 376 return active_tab_index; |
533 } | 377 } |
534 | 378 |
535 bool UITestBase::IsBrowserRunning() { | 379 bool UITestBase::IsBrowserRunning() { |
536 return CrashAwareSleep(0); | 380 return launcher_->IsBrowserRunning(process_); |
537 } | 381 } |
538 | 382 |
539 bool UITestBase::CrashAwareSleep(int time_out_ms) { | 383 bool UITestBase::CrashAwareSleep(int time_out_ms) { |
540 return base::CrashAwareSleep(process_, time_out_ms); | 384 return launcher_->CrashAwareSleep(process_, time_out_ms); |
541 } | 385 } |
542 | 386 |
543 int UITestBase::GetTabCount() { | 387 int UITestBase::GetTabCount() { |
544 return GetTabCount(0); | 388 return GetTabCount(0); |
545 } | 389 } |
546 | 390 |
547 int UITestBase::GetTabCount(int window_index) { | 391 int UITestBase::GetTabCount(int window_index) { |
548 scoped_refptr<BrowserProxy> window( | 392 scoped_refptr<BrowserProxy> window( |
549 automation()->GetBrowserWindow(window_index)); | 393 automation()->GetBrowserWindow(window_index)); |
550 EXPECT_TRUE(window.get()); | 394 EXPECT_TRUE(window.get()); |
(...skipping 27 matching lines...) Expand all Loading... | |
578 EXPECT_TRUE(tab_proxy.get()); | 422 EXPECT_TRUE(tab_proxy.get()); |
579 if (!tab_proxy.get()) | 423 if (!tab_proxy.get()) |
580 return FilePath(); | 424 return FilePath(); |
581 | 425 |
582 FilePath download_directory; | 426 FilePath download_directory; |
583 EXPECT_TRUE(tab_proxy->GetDownloadDirectory(&download_directory)); | 427 EXPECT_TRUE(tab_proxy->GetDownloadDirectory(&download_directory)); |
584 return download_directory; | 428 return download_directory; |
585 } | 429 } |
586 | 430 |
587 void UITestBase::CloseBrowserAsync(BrowserProxy* browser) const { | 431 void UITestBase::CloseBrowserAsync(BrowserProxy* browser) const { |
588 ASSERT_TRUE(automation_proxy_->Send( | 432 ASSERT_TRUE(automation()->Send( |
589 new AutomationMsg_CloseBrowserRequestAsync(browser->handle()))); | 433 new AutomationMsg_CloseBrowserRequestAsync(browser->handle()))); |
590 } | 434 } |
591 | 435 |
592 bool UITestBase::CloseBrowser(BrowserProxy* browser, | 436 bool UITestBase::CloseBrowser(BrowserProxy* browser, |
593 bool* application_closed) const { | 437 bool* application_closed) const { |
594 DCHECK(application_closed); | 438 DCHECK(application_closed); |
595 if (!browser->is_valid() || !browser->handle()) | 439 if (!browser->is_valid() || !browser->handle()) |
596 return false; | 440 return false; |
597 | 441 |
598 bool result = true; | 442 bool result = true; |
599 | 443 |
600 bool succeeded = automation_proxy_->Send(new AutomationMsg_CloseBrowser( | 444 bool succeeded = automation()->Send(new AutomationMsg_CloseBrowser( |
601 browser->handle(), &result, application_closed)); | 445 browser->handle(), &result, application_closed)); |
602 | 446 |
603 if (!succeeded) | 447 if (!succeeded) |
604 return false; | 448 return false; |
605 | 449 |
606 if (*application_closed) { | 450 if (*application_closed) { |
607 // Let's wait until the process dies (if it is not gone already). | 451 // Let's wait until the process dies (if it is not gone already). |
608 bool success = base::WaitForSingleProcess(process_, base::kNoTimeout); | 452 bool success = base::WaitForSingleProcess(process_, base::kNoTimeout); |
609 EXPECT_TRUE(success); | 453 EXPECT_TRUE(success); |
610 } | 454 } |
611 | 455 |
612 return result; | 456 return result; |
613 } | 457 } |
614 | 458 |
615 // static | 459 // static |
616 void UITestBase::RewritePreferencesFile(const FilePath& user_data_dir) { | 460 FilePath UITestBase::ComputeTypicalUserDataSource( |
617 const FilePath pref_template_path( | 461 ProxyLauncher::ProfileType profile_type) { |
618 user_data_dir.AppendASCII("Default").AppendASCII("PreferencesTemplate")); | |
619 const FilePath pref_path( | |
620 user_data_dir.AppendASCII("Default").AppendASCII("Preferences")); | |
621 | |
622 // Read in preferences template. | |
623 std::string pref_string; | |
624 EXPECT_TRUE(file_util::ReadFileToString(pref_template_path, &pref_string)); | |
625 string16 format_string = ASCIIToUTF16(pref_string); | |
626 | |
627 // Make sure temp directory has the proper format for writing to prefs file. | |
628 #if defined(OS_POSIX) | |
629 std::wstring user_data_dir_w(ASCIIToWide(user_data_dir.value())); | |
630 #elif defined(OS_WIN) | |
631 std::wstring user_data_dir_w(user_data_dir.value()); | |
632 // In Windows, the FilePath will write '\' for the path separators; change | |
633 // these to a separator that won't trigger escapes. | |
634 std::replace(user_data_dir_w.begin(), | |
635 user_data_dir_w.end(), '\\', '/'); | |
636 #endif | |
637 | |
638 // Rewrite prefs file. | |
639 std::vector<string16> subst; | |
640 subst.push_back(WideToUTF16(user_data_dir_w)); | |
641 const std::string prefs_string = | |
642 UTF16ToASCII(ReplaceStringPlaceholders(format_string, subst, NULL)); | |
643 EXPECT_TRUE(file_util::WriteFile(pref_path, prefs_string.c_str(), | |
644 prefs_string.size())); | |
645 file_util::EvictFileFromSystemCache(pref_path); | |
646 } | |
647 | |
648 FilePath UITestBase::user_data_dir() const { | |
649 EXPECT_TRUE(temp_profile_dir_->IsValid()); | |
650 return temp_profile_dir_->path(); | |
651 } | |
652 | |
653 // static | |
654 FilePath UITestBase::ComputeTypicalUserDataSource(ProfileType profile_type) { | |
655 FilePath source_history_file; | 462 FilePath source_history_file; |
656 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, | 463 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, |
657 &source_history_file)); | 464 &source_history_file)); |
658 source_history_file = source_history_file.AppendASCII("profiles"); | 465 source_history_file = source_history_file.AppendASCII("profiles"); |
659 switch (profile_type) { | 466 switch (profile_type) { |
660 case UITestBase::DEFAULT_THEME: | 467 case ProxyLauncher::DEFAULT_THEME: |
661 source_history_file = source_history_file.AppendASCII("typical_history"); | 468 source_history_file = source_history_file.AppendASCII("typical_history"); |
662 break; | 469 break; |
663 case UITestBase::COMPLEX_THEME: | 470 case ProxyLauncher::COMPLEX_THEME: |
664 source_history_file = source_history_file.AppendASCII("complex_theme"); | 471 source_history_file = source_history_file.AppendASCII("complex_theme"); |
665 break; | 472 break; |
666 case UITestBase::NATIVE_THEME: | 473 case ProxyLauncher::NATIVE_THEME: |
667 source_history_file = source_history_file.AppendASCII("gtk_theme"); | 474 source_history_file = source_history_file.AppendASCII("gtk_theme"); |
668 break; | 475 break; |
669 case UITestBase::CUSTOM_FRAME: | 476 case ProxyLauncher::CUSTOM_FRAME: |
670 source_history_file = source_history_file.AppendASCII("custom_frame"); | 477 source_history_file = source_history_file.AppendASCII("custom_frame"); |
671 break; | 478 break; |
672 case UITestBase::CUSTOM_FRAME_NATIVE_THEME: | 479 case ProxyLauncher::CUSTOM_FRAME_NATIVE_THEME: |
673 source_history_file = | 480 source_history_file = |
674 source_history_file.AppendASCII("custom_frame_gtk_theme"); | 481 source_history_file.AppendASCII("custom_frame_gtk_theme"); |
675 break; | 482 break; |
676 default: | 483 default: |
677 NOTREACHED(); | 484 NOTREACHED(); |
678 } | 485 } |
679 return source_history_file; | 486 return source_history_file; |
680 } | 487 } |
681 | 488 |
682 void UITestBase::PrepareTestCommandline(CommandLine* command_line) { | |
683 // Propagate commandline settings from test_launcher_utils. | |
684 test_launcher_utils::PrepareBrowserCommandLineForTests(command_line); | |
685 | |
686 // Add any explicit command line flags passed to the process. | |
687 CommandLine::StringType extra_chrome_flags = | |
688 CommandLine::ForCurrentProcess()->GetSwitchValueNative( | |
689 switches::kExtraChromeFlags); | |
690 if (!extra_chrome_flags.empty()) { | |
691 // Split by spaces and append to command line | |
692 std::vector<CommandLine::StringType> flags; | |
693 base::SplitString(extra_chrome_flags, ' ', &flags); | |
694 for (size_t i = 0; i < flags.size(); ++i) | |
695 command_line->AppendArgNative(flags[i]); | |
696 } | |
697 | |
698 // No default browser check, it would create an info-bar (if we are not the | |
699 // default browser) that could conflicts with some tests expectations. | |
700 command_line->AppendSwitch(switches::kNoDefaultBrowserCheck); | |
701 | |
702 // This is a UI test. | |
703 command_line->AppendSwitchASCII(switches::kTestType, kUITestType); | |
704 | |
705 // Tell the browser to use a temporary directory just for this test. | |
706 command_line->AppendSwitchPath(switches::kUserDataDir, user_data_dir()); | |
707 | |
708 // We need cookies on file:// for things like the page cycler. | |
709 if (enable_file_cookies_) | |
710 command_line->AppendSwitch(switches::kEnableFileCookies); | |
711 | |
712 if (dom_automation_enabled_) | |
713 command_line->AppendSwitch(switches::kDomAutomationController); | |
714 | |
715 if (include_testing_id_) | |
716 command_line->AppendSwitchASCII(switches::kTestingChannelID, | |
717 launcher_->PrefixedChannelID()); | |
718 | |
719 if (!show_error_dialogs_ && | |
720 !CommandLine::ForCurrentProcess()->HasSwitch( | |
721 switches::kEnableErrorDialogs)) { | |
722 command_line->AppendSwitch(switches::kNoErrorDialogs); | |
723 } | |
724 if (in_process_renderer_) | |
725 command_line->AppendSwitch(switches::kSingleProcess); | |
726 if (no_sandbox_) | |
727 command_line->AppendSwitch(switches::kNoSandbox); | |
728 if (full_memory_dump_) | |
729 command_line->AppendSwitch(switches::kFullMemoryCrashReport); | |
730 if (safe_plugins_) | |
731 command_line->AppendSwitch(switches::kSafePlugins); | |
732 if (enable_dcheck_) | |
733 command_line->AppendSwitch(switches::kEnableDCHECK); | |
734 if (silent_dump_on_dcheck_) | |
735 command_line->AppendSwitch(switches::kSilentDumpOnDCHECK); | |
736 if (disable_breakpad_) | |
737 command_line->AppendSwitch(switches::kDisableBreakpad); | |
738 if (!homepage_.empty()) | |
739 command_line->AppendSwitchASCII(switches::kHomePage, homepage_); | |
740 | |
741 if (!js_flags_.empty()) | |
742 command_line->AppendSwitchASCII(switches::kJavaScriptFlags, js_flags_); | |
743 if (!log_level_.empty()) | |
744 command_line->AppendSwitchASCII(switches::kLoggingLevel, log_level_); | |
745 | |
746 command_line->AppendSwitch(switches::kMetricsRecordingOnly); | |
747 | |
748 if (!CommandLine::ForCurrentProcess()->HasSwitch( | |
749 switches::kEnableErrorDialogs)) | |
750 command_line->AppendSwitch(switches::kEnableLogging); | |
751 | |
752 if (dump_histograms_on_exit_) | |
753 command_line->AppendSwitch(switches::kDumpHistogramsOnExit); | |
754 | |
755 #ifdef WAIT_FOR_DEBUGGER_ON_OPEN | |
756 command_line->AppendSwitch(switches::kDebugOnStart); | |
757 #endif | |
758 | |
759 if (!ui_test_name_.empty()) | |
760 command_line->AppendSwitchASCII(switches::kTestName, ui_test_name_); | |
761 | |
762 // The tests assume that file:// URIs can freely access other file:// URIs. | |
763 command_line->AppendSwitch(switches::kAllowFileAccessFromFiles); | |
764 | |
765 // Disable TabCloseableStateWatcher for tests. | |
766 command_line->AppendSwitch(switches::kDisableTabCloseableStateWatcher); | |
767 | |
768 // Allow file:// access on ChromeOS. | |
769 command_line->AppendSwitch(switches::kAllowFileAccess); | |
770 } | |
771 | |
772 bool UITestBase::LaunchBrowserHelper(const CommandLine& arguments, | |
773 bool wait, | |
774 base::ProcessHandle* process) { | |
775 FilePath command = browser_directory_.Append( | |
776 chrome::kBrowserProcessExecutablePath); | |
777 | |
778 CommandLine command_line(command); | |
779 | |
780 // Add command line arguments that should be applied to all UI tests. | |
781 PrepareTestCommandline(&command_line); | |
782 DebugFlags::ProcessDebugFlags( | |
783 &command_line, ChildProcessInfo::UNKNOWN_PROCESS, false); | |
784 command_line.AppendArguments(arguments, false); | |
785 | |
786 // TODO(phajdan.jr): Only run it for "main" browser launch. | |
787 browser_launch_time_ = TimeTicks::Now(); | |
788 | |
789 #if defined(OS_WIN) | |
790 bool started = base::LaunchApp(command_line, | |
791 wait, | |
792 !show_window_, | |
793 process); | |
794 #elif defined(OS_POSIX) | |
795 // Sometimes one needs to run the browser under a special environment | |
796 // (e.g. valgrind) without also running the test harness (e.g. python) | |
797 // under the special environment. Provide a way to wrap the browser | |
798 // commandline with a special prefix to invoke the special environment. | |
799 const char* browser_wrapper = getenv("BROWSER_WRAPPER"); | |
800 if (browser_wrapper) { | |
801 command_line.PrependWrapper(browser_wrapper); | |
802 VLOG(1) << "BROWSER_WRAPPER was set, prefixing command_line with " | |
803 << browser_wrapper; | |
804 } | |
805 | |
806 base::file_handle_mapping_vector fds; | |
807 if (automation_proxy_.get()) | |
808 fds = automation_proxy_->fds_to_map(); | |
809 | |
810 bool started = base::LaunchApp(command_line.argv(), fds, wait, process); | |
811 #endif | |
812 | |
813 return started; | |
814 } | |
815 | |
816 void UITestBase::UpdateHistoryDates() { | |
817 // Migrate the times in the segment_usage table to yesterday so we get | |
818 // actual thumbnails on the NTP. | |
819 sql::Connection db; | |
820 FilePath history = | |
821 user_data_dir().AppendASCII("Default").AppendASCII("History"); | |
822 // Not all test profiles have a history file. | |
823 if (!file_util::PathExists(history)) | |
824 return; | |
825 | |
826 ASSERT_TRUE(db.Open(history)); | |
827 Time yesterday = Time::Now() - TimeDelta::FromDays(1); | |
828 std::string yesterday_str = base::Int64ToString(yesterday.ToInternalValue()); | |
829 std::string query = StringPrintf( | |
830 "UPDATE segment_usage " | |
831 "SET time_slot = %s " | |
832 "WHERE id IN (SELECT id FROM segment_usage WHERE time_slot > 0);", | |
833 yesterday_str.c_str()); | |
834 ASSERT_TRUE(db.Execute(query.c_str())); | |
835 db.Close(); | |
836 file_util::EvictFileFromSystemCache(history); | |
837 } | |
838 | |
839 int UITestBase::GetCrashCount() { | 489 int UITestBase::GetCrashCount() { |
840 FilePath crash_dump_path; | 490 FilePath crash_dump_path; |
841 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); | 491 PathService::Get(chrome::DIR_CRASH_DUMPS, &crash_dump_path); |
842 int actual_crashes = file_util::CountFilesCreatedAfter( | 492 int actual_crashes = file_util::CountFilesCreatedAfter( |
843 crash_dump_path, test_start_time_); | 493 crash_dump_path, test_start_time_); |
844 | 494 |
845 #if defined(OS_WIN) | 495 #if defined(OS_WIN) |
846 // Each crash creates two dump files, so we divide by two here. | 496 // Each crash creates two dump files, so we divide by two here. |
847 actual_crashes /= 2; | 497 actual_crashes /= 2; |
848 #endif | 498 #endif |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1208 incorrect_state_count++; | 858 incorrect_state_count++; |
1209 } | 859 } |
1210 | 860 |
1211 LOG(INFO) << "Elapsed time: " << (base::Time::Now() - start).InSecondsF() | 861 LOG(INFO) << "Elapsed time: " << (base::Time::Now() - start).InSecondsF() |
1212 << " seconds" | 862 << " seconds" |
1213 << " call failed " << fail_count << " times" | 863 << " call failed " << fail_count << " times" |
1214 << " state was incorrect " << incorrect_state_count << " times"; | 864 << " state was incorrect " << incorrect_state_count << " times"; |
1215 ADD_FAILURE() << "Timeout reached in " << __FUNCTION__; | 865 ADD_FAILURE() << "Timeout reached in " << __FUNCTION__; |
1216 return false; | 866 return false; |
1217 } | 867 } |
OLD | NEW |