| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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 "base/file_util.h" | 5 #include "base/file_util.h" |
| 6 | 6 #include "base/platform_thread.h" |
| 7 #include "chrome/browser/automation/url_request_mock_http_job.h" | 7 #include "chrome/browser/automation/url_request_mock_http_job.h" |
| 8 #include "chrome/common/chrome_switches.h" | 8 #include "chrome/common/chrome_switches.h" |
| 9 #include "chrome/common/message_box_flags.h" |
| 9 #include "chrome/test/automation/browser_proxy.h" | 10 #include "chrome/test/automation/browser_proxy.h" |
| 10 #include "chrome/test/automation/tab_proxy.h" | 11 #include "chrome/test/automation/tab_proxy.h" |
| 11 #include "chrome/test/ui/ui_test.h" | 12 #include "chrome/test/ui/ui_test.h" |
| 12 #include "chrome/views/window/dialog_delegate.h" | |
| 13 #include "net/url_request/url_request_unittest.h" | 13 #include "net/url_request/url_request_unittest.h" |
| 14 | 14 |
| 15 const std::string NOLISTENERS_HTML = | 15 const std::string NOLISTENERS_HTML = |
| 16 "<html><head><title>nolisteners</title></head><body></body></html>"; | 16 "<html><head><title>nolisteners</title></head><body></body></html>"; |
| 17 | 17 |
| 18 const std::string UNLOAD_HTML = | 18 const std::string UNLOAD_HTML = |
| 19 "<html><head><title>unload</title></head><body>" | 19 "<html><head><title>unload</title></head><body>" |
| 20 "<script>window.onunload=function(e){}</script></body></html>"; | 20 "<script>window.onunload=function(e){}</script></body></html>"; |
| 21 | 21 |
| 22 const std::string BEFORE_UNLOAD_HTML = | 22 const std::string BEFORE_UNLOAD_HTML = |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 89 } | 89 } |
| 90 | 90 |
| 91 UITest::SetUp(); | 91 UITest::SetUp(); |
| 92 } | 92 } |
| 93 | 93 |
| 94 void WaitForBrowserClosed() { | 94 void WaitForBrowserClosed() { |
| 95 const int kCheckDelayMs = 100; | 95 const int kCheckDelayMs = 100; |
| 96 int max_wait_time = 5000; | 96 int max_wait_time = 5000; |
| 97 while (max_wait_time > 0) { | 97 while (max_wait_time > 0) { |
| 98 max_wait_time -= kCheckDelayMs; | 98 max_wait_time -= kCheckDelayMs; |
| 99 Sleep(kCheckDelayMs); | 99 PlatformThread::Sleep(kCheckDelayMs); |
| 100 if (!IsBrowserRunning()) | 100 if (!IsBrowserRunning()) |
| 101 break; | 101 break; |
| 102 } | 102 } |
| 103 } | 103 } |
| 104 | 104 |
| 105 void CheckTitle(const std::wstring& expected_title) { | 105 void CheckTitle(const std::wstring& expected_title) { |
| 106 const int kCheckDelayMs = 100; | 106 const int kCheckDelayMs = 100; |
| 107 int max_wait_time = 5000; | 107 int max_wait_time = 5000; |
| 108 while (max_wait_time > 0) { | 108 while (max_wait_time > 0) { |
| 109 max_wait_time -= kCheckDelayMs; | 109 max_wait_time -= kCheckDelayMs; |
| 110 Sleep(kCheckDelayMs); | 110 PlatformThread::Sleep(kCheckDelayMs); |
| 111 if (expected_title == GetActiveTabTitle()) | 111 if (expected_title == GetActiveTabTitle()) |
| 112 break; | 112 break; |
| 113 } | 113 } |
| 114 | 114 |
| 115 EXPECT_EQ(expected_title, GetActiveTabTitle()); | 115 EXPECT_EQ(expected_title, GetActiveTabTitle()); |
| 116 } | 116 } |
| 117 | 117 |
| 118 void NavigateToDataURL(const std::string& html_content, | 118 void NavigateToDataURL(const std::string& html_content, |
| 119 const std::wstring& expected_title) { | 119 const std::wstring& expected_title) { |
| 120 NavigateToURL(GURL("data:text/html," + html_content)); | 120 NavigateToURL(GURL("data:text/html," + html_content)); |
| 121 CheckTitle(expected_title); | 121 CheckTitle(expected_title); |
| 122 } | 122 } |
| 123 | 123 |
| 124 void NavigateToNolistenersFileTwice() { | 124 void NavigateToNolistenersFileTwice() { |
| 125 NavigateToURL( | 125 NavigateToURL( |
| 126 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 126 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 127 CheckTitle(L"Title Of Awesomeness"); | 127 CheckTitle(L"Title Of Awesomeness"); |
| 128 NavigateToURL( | 128 NavigateToURL( |
| 129 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 129 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 130 CheckTitle(L"Title Of Awesomeness"); | 130 CheckTitle(L"Title Of Awesomeness"); |
| 131 } | 131 } |
| 132 | 132 |
| 133 // Navigates to a URL asynchronously, then again synchronously. The first | 133 // Navigates to a URL asynchronously, then again synchronously. The first |
| 134 // load is purposely async to test the case where the user loads another | 134 // load is purposely async to test the case where the user loads another |
| 135 // page without waiting for the first load to complete. | 135 // page without waiting for the first load to complete. |
| 136 void NavigateToNolistenersFileTwiceAsync() { | 136 void NavigateToNolistenersFileTwiceAsync() { |
| 137 // TODO(ojan): We hit a DCHECK in RenderViewHost::OnMsgShouldCloseACK | 137 // TODO(ojan): We hit a DCHECK in RenderViewHost::OnMsgShouldCloseACK |
| 138 // if we don't sleep here. | 138 // if we don't sleep here. |
| 139 Sleep(400); | 139 PlatformThread::Sleep(400); |
| 140 NavigateToURLAsync( | 140 NavigateToURLAsync( |
| 141 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 141 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 142 Sleep(400); | 142 PlatformThread::Sleep(400); |
| 143 NavigateToURL( | 143 NavigateToURL( |
| 144 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 144 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 145 | 145 |
| 146 CheckTitle(L"Title Of Awesomeness"); | 146 CheckTitle(L"Title Of Awesomeness"); |
| 147 } | 147 } |
| 148 | 148 |
| 149 void LoadUrlAndQuitBrowser(const std::string& html_content, | 149 void LoadUrlAndQuitBrowser(const std::string& html_content, |
| 150 const std::wstring& expected_title = L"") { | 150 const std::wstring& expected_title = L"") { |
| 151 scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | 151 scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| 152 NavigateToDataURL(html_content, expected_title); | 152 NavigateToDataURL(html_content, expected_title); |
| 153 bool application_closed = false; | 153 bool application_closed = false; |
| 154 EXPECT_TRUE(CloseBrowser(browser.get(), &application_closed)); | 154 EXPECT_TRUE(CloseBrowser(browser.get(), &application_closed)); |
| 155 } | 155 } |
| 156 | 156 |
| 157 void ClickModalDialogButton(MessageBoxFlags::DialogButton button) { | 157 void ClickModalDialogButton(MessageBoxFlags::DialogButton button) { |
| 158 #if defined(OS_WIN) || defined(OS_LINUX) |
| 158 bool modal_dialog_showing = false; | 159 bool modal_dialog_showing = false; |
| 159 MessageBoxFlags::DialogButton available_buttons; | 160 MessageBoxFlags::DialogButton available_buttons; |
| 160 EXPECT_TRUE(automation()->WaitForAppModalDialog(3000)); | 161 EXPECT_TRUE(automation()->WaitForAppModalDialog(3000)); |
| 161 EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, | 162 EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| 162 &available_buttons)); | 163 &available_buttons)); |
| 163 ASSERT_TRUE(modal_dialog_showing); | 164 ASSERT_TRUE(modal_dialog_showing); |
| 164 EXPECT_TRUE((button & available_buttons) != NULL); | 165 EXPECT_TRUE((button & available_buttons) != 0); |
| 165 EXPECT_TRUE(automation()->ClickAppModalDialogButton(button)); | 166 EXPECT_TRUE(automation()->ClickAppModalDialogButton(button)); |
| 167 #else |
| 168 // TODO(port): port this function if and when the tests that use it are |
| 169 // enabled (currently they are not being run even on windows). |
| 170 NOTIMPLEMENTED(); |
| 171 #endif |
| 166 } | 172 } |
| 167 }; | 173 }; |
| 168 | 174 |
| 175 // TODO(port): these tests fail on linux because they leave a renderer process |
| 176 // lying around which holds onto the user data directory. |
| 177 #if defined(OS_WIN) |
| 169 // Navigate to a page with an infinite unload handler. | 178 // Navigate to a page with an infinite unload handler. |
| 170 // Then two two async crosssite requests to ensure | 179 // Then two two async crosssite requests to ensure |
| 171 // we don't get confused and think we're closing the tab. | 180 // we don't get confused and think we're closing the tab. |
| 172 TEST_F(UnloadTest, CrossSiteInfiniteUnloadAsync) { | 181 TEST_F(UnloadTest, CrossSiteInfiniteUnloadAsync) { |
| 173 // Tests makes no sense in single-process mode since the renderer is hung. | 182 // Tests makes no sense in single-process mode since the renderer is hung. |
| 174 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | 183 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 175 return; | 184 return; |
| 176 | 185 |
| 177 NavigateToDataURL(INFINITE_UNLOAD_HTML, L"infiniteunload"); | 186 NavigateToDataURL(INFINITE_UNLOAD_HTML, L"infiniteunload"); |
| 178 // Must navigate to a non-data URL to trigger cross-site codepath. | 187 // Must navigate to a non-data URL to trigger cross-site codepath. |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 TEST_F(UnloadTest, CrossSiteInfiniteBeforeUnloadSync) { | 223 TEST_F(UnloadTest, CrossSiteInfiniteBeforeUnloadSync) { |
| 215 // Tests makes no sense in single-process mode since the renderer is hung. | 224 // Tests makes no sense in single-process mode since the renderer is hung. |
| 216 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | 225 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 217 return; | 226 return; |
| 218 | 227 |
| 219 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML, L"infinitebeforeunload"); | 228 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML, L"infinitebeforeunload"); |
| 220 // Must navigate to a non-data URL to trigger cross-site codepath. | 229 // Must navigate to a non-data URL to trigger cross-site codepath. |
| 221 NavigateToNolistenersFileTwice(); | 230 NavigateToNolistenersFileTwice(); |
| 222 ASSERT_TRUE(IsBrowserRunning()); | 231 ASSERT_TRUE(IsBrowserRunning()); |
| 223 } | 232 } |
| 233 #endif |
| 224 | 234 |
| 225 // Tests closing the browser on a page with no unload listeners registered. | 235 // Tests closing the browser on a page with no unload listeners registered. |
| 226 TEST_F(UnloadTest, BrowserCloseNoUnloadListeners) { | 236 TEST_F(UnloadTest, BrowserCloseNoUnloadListeners) { |
| 227 LoadUrlAndQuitBrowser(NOLISTENERS_HTML, L"nolisteners"); | 237 LoadUrlAndQuitBrowser(NOLISTENERS_HTML, L"nolisteners"); |
| 228 } | 238 } |
| 229 | 239 |
| 230 // Tests closing the browser on a page with an unload listener registered. | 240 // Tests closing the browser on a page with an unload listener registered. |
| 231 TEST_F(UnloadTest, BrowserCloseUnload) { | 241 TEST_F(UnloadTest, BrowserCloseUnload) { |
| 232 LoadUrlAndQuitBrowser(UNLOAD_HTML, L"unload"); | 242 LoadUrlAndQuitBrowser(UNLOAD_HTML, L"unload"); |
| 233 } | 243 } |
| (...skipping 27 matching lines...) Expand all Loading... |
| 261 EXPECT_FALSE(IsBrowserRunning()); | 271 EXPECT_FALSE(IsBrowserRunning()); |
| 262 } | 272 } |
| 263 | 273 |
| 264 // Tests closing the browser with a beforeunload handler that takes | 274 // Tests closing the browser with a beforeunload handler that takes |
| 265 // two seconds to run. | 275 // two seconds to run. |
| 266 TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnload) { | 276 TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnload) { |
| 267 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_HTML, | 277 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_HTML, |
| 268 L"twosecondbeforeunload"); | 278 L"twosecondbeforeunload"); |
| 269 } | 279 } |
| 270 | 280 |
| 281 // TODO(estade): On linux, the renderer process doesn't seem to quit and pegs |
| 282 // CPU. |
| 283 #if defined(OS_WIN) |
| 271 // Tests closing the browser on a page with an unload listener registered where | 284 // Tests closing the browser on a page with an unload listener registered where |
| 272 // the unload handler has an infinite loop. | 285 // the unload handler has an infinite loop. |
| 273 TEST_F(UnloadTest, BrowserCloseInfiniteUnload) { | 286 TEST_F(UnloadTest, BrowserCloseInfiniteUnload) { |
| 274 // Tests makes no sense in single-process mode since the renderer is hung. | 287 // Tests makes no sense in single-process mode since the renderer is hung. |
| 275 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | 288 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 276 return; | 289 return; |
| 277 | 290 |
| 278 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_HTML, L"infiniteunload"); | 291 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_HTML, L"infiniteunload"); |
| 279 } | 292 } |
| 280 | 293 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 300 // Tests closing the browser with a beforeunload handler that hangs then | 313 // Tests closing the browser with a beforeunload handler that hangs then |
| 301 // pops up an alert. | 314 // pops up an alert. |
| 302 TEST_F(UnloadTest, BrowserCloseInfiniteBeforeUnloadAlert) { | 315 TEST_F(UnloadTest, BrowserCloseInfiniteBeforeUnloadAlert) { |
| 303 // Tests makes no sense in single-process mode since the renderer is hung. | 316 // Tests makes no sense in single-process mode since the renderer is hung. |
| 304 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | 317 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 305 return; | 318 return; |
| 306 | 319 |
| 307 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_ALERT_HTML, | 320 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_ALERT_HTML, |
| 308 L"infinitebeforeunloadalert"); | 321 L"infinitebeforeunloadalert"); |
| 309 } | 322 } |
| 323 #endif // defined(OS_WIN) |
| 310 | 324 |
| 311 // Tests closing the browser on a page with an unload listener registered where | 325 // Tests closing the browser on a page with an unload listener registered where |
| 312 // the unload handler has an 2 second long loop followed by an alert. | 326 // the unload handler has an 2 second long loop followed by an alert. |
| 313 TEST_F(UnloadTest, BrowserCloseTwoSecondUnloadAlert) { | 327 TEST_F(UnloadTest, BrowserCloseTwoSecondUnloadAlert) { |
| 314 LoadUrlAndQuitBrowser(TWO_SECOND_UNLOAD_ALERT_HTML, L"twosecondunloadalert"); | 328 LoadUrlAndQuitBrowser(TWO_SECOND_UNLOAD_ALERT_HTML, L"twosecondunloadalert"); |
| 315 } | 329 } |
| 316 | 330 |
| 317 // Tests closing the browser with a beforeunload handler that takes | 331 // Tests closing the browser with a beforeunload handler that takes |
| 318 // two seconds to run then pops up an alert. | 332 // two seconds to run then pops up an alert. |
| 319 TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnloadAlert) { | 333 TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnloadAlert) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 340 | 354 |
| 341 scoped_ptr<TabProxy> first_tab(browser_proxy->GetActiveTab()); | 355 scoped_ptr<TabProxy> first_tab(browser_proxy->GetActiveTab()); |
| 342 std::wstring title; | 356 std::wstring title; |
| 343 EXPECT_TRUE(first_tab.get() != NULL); | 357 EXPECT_TRUE(first_tab.get() != NULL); |
| 344 EXPECT_TRUE(first_tab->GetTabTitle(&title)); | 358 EXPECT_TRUE(first_tab->GetTabTitle(&title)); |
| 345 EXPECT_EQ(title, L"only_one_unload"); | 359 EXPECT_EQ(title, L"only_one_unload"); |
| 346 } | 360 } |
| 347 | 361 |
| 348 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs | 362 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs |
| 349 // and multiple windows. | 363 // and multiple windows. |
| OLD | NEW |