| 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/ui/ui_test.h" | 11 #include "chrome/test/ui/ui_test.h" |
| 11 #include "chrome/views/window/dialog_delegate.h" | |
| 12 #include "net/url_request/url_request_unittest.h" | 12 #include "net/url_request/url_request_unittest.h" |
| 13 | 13 |
| 14 const std::string NOLISTENERS_HTML = | 14 const std::string NOLISTENERS_HTML = |
| 15 "<html><head><title>nolisteners</title></head><body></body></html>"; | 15 "<html><head><title>nolisteners</title></head><body></body></html>"; |
| 16 | 16 |
| 17 const std::string UNLOAD_HTML = | 17 const std::string UNLOAD_HTML = |
| 18 "<html><head><title>unload</title></head><body>" | 18 "<html><head><title>unload</title></head><body>" |
| 19 "<script>window.onunload=function(e){}</script></body></html>"; | 19 "<script>window.onunload=function(e){}</script></body></html>"; |
| 20 | 20 |
| 21 const std::string BEFORE_UNLOAD_HTML = | 21 const std::string BEFORE_UNLOAD_HTML = |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 "alert('foo');" | 71 "alert('foo');" |
| 72 "}</script></body></html>"; | 72 "}</script></body></html>"; |
| 73 | 73 |
| 74 class UnloadTest : public UITest { | 74 class UnloadTest : public UITest { |
| 75 public: | 75 public: |
| 76 void WaitForBrowserClosed() { | 76 void WaitForBrowserClosed() { |
| 77 const int kCheckDelayMs = 100; | 77 const int kCheckDelayMs = 100; |
| 78 int max_wait_time = 5000; | 78 int max_wait_time = 5000; |
| 79 while (max_wait_time > 0) { | 79 while (max_wait_time > 0) { |
| 80 max_wait_time -= kCheckDelayMs; | 80 max_wait_time -= kCheckDelayMs; |
| 81 Sleep(kCheckDelayMs); | 81 PlatformThread::Sleep(kCheckDelayMs); |
| 82 if (!IsBrowserRunning()) | 82 if (!IsBrowserRunning()) |
| 83 break; | 83 break; |
| 84 } | 84 } |
| 85 } | 85 } |
| 86 | 86 |
| 87 void CheckTitle(const std::wstring& expected_title) { | 87 void CheckTitle(const std::wstring& expected_title) { |
| 88 const int kCheckDelayMs = 100; | 88 const int kCheckDelayMs = 100; |
| 89 int max_wait_time = 5000; | 89 int max_wait_time = 5000; |
| 90 while (max_wait_time > 0) { | 90 while (max_wait_time > 0) { |
| 91 max_wait_time -= kCheckDelayMs; | 91 max_wait_time -= kCheckDelayMs; |
| 92 Sleep(kCheckDelayMs); | 92 PlatformThread::Sleep(kCheckDelayMs); |
| 93 if (expected_title == GetActiveTabTitle()) | 93 if (expected_title == GetActiveTabTitle()) |
| 94 break; | 94 break; |
| 95 } | 95 } |
| 96 | 96 |
| 97 EXPECT_EQ(expected_title, GetActiveTabTitle()); | 97 EXPECT_EQ(expected_title, GetActiveTabTitle()); |
| 98 } | 98 } |
| 99 | 99 |
| 100 void NavigateToDataURL(const std::string& html_content, | 100 void NavigateToDataURL(const std::string& html_content, |
| 101 const std::wstring& expected_title) { | 101 const std::wstring& expected_title) { |
| 102 NavigateToURL(GURL("data:text/html," + html_content)); | 102 NavigateToURL(GURL("data:text/html," + html_content)); |
| 103 CheckTitle(expected_title); | 103 CheckTitle(expected_title); |
| 104 } | 104 } |
| 105 | 105 |
| 106 void NavigateToNolistenersFileTwice() { | 106 void NavigateToNolistenersFileTwice() { |
| 107 NavigateToURL( | 107 NavigateToURL( |
| 108 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 108 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 109 CheckTitle(L"Title Of Awesomeness"); | 109 CheckTitle(L"Title Of Awesomeness"); |
| 110 NavigateToURL( | 110 NavigateToURL( |
| 111 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 111 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 112 CheckTitle(L"Title Of Awesomeness"); | 112 CheckTitle(L"Title Of Awesomeness"); |
| 113 } | 113 } |
| 114 | 114 |
| 115 // Navigates to a URL asynchronously, then again synchronously. The first | 115 // Navigates to a URL asynchronously, then again synchronously. The first |
| 116 // load is purposely async to test the case where the user loads another | 116 // load is purposely async to test the case where the user loads another |
| 117 // page without waiting for the first load to complete. | 117 // page without waiting for the first load to complete. |
| 118 void NavigateToNolistenersFileTwiceAsync() { | 118 void NavigateToNolistenersFileTwiceAsync() { |
| 119 // TODO(ojan): We hit a DCHECK in RenderViewHost::OnMsgShouldCloseACK | 119 // TODO(ojan): We hit a DCHECK in RenderViewHost::OnMsgShouldCloseACK |
| 120 // if we don't sleep here. | 120 // if we don't sleep here. |
| 121 Sleep(400); | 121 PlatformThread::Sleep(400); |
| 122 NavigateToURLAsync( | 122 NavigateToURLAsync( |
| 123 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 123 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 124 Sleep(400); | 124 PlatformThread::Sleep(400); |
| 125 NavigateToURL( | 125 NavigateToURL( |
| 126 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); | 126 URLRequestMockHTTPJob::GetMockUrl(L"title2.html")); |
| 127 | 127 |
| 128 CheckTitle(L"Title Of Awesomeness"); | 128 CheckTitle(L"Title Of Awesomeness"); |
| 129 } | 129 } |
| 130 | 130 |
| 131 void LoadUrlAndQuitBrowser(const std::string& html_content, | 131 void LoadUrlAndQuitBrowser(const std::string& html_content, |
| 132 const std::wstring& expected_title = L"") { | 132 const std::wstring& expected_title = L"") { |
| 133 scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); | 133 scoped_ptr<BrowserProxy> browser(automation()->GetBrowserWindow(0)); |
| 134 NavigateToDataURL(html_content, expected_title); | 134 NavigateToDataURL(html_content, expected_title); |
| 135 bool application_closed = false; | 135 bool application_closed = false; |
| 136 EXPECT_TRUE(CloseBrowser(browser.get(), &application_closed)); | 136 EXPECT_TRUE(CloseBrowser(browser.get(), &application_closed)); |
| 137 } | 137 } |
| 138 | 138 |
| 139 void ClickModalDialogButton(MessageBoxFlags::DialogButton button) { | 139 void ClickModalDialogButton(MessageBoxFlags::DialogButton button) { |
| 140 #if defined(OS_WIN) |
| 140 bool modal_dialog_showing = false; | 141 bool modal_dialog_showing = false; |
| 141 MessageBoxFlags::DialogButton available_buttons; | 142 MessageBoxFlags::DialogButton available_buttons; |
| 142 EXPECT_TRUE(automation()->WaitForAppModalDialog(3000)); | 143 EXPECT_TRUE(automation()->WaitForAppModalDialog(3000)); |
| 143 EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, | 144 EXPECT_TRUE(automation()->GetShowingAppModalDialog(&modal_dialog_showing, |
| 144 &available_buttons)); | 145 &available_buttons)); |
| 145 ASSERT_TRUE(modal_dialog_showing); | 146 ASSERT_TRUE(modal_dialog_showing); |
| 146 EXPECT_TRUE((button & available_buttons) != NULL); | 147 EXPECT_TRUE((button & available_buttons) != 0); |
| 147 EXPECT_TRUE(automation()->ClickAppModalDialogButton(button)); | 148 EXPECT_TRUE(automation()->ClickAppModalDialogButton(button)); |
| 149 #else |
| 150 // TODO(port): port this function if and when the tests that use it are |
| 151 // enabled (currently they are not being run even on windows). |
| 152 NOTIMPLEMENTED(); |
| 153 #endif |
| 148 } | 154 } |
| 149 }; | 155 }; |
| 150 | 156 |
| 157 // TODO(port): these tests fail on linux because they leave a renderer process |
| 158 // lying around which holds onto the user data directory. |
| 159 #if defined(OS_WIN) |
| 151 // Navigate to a page with an infinite unload handler. | 160 // Navigate to a page with an infinite unload handler. |
| 152 // Then two two async crosssite requests to ensure | 161 // Then two two async crosssite requests to ensure |
| 153 // we don't get confused and think we're closing the tab. | 162 // we don't get confused and think we're closing the tab. |
| 154 TEST_F(UnloadTest, CrossSiteInfiniteUnloadAsync) { | 163 TEST_F(UnloadTest, CrossSiteInfiniteUnloadAsync) { |
| 155 // Tests makes no sense in single-process mode since the renderer is hung. | 164 // Tests makes no sense in single-process mode since the renderer is hung. |
| 156 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | 165 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 157 return; | 166 return; |
| 158 | 167 |
| 159 NavigateToDataURL(INFINITE_UNLOAD_HTML, L"infiniteunload"); | 168 NavigateToDataURL(INFINITE_UNLOAD_HTML, L"infiniteunload"); |
| 160 // Must navigate to a non-data URL to trigger cross-site codepath. | 169 // 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... |
| 196 TEST_F(UnloadTest, CrossSiteInfiniteBeforeUnloadSync) { | 205 TEST_F(UnloadTest, CrossSiteInfiniteBeforeUnloadSync) { |
| 197 // Tests makes no sense in single-process mode since the renderer is hung. | 206 // Tests makes no sense in single-process mode since the renderer is hung. |
| 198 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | 207 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 199 return; | 208 return; |
| 200 | 209 |
| 201 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML, L"infinitebeforeunload"); | 210 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML, L"infinitebeforeunload"); |
| 202 // Must navigate to a non-data URL to trigger cross-site codepath. | 211 // Must navigate to a non-data URL to trigger cross-site codepath. |
| 203 NavigateToNolistenersFileTwice(); | 212 NavigateToNolistenersFileTwice(); |
| 204 ASSERT_TRUE(IsBrowserRunning()); | 213 ASSERT_TRUE(IsBrowserRunning()); |
| 205 } | 214 } |
| 215 #endif |
| 206 | 216 |
| 207 // Tests closing the browser on a page with no unload listeners registered. | 217 // Tests closing the browser on a page with no unload listeners registered. |
| 208 TEST_F(UnloadTest, BrowserCloseNoUnloadListeners) { | 218 TEST_F(UnloadTest, BrowserCloseNoUnloadListeners) { |
| 209 LoadUrlAndQuitBrowser(NOLISTENERS_HTML, L"nolisteners"); | 219 LoadUrlAndQuitBrowser(NOLISTENERS_HTML, L"nolisteners"); |
| 210 } | 220 } |
| 211 | 221 |
| 212 // Tests closing the browser on a page with an unload listener registered. | 222 // Tests closing the browser on a page with an unload listener registered. |
| 213 TEST_F(UnloadTest, BrowserCloseUnload) { | 223 TEST_F(UnloadTest, BrowserCloseUnload) { |
| 214 LoadUrlAndQuitBrowser(UNLOAD_HTML, L"unload"); | 224 LoadUrlAndQuitBrowser(UNLOAD_HTML, L"unload"); |
| 215 } | 225 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 298 | 308 |
| 299 // Tests closing the browser with a beforeunload handler that takes | 309 // Tests closing the browser with a beforeunload handler that takes |
| 300 // two seconds to run then pops up an alert. | 310 // two seconds to run then pops up an alert. |
| 301 TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnloadAlert) { | 311 TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnloadAlert) { |
| 302 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML, | 312 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML, |
| 303 L"twosecondbeforeunloadalert"); | 313 L"twosecondbeforeunloadalert"); |
| 304 } | 314 } |
| 305 | 315 |
| 306 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs | 316 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs |
| 307 // and multiple windows. | 317 // and multiple windows. |
| OLD | NEW |