| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/base_paths.h" | |
| 6 #include "base/file_path.h" | |
| 7 #include "base/file_util.h" | |
| 8 #include "base/path_service.h" | |
| 9 #include "base/string_util.h" | |
| 10 #include "base/sys_info.h" | |
| 11 #include "base/test/test_file_util.h" | |
| 12 #include "base/values.h" | |
| 13 #include "chrome/app/chrome_command_ids.h" | |
| 14 #include "chrome/browser/platform_util.h" | |
| 15 #include "chrome/browser/ui/browser.h" | |
| 16 #include "chrome/common/chrome_switches.h" | |
| 17 #include "chrome/common/chrome_constants.h" | |
| 18 #include "chrome/common/pref_names.h" | |
| 19 #include "chrome/test/automation/browser_proxy.h" | |
| 20 #include "chrome/test/automation/tab_proxy.h" | |
| 21 #include "chrome/test/automation/window_proxy.h" | |
| 22 #include "chrome/test/ui/ui_test.h" | |
| 23 #include "gfx/native_widget_types.h" | |
| 24 #include "grit/chromium_strings.h" | |
| 25 #include "grit/generated_resources.h" | |
| 26 #include "net/base/net_util.h" | |
| 27 #include "net/test/test_server.h" | |
| 28 | |
| 29 namespace { | |
| 30 | |
| 31 class BrowserTest : public UITest { | |
| 32 }; | |
| 33 | |
| 34 class VisibleBrowserTest : public UITest { | |
| 35 protected: | |
| 36 VisibleBrowserTest() : UITest() { | |
| 37 show_window_ = true; | |
| 38 } | |
| 39 }; | |
| 40 | |
| 41 #if defined(OS_WIN) | |
| 42 // The browser should quit quickly if it receives a WM_ENDSESSION message. | |
| 43 TEST_F(BrowserTest, WindowsSessionEnd) { | |
| 44 #elif defined(OS_POSIX) | |
| 45 // The browser should quit gracefully and quickly if it receives a SIGTERM. | |
| 46 TEST_F(BrowserTest, PosixSessionEnd) { | |
| 47 #endif | |
| 48 FilePath test_file(test_data_directory_); | |
| 49 test_file = test_file.AppendASCII("title1.html"); | |
| 50 | |
| 51 NavigateToURL(net::FilePathToFileURL(test_file)); | |
| 52 TerminateBrowser(); | |
| 53 ASSERT_FALSE(IsBrowserRunning()); | |
| 54 | |
| 55 // Make sure the UMA metrics say we didn't crash. | |
| 56 scoped_ptr<DictionaryValue> local_prefs(GetLocalState()); | |
| 57 bool exited_cleanly; | |
| 58 ASSERT_TRUE(local_prefs.get()); | |
| 59 ASSERT_TRUE(local_prefs->GetBoolean(prefs::kStabilityExitedCleanly, | |
| 60 &exited_cleanly)); | |
| 61 ASSERT_TRUE(exited_cleanly); | |
| 62 | |
| 63 // And that session end was successful. | |
| 64 bool session_end_completed; | |
| 65 ASSERT_TRUE(local_prefs->GetBoolean(prefs::kStabilitySessionEndCompleted, | |
| 66 &session_end_completed)); | |
| 67 ASSERT_TRUE(session_end_completed); | |
| 68 | |
| 69 // Make sure session restore says we didn't crash. | |
| 70 scoped_ptr<DictionaryValue> profile_prefs(GetDefaultProfilePreferences()); | |
| 71 ASSERT_TRUE(profile_prefs.get()); | |
| 72 ASSERT_TRUE(profile_prefs->GetBoolean(prefs::kSessionExitedCleanly, | |
| 73 &exited_cleanly)); | |
| 74 ASSERT_TRUE(exited_cleanly); | |
| 75 } | |
| 76 | |
| 77 // Test that scripts can fork a new renderer process for a tab in a particular | |
| 78 // case (which matches following a link in Gmail). The script must open a new | |
| 79 // tab, set its window.opener to null, and redirect it to a cross-site URL. | |
| 80 // (Bug 1115708) | |
| 81 // This test can only run if V8 is in use, and not KJS, because KJS will not | |
| 82 // set window.opener to null properly. | |
| 83 #ifdef CHROME_V8 | |
| 84 TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { | |
| 85 // This test only works in multi-process mode | |
| 86 if (in_process_renderer()) | |
| 87 return; | |
| 88 | |
| 89 net::TestServer test_server(net::TestServer::TYPE_HTTP, | |
| 90 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 91 ASSERT_TRUE(test_server.Start()); | |
| 92 | |
| 93 FilePath test_file(test_data_directory_); | |
| 94 scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); | |
| 95 ASSERT_TRUE(window.get()); | |
| 96 scoped_refptr<TabProxy> tab(window->GetActiveTab()); | |
| 97 ASSERT_TRUE(tab.get()); | |
| 98 | |
| 99 // Start with a file:// url | |
| 100 test_file = test_file.AppendASCII("title2.html"); | |
| 101 tab->NavigateToURL(net::FilePathToFileURL(test_file)); | |
| 102 int orig_tab_count = -1; | |
| 103 ASSERT_TRUE(window->GetTabCount(&orig_tab_count)); | |
| 104 int orig_process_count = GetBrowserProcessCount(); | |
| 105 ASSERT_GE(orig_process_count, 1); | |
| 106 | |
| 107 // Use JavaScript URL to "fork" a new tab, just like Gmail. (Open tab to a | |
| 108 // blank page, set its opener to null, and redirect it cross-site.) | |
| 109 std::wstring url_prefix(L"javascript:(function(){w=window.open();"); | |
| 110 GURL fork_url(url_prefix + | |
| 111 L"w.opener=null;w.document.location=\"http://localhost:1337\";})()"); | |
| 112 | |
| 113 // Make sure that a new tab has been created and that we have a new renderer | |
| 114 // process for it. | |
| 115 ASSERT_TRUE(tab->NavigateToURLAsync(fork_url)); | |
| 116 PlatformThread::Sleep(sleep_timeout_ms()); | |
| 117 ASSERT_EQ(orig_process_count + 1, GetBrowserProcessCount()); | |
| 118 int new_tab_count = -1; | |
| 119 ASSERT_TRUE(window->GetTabCount(&new_tab_count)); | |
| 120 ASSERT_EQ(orig_tab_count + 1, new_tab_count); | |
| 121 } | |
| 122 #endif // CHROME_V8 | |
| 123 | |
| 124 // This test fails on ChromeOS (it has never been known to work on it). | |
| 125 // Currently flaky on Windows - it has crashed a couple of times. | |
| 126 // http://crbug.com/32799 | |
| 127 #if defined(OS_CHROMEOS) | |
| 128 #define MAYBE_OtherRedirectsDontForkProcess DISABLED_OtherRedirectsDontForkProce
ss | |
| 129 #else | |
| 130 #define MAYBE_OtherRedirectsDontForkProcess FLAKY_OtherRedirectsDontForkProcess | |
| 131 #endif | |
| 132 | |
| 133 // Tests that non-Gmail-like script redirects (i.e., non-null window.opener) or | |
| 134 // a same-page-redirect) will not fork a new process. | |
| 135 TEST_F(BrowserTest, MAYBE_OtherRedirectsDontForkProcess) { | |
| 136 // This test only works in multi-process mode | |
| 137 if (in_process_renderer()) | |
| 138 return; | |
| 139 | |
| 140 net::TestServer test_server(net::TestServer::TYPE_HTTP, | |
| 141 FilePath(FILE_PATH_LITERAL("chrome/test/data"))); | |
| 142 ASSERT_TRUE(test_server.Start()); | |
| 143 | |
| 144 FilePath test_file(test_data_directory_); | |
| 145 scoped_refptr<BrowserProxy> window(automation()->GetBrowserWindow(0)); | |
| 146 ASSERT_TRUE(window.get()); | |
| 147 scoped_refptr<TabProxy> tab(window->GetActiveTab()); | |
| 148 ASSERT_TRUE(tab.get()); | |
| 149 | |
| 150 // Start with a file:// url | |
| 151 test_file = test_file.AppendASCII("title2.html"); | |
| 152 ASSERT_EQ(AUTOMATION_MSG_NAVIGATION_SUCCESS, | |
| 153 tab->NavigateToURL(net::FilePathToFileURL(test_file))); | |
| 154 int orig_tab_count = -1; | |
| 155 ASSERT_TRUE(window->GetTabCount(&orig_tab_count)); | |
| 156 int orig_process_count = GetBrowserProcessCount(); | |
| 157 ASSERT_GE(orig_process_count, 1); | |
| 158 | |
| 159 // Use JavaScript URL to almost fork a new tab, but not quite. (Leave the | |
| 160 // opener non-null.) Should not fork a process. | |
| 161 std::string url_str = "javascript:(function(){w=window.open(); "; | |
| 162 url_str += "w.document.location=\""; | |
| 163 url_str += test_server.GetURL("").spec(); | |
| 164 url_str += "\";})()"; | |
| 165 GURL dont_fork_url(url_str); | |
| 166 | |
| 167 // Make sure that a new tab but not new process has been created. | |
| 168 ASSERT_TRUE(tab->NavigateToURLAsync(dont_fork_url)); | |
| 169 PlatformThread::Sleep(sleep_timeout_ms()); | |
| 170 ASSERT_EQ(orig_process_count, GetBrowserProcessCount()); | |
| 171 int new_tab_count = -1; | |
| 172 ASSERT_TRUE(window->GetTabCount(&new_tab_count)); | |
| 173 ASSERT_EQ(orig_tab_count + 1, new_tab_count); | |
| 174 | |
| 175 // Same thing if the current tab tries to redirect itself. | |
| 176 url_str = "javascript:(function(){w=window.open(); "; | |
| 177 url_str += "document.location=\""; | |
| 178 url_str += test_server.GetURL("").spec(); | |
| 179 url_str += "\";})()"; | |
| 180 GURL dont_fork_url2(url_str); | |
| 181 | |
| 182 // Make sure that no new process has been created. | |
| 183 ASSERT_TRUE(tab->NavigateToURLAsync(dont_fork_url2)); | |
| 184 PlatformThread::Sleep(sleep_timeout_ms()); | |
| 185 ASSERT_EQ(orig_process_count, GetBrowserProcessCount()); | |
| 186 } | |
| 187 | |
| 188 TEST_F(VisibleBrowserTest, WindowOpenClose) { | |
| 189 FilePath test_file(test_data_directory_); | |
| 190 test_file = test_file.AppendASCII("window.close.html"); | |
| 191 | |
| 192 NavigateToURLBlockUntilNavigationsComplete( | |
| 193 net::FilePathToFileURL(test_file), 2); | |
| 194 EXPECT_EQ(L"Title Of Awesomeness", GetActiveTabTitle()); | |
| 195 } | |
| 196 | |
| 197 class ShowModalDialogTest : public UITest { | |
| 198 public: | |
| 199 ShowModalDialogTest() { | |
| 200 launch_arguments_.AppendSwitch(switches::kDisablePopupBlocking); | |
| 201 } | |
| 202 }; | |
| 203 | |
| 204 // Flakiness returned. Re-opened crbug.com/17806 | |
| 205 TEST_F(ShowModalDialogTest, FLAKY_BasicTest) { | |
| 206 FilePath test_file(test_data_directory_); | |
| 207 test_file = test_file.AppendASCII("showmodaldialog.html"); | |
| 208 | |
| 209 // This navigation should show a modal dialog that will be immediately | |
| 210 // closed, but the fact that it was shown should be recorded. | |
| 211 NavigateToURL(net::FilePathToFileURL(test_file)); | |
| 212 | |
| 213 // At this point the modal dialog should not be showing. | |
| 214 int window_count = 0; | |
| 215 EXPECT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
| 216 EXPECT_EQ(1, window_count); | |
| 217 | |
| 218 // Verify that we set a mark on successful dialog show. | |
| 219 scoped_refptr<BrowserProxy> browser = automation()->GetBrowserWindow(0); | |
| 220 ASSERT_TRUE(browser.get()); | |
| 221 scoped_refptr<TabProxy> tab = browser->GetActiveTab(); | |
| 222 ASSERT_TRUE(tab.get()); | |
| 223 std::wstring title; | |
| 224 ASSERT_TRUE(tab->GetTabTitle(&title)); | |
| 225 ASSERT_EQ(L"SUCCESS", title); | |
| 226 } | |
| 227 | |
| 228 class SecurityTest : public UITest { | |
| 229 }; | |
| 230 | |
| 231 TEST_F(SecurityTest, DisallowFileUrlUniversalAccessTest) { | |
| 232 scoped_refptr<TabProxy> tab(GetActiveTab()); | |
| 233 ASSERT_TRUE(tab.get()); | |
| 234 | |
| 235 FilePath test_file(test_data_directory_); | |
| 236 test_file = test_file.AppendASCII("fileurl_universalaccess.html"); | |
| 237 | |
| 238 GURL url = net::FilePathToFileURL(test_file); | |
| 239 ASSERT_TRUE(tab->NavigateToURL(url)); | |
| 240 | |
| 241 std::string value = WaitUntilCookieNonEmpty(tab.get(), url, | |
| 242 "status", action_max_timeout_ms()); | |
| 243 ASSERT_STREQ("Disallowed", value.c_str()); | |
| 244 } | |
| 245 | |
| 246 #if !defined(OS_MACOSX) | |
| 247 class KioskModeTest : public UITest { | |
| 248 public: | |
| 249 KioskModeTest() { | |
| 250 launch_arguments_.AppendSwitch(switches::kKioskMode); | |
| 251 } | |
| 252 }; | |
| 253 | |
| 254 TEST_F(KioskModeTest, EnableKioskModeTest) { | |
| 255 // Load a local file. | |
| 256 FilePath test_file(test_data_directory_); | |
| 257 test_file = test_file.AppendASCII("title1.html"); | |
| 258 | |
| 259 // Verify that the window is present. | |
| 260 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | |
| 261 ASSERT_TRUE(browser.get()); | |
| 262 | |
| 263 // Check if browser is in fullscreen mode. | |
| 264 bool is_visible; | |
| 265 ASSERT_TRUE(browser->IsFullscreen(&is_visible)); | |
| 266 EXPECT_TRUE(is_visible); | |
| 267 ASSERT_TRUE(browser->IsFullscreenBubbleVisible(&is_visible)); | |
| 268 EXPECT_FALSE(is_visible); | |
| 269 } | |
| 270 #endif // !defined(OS_MACOSX) | |
| 271 | |
| 272 #if defined(OS_WIN) | |
| 273 // This test verifies that Chrome can be launched with a user-data-dir path | |
| 274 // which contains non ASCII characters. | |
| 275 class LaunchBrowserWithNonAsciiUserDatadir : public UITest { | |
| 276 public: | |
| 277 void SetUp() { | |
| 278 PathService::Get(base::DIR_TEMP, &tmp_profile_); | |
| 279 tmp_profile_ = tmp_profile_.AppendASCII("tmp_profile"); | |
| 280 tmp_profile_ = tmp_profile_.Append(L"Test Chrome G�raldine"); | |
| 281 | |
| 282 // Create a fresh, empty copy of this directory. | |
| 283 file_util::Delete(tmp_profile_, true); | |
| 284 file_util::CreateDirectory(tmp_profile_); | |
| 285 | |
| 286 launch_arguments_.AppendSwitchPath(switches::kUserDataDir, tmp_profile_); | |
| 287 } | |
| 288 | |
| 289 bool LaunchAppWithProfile() { | |
| 290 UITest::SetUp(); | |
| 291 return true; | |
| 292 } | |
| 293 | |
| 294 void TearDown() { | |
| 295 UITest::TearDown(); | |
| 296 EXPECT_TRUE(file_util::DieFileDie(tmp_profile_, true)); | |
| 297 } | |
| 298 | |
| 299 public: | |
| 300 FilePath tmp_profile_; | |
| 301 }; | |
| 302 | |
| 303 TEST_F(LaunchBrowserWithNonAsciiUserDatadir, TestNonAsciiUserDataDir) { | |
| 304 ASSERT_TRUE(LaunchAppWithProfile()); | |
| 305 // Verify that the window is present. | |
| 306 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | |
| 307 ASSERT_TRUE(browser.get()); | |
| 308 } | |
| 309 #endif // defined(OS_WIN) | |
| 310 | |
| 311 class AppModeTest : public UITest { | |
| 312 public: | |
| 313 AppModeTest() { | |
| 314 // Load a local file. | |
| 315 FilePath test_file(test_data_directory_); | |
| 316 test_file = test_file.AppendASCII("title1.html"); | |
| 317 GURL test_file_url(net::FilePathToFileURL(test_file)); | |
| 318 | |
| 319 launch_arguments_.AppendSwitchASCII(switches::kApp, test_file_url.spec()); | |
| 320 } | |
| 321 }; | |
| 322 | |
| 323 TEST_F(AppModeTest, EnableAppModeTest) { | |
| 324 // Test that an application browser window loads correctly. | |
| 325 | |
| 326 // Verify that the window is present. | |
| 327 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | |
| 328 ASSERT_TRUE(browser.get()); | |
| 329 | |
| 330 // Verify the browser is an application. | |
| 331 Browser::Type type; | |
| 332 ASSERT_TRUE(browser->GetType(&type)); | |
| 333 EXPECT_EQ(Browser::TYPE_APP, type); | |
| 334 } | |
| 335 | |
| 336 // Tests to ensure that the browser continues running in the background after | |
| 337 // the last window closes. | |
| 338 class RunInBackgroundTest : public UITest { | |
| 339 public: | |
| 340 RunInBackgroundTest() { | |
| 341 launch_arguments_.AppendSwitch(switches::kKeepAliveForTest); | |
| 342 } | |
| 343 }; | |
| 344 | |
| 345 TEST_F(RunInBackgroundTest, RunInBackgroundBasicTest) { | |
| 346 // Close the browser window, then open a new one - the browser should keep | |
| 347 // running. | |
| 348 scoped_refptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | |
| 349 ASSERT_TRUE(browser.get()); | |
| 350 int window_count; | |
| 351 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
| 352 EXPECT_EQ(1, window_count); | |
| 353 ASSERT_TRUE(browser->RunCommand(IDC_CLOSE_WINDOW)); | |
| 354 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
| 355 EXPECT_EQ(0, window_count); | |
| 356 ASSERT_TRUE(IsBrowserRunning()); | |
| 357 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, true)); | |
| 358 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
| 359 EXPECT_EQ(1, window_count); | |
| 360 } | |
| 361 | |
| 362 // Tests to ensure that the browser continues running in the background after | |
| 363 // the last window closes. | |
| 364 class NoStartupWindowTest : public UITest { | |
| 365 public: | |
| 366 NoStartupWindowTest() { | |
| 367 launch_arguments_.AppendSwitch(switches::kNoStartupWindow); | |
| 368 launch_arguments_.AppendSwitch(switches::kKeepAliveForTest); | |
| 369 } | |
| 370 }; | |
| 371 | |
| 372 TEST_F(NoStartupWindowTest, NoStartupWindowBasicTest) { | |
| 373 // No browser window should be started by default. | |
| 374 int window_count; | |
| 375 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
| 376 EXPECT_EQ(0, window_count); | |
| 377 | |
| 378 // Starting a browser window should work just fine. | |
| 379 ASSERT_TRUE(IsBrowserRunning()); | |
| 380 ASSERT_TRUE(automation()->OpenNewBrowserWindow(Browser::TYPE_NORMAL, true)); | |
| 381 ASSERT_TRUE(automation()->GetBrowserWindowCount(&window_count)); | |
| 382 EXPECT_EQ(1, window_count); | |
| 383 } | |
| 384 | |
| 385 } // namespace | |
| OLD | NEW |